📄 qgsrasterlayer.cpp
字号:
QgsLogger::debug("QgsRasterLayer::draw: clippedYMax", myRasterViewPort->clippedYMax, 1, __FILE__,\ __FUNCTION__, __LINE__); QgsLogger::debug("QgsRasterLayer::draw: clippedWidth", myRasterViewPort->clippedWidth, 1, __FILE__,\ __FUNCTION__, __LINE__); QgsLogger::debug("QgsRasterLayer::draw: clippedHeight", myRasterViewPort->clippedHeight, 1, __FILE__,\ __FUNCTION__, __LINE__); QgsLogger::debug("QgsRasterLayer::draw: drawableAreaXDim", myRasterViewPort->drawableAreaXDim, 1, __FILE__,\ __FUNCTION__, __LINE__); QgsLogger::debug("QgsRasterLayer::draw: drawableAreaYDim", myRasterViewPort->drawableAreaYDim, 1, __FILE__,\ __FUNCTION__, __LINE__); QgsDebugMsg("ReadXml: gray band name : " + mGrayBandName); QgsDebugMsg("ReadXml: red band name : " + mRedBandName); QgsDebugMsg("ReadXml: green band name : " + mGreenBandName); QgsDebugMsg("ReadXml: blue band name : " + mBlueBandName);#endif // /\/\/\ - added to handle zoomed-in rasters // Provider mode: See if a provider key is specified, and if so use the provider instead QgsDebugMsg("QgsRasterLayer::draw: Checking for provider key."); if (!mProviderKey.isEmpty()) { QgsDebugMsg("QgsRasterLayer::draw: Wanting a '" + mProviderKey + "' provider to draw this."); emit setStatus(QString("Retrieving using ")+mProviderKey); QImage* image = mDataProvider->draw( myRasterExtent, // Below should calculate to the actual pixel size of the // part of the layer that's visible. static_cast<int>( fabs( (myRasterViewPort->clippedXMax - myRasterViewPort->clippedXMin) / theQgsMapToPixel->mapUnitsPerPixel() * mGeoTransform[1]) + 1), static_cast<int>( fabs( (myRasterViewPort->clippedYMax - myRasterViewPort->clippedYMin) / theQgsMapToPixel->mapUnitsPerPixel() * mGeoTransform[5]) + 1)// myRasterViewPort->drawableAreaXDim,// myRasterViewPort->drawableAreaYDim ); if (!image) { // An error occurred. mErrorCaption = mDataProvider->errorCaptionString(); mError = mDataProvider->errorString(); delete myRasterViewPort; return FALSE; } QgsDebugMsg("QgsRasterLayer::draw: Done mDataProvider->draw."); QgsDebugMsg("QgsRasterLayer::draw: image stats: ");#ifdef QGISDEBUG QgsLogger::debug("depth", image->depth(), __FILE__, __FUNCTION__, __LINE__, 1); QgsLogger::debug("bytes", image->numBytes(), __FILE__, __FUNCTION__, __LINE__, 1); QgsLogger::debug("width", image->width(), __FILE__, __FUNCTION__, __LINE__, 1); QgsLogger::debug("height", image->height(), __FILE__, __FUNCTION__, __LINE__, 1);#endif QgsDebugMsg("QgsRasterLayer::draw: Want to theQPainter->drawImage with");#ifdef QGISDEBUG QgsLogger::debug("origin x", myRasterViewPort->topLeftPoint.x(), __FILE__, __FUNCTION__, __LINE__, 1); QgsLogger::debug("(int)origin x", static_cast<int>(myRasterViewPort->topLeftPoint.x()), __FILE__,\ __FUNCTION__, __LINE__, 1); QgsLogger::debug("origin y", myRasterViewPort->topLeftPoint.y(), __FILE__, __FUNCTION__, __LINE__, 1); QgsLogger::debug("(int)origin y", static_cast<int>(myRasterViewPort->topLeftPoint.y()), __FILE__,\ __FUNCTION__, __LINE__, 1);#endif // Since GDAL's RasterIO can't handle floating point, we have to round to // the nearest pixel. Add 0.5 to get rounding instead of truncation // out of static_cast<int>. theQPainter->drawImage(static_cast<int>( myRasterViewPort->topLeftPoint.x() + 0.5 // try simulating rounding instead of truncation, to avoid off-by-one errors // TODO: Check for rigorous correctness ), static_cast<int>( myRasterViewPort->topLeftPoint.y() + 0.5 // try simulating rounding instead of truncation, to avoid off-by-one errors // TODO: Check for rigorous correctness ), *image); } else { if ((myRasterViewPort->drawableAreaXDim) > 4000 && (myRasterViewPort->drawableAreaYDim > 4000)) { // We have scaled one raster pixel to more than 4000 screen pixels. What's the point of showing this layer? // Instead, we just stop displaying the layer. Prevents allocating the entire world of memory for showing // very few pixels. // (Alternatively, we have a very big screen > 2000 x 2000) QgsDebugMsg("Too zoomed in! Displaying raster requires too much memory. Raster will not display"); } else { // Otherwise use the old-fashioned GDAL direct-drawing style // TODO: Move into its own GDAL provider. // \/\/\/ - commented-out to handle zoomed-in rasters // draw(theQPainter,myRasterViewPort); // /\/\/\ - commented-out to handle zoomed-in rasters // \/\/\/ - added to handle zoomed-in rasters draw(theQPainter, myRasterViewPort, theQgsMapToPixel); // /\/\/\ - added to handle zoomed-in rasters } } delete myRasterViewPort; QgsDebugMsg("QgsRasterLayer::draw: exiting."); return TRUE;}void QgsRasterLayer::draw (QPainter * theQPainter, QgsRasterViewPort * theRasterViewPort, QgsMapToPixel * theQgsMapToPixel){ QgsDebugMsg("QgsRasterLayer::draw (3 arguments)"); // // // The goal here is to make as many decisions as possible early on (outside of the rendering loop) // so that we can maximise performance of the rendering process. So now we check which drawing // procedure to use : // switch (drawingStyle) { // a "Gray" or "Undefined" layer drawn as a range of gray colors case SINGLE_BAND_GRAY: //check the band is set! if (mGrayBandName == tr(QSTRING_NOT_SET)) { break; } else { drawSingleBandGray(theQPainter, theRasterViewPort, theQgsMapToPixel, getRasterBandNumber(mGrayBandName)); break; } // a "Gray" or "Undefined" layer drawn using a pseudocolor algorithm case SINGLE_BAND_PSEUDO_COLOR: //check the band is set! if (mGrayBandName == tr(QSTRING_NOT_SET)) { break; } else { drawSingleBandPseudoColor(theQPainter, theRasterViewPort, theQgsMapToPixel, getRasterBandNumber(mGrayBandName)); break; } // a "Palette" layer drawn in gray scale (using only one of the color components) case PALETTED_SINGLE_BAND_GRAY: //check the band is set! if (mGrayBandName == tr(QSTRING_NOT_SET)) { break; } else { QgsDebugMsg("PALETTED_SINGLE_BAND_GRAY drawing type detected..."); int myBandNo = 1; drawPalettedSingleBandGray(theQPainter, theRasterViewPort, theQgsMapToPixel, myBandNo, mGrayBandName); break; } // a "Palette" layer having only one of its color components rendered as psuedo color case PALETTED_SINGLE_BAND_PSEUDO_COLOR: //check the band is set! if (mGrayBandName == tr(QSTRING_NOT_SET)) { break; } else { int myBandNo = 1; drawPalettedSingleBandPseudoColor(theQPainter, theRasterViewPort, theQgsMapToPixel, myBandNo, mGrayBandName); break; } //a "Palette" image where the bands contains 24bit color info and 8 bits is pulled out per color case PALETTED_MULTI_BAND_COLOR: drawPalettedMultiBandColor(theQPainter, theRasterViewPort, theQgsMapToPixel, 1); break; // a layer containing 2 or more bands, but using only one band to produce a grayscale image case MULTI_BAND_SINGLE_BAND_GRAY: QgsDebugMsg("MULTI_BAND_SINGLE_BAND_GRAY drawing type detected..."); //check the band is set! if (mGrayBandName == tr(QSTRING_NOT_SET)) { QgsDebugMsg("MULTI_BAND_SINGLE_BAND_GRAY Not Set detected..." + mGrayBandName); break; } else { //get the band number for the mapped gray band drawMultiBandSingleBandGray(theQPainter, theRasterViewPort, theQgsMapToPixel, getRasterBandNumber(mGrayBandName)); break; } //a layer containing 2 or more bands, but using only one band to produce a pseudocolor image case MULTI_BAND_SINGLE_BAND_PSEUDO_COLOR: //check the band is set! if (mGrayBandName == tr(QSTRING_NOT_SET)) { break; } else { drawMultiBandSingleBandPseudoColor(theQPainter, theRasterViewPort, theQgsMapToPixel, getRasterBandNumber(mGrayBandName)); break; } //a layer containing 2 or more bands, mapped to the three RGBcolors. //In the case of a multiband with only two bands, //one band will have to be mapped to more than one color case MULTI_BAND_COLOR: if(mRedBandName == tr(QSTRING_NOT_SET) || mGreenBandName == tr(QSTRING_NOT_SET) || mBlueBandName == tr(QSTRING_NOT_SET)) { break; } else { drawMultiBandColor(theQPainter, theRasterViewPort, theQgsMapToPixel); } break; default: break; } //see if debug info is wanted if (mDebugOverlayFlag) { showDebugOverlay(theQPainter, theRasterViewPort); };} //end of draw methodvoid QgsRasterLayer::drawSingleBandGray(QPainter * theQPainter, QgsRasterViewPort * theRasterViewPort, QgsMapToPixel * theQgsMapToPixel, int theBandNo){ QgsDebugMsg("QgsRasterLayer::drawSingleBandGray called for layer " + QString::number(theBandNo)); //Invalid band number, segfault prevention if(0 >= theBandNo) { return; } GDALRasterBandH myGdalBand = GDALGetRasterBand(mGdalDataset,theBandNo); GDALDataType myDataType = GDALGetRasterDataType(myGdalBand); void *myGdalScanData = readData ( myGdalBand, theRasterViewPort ); /* Check for out of memory error */ if (myGdalScanData == NULL) { return; } QImage myQImage = QImage(theRasterViewPort->drawableAreaXDim, theRasterViewPort->drawableAreaYDim, 32); myQImage.setAlphaBuffer(true); myQImage.fill(qRgba(255,255,255,0 )); // fill transparent QgsRasterBandStats myGrayBandStats; if(QgsContrastEnhancement::NO_STRETCH != getContrastEnhancementAlgorithm() && !mUserDefinedGrayMinMaxFlag && mStandardDeviations > 0) { myGrayBandStats = getRasterBandStats(theBandNo); setMaximumValue(theBandNo, myGrayBandStats.mean + (mStandardDeviations * myGrayBandStats.stdDev)); setMinimumValue(theBandNo, myGrayBandStats.mean - (mStandardDeviations * myGrayBandStats.stdDev)); } else if(QgsContrastEnhancement::NO_STRETCH != getContrastEnhancementAlgorithm() && !mUserDefinedGrayMinMaxFlag) { //This case will be true the first time the image is loaded, so just approimate the min max to keep //from calling generate raster band stats double GDALrange[2]; GDALComputeRasterMinMax( myGdalBand, 1, GDALrange ); //Approximate setMaximumValue(theBandNo, GDALrange[1]); setMinimumValue(theBandNo, GDALrange[0]); } QgsDebugMsg("Starting main render loop"); // print each point in myGdalScanData with equal parts R, G ,B o make it show as gray double myGrayValue = 0.0; int myGrayVal = 0; int myAlphaValue = 0; QgsContrastEnhancement* myContrastEnhancement = getContrastEnhancement(theBandNo); for (int myColumn = 0; myColumn < theRasterViewPort->drawableAreaYDim; ++myColumn) { for (int myRow = 0; myRow < theRasterViewPort->drawableAreaXDim; ++myRow) { myGrayValue = readValue ( myGdalScanData, myDataType, myColumn * theRasterViewPort->drawableAreaXDim + myRow ); // If mNoDataValue is 'nan', the comparison // against myGrayVal will always fail ( nan==nan always // returns false, by design), hence the slightly odd comparison // of myGrayVal against itself. if (mValidNoDataValue && (myGrayValue == mNoDataValue || myGrayValue != myGrayValue)) { continue; } if(!myContrastEnhancement->isValueInDisplayableRange(myGrayValue)) { continue; } myAlphaValue = mRasterTransparency.getAlphaValue(myGrayValue, mTransparencyLevel); if(0 == myAlphaValue) { continue; } myGrayVal = myContrastEnhancement->stretch(myGrayValue); if (mInvertPixelsFlag) { myGrayVal = 255 - myGrayVal; } myQImage.setPixel(myRow, myColumn, qRgba(myGrayVal, myGrayVal, myGrayVal, myAlphaValue)); } } CPLFree ( myGdalScanData ); QgsDebugMsg("Render done, preparing to copy to canvas"); //render any inline filters filterLayer(&myQImage); paintImageToCanvas(theQPainter, theRasterViewPort, theQgsMapToPixel, &myQImage);} // QgsRasterLayer::drawSingleBandGrayvoid QgsRasterLayer::drawSingleBandPseudoColor(QPainter * theQPainter, QgsRasterViewPort * theRasterViewPort, QgsMapToPixel * theQgsMapToPixel, int theBandNo){ QgsDebugMsg("QgsRasterLayer::drawSingleBandPseudoColor called"); //Invalid band number, segfault prevention if(0 >= theBandNo) { return; } QgsRasterBandStats myRasterBandStats = getRasterBandStats(theBandNo); GDALRasterBandH myGdalBand = GDALGetRasterBand(mGdalDataset,theBandNo); GDALDataType myDataType = GDALGetRasterDataType(myGdalBand); void *myGdalScanData = readData ( myGdalBand, theRasterViewPort ); /* Check for out of memory error */ if (myGdalScanData == NULL) { return; } QImage myQImage = QImage(theRasterViewPort->drawableAreaXDim, theRasterViewPort->drawableAreaYDim, 32); myQImage.setAlphaBuffer(true); myQImage.fill(qRgba(255,255,255,0 )); // fill transparent if (NULL == mRasterShader) { return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -