00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "qgsapplication.h"
00020 #include "qgslogger.h"
00021 #include "qgsmaplayerregistry.h"
00022 #include "qgsmaptopixel.h"
00023 #include "qgsproviderregistry.h"
00024 #include "qgsrasterbandstats.h"
00025 #include "qgsrasterlayer.h"
00026 #include "qgsrasterpyramid.h"
00027 #include "qgsrectangle.h"
00028 #include "qgsrendercontext.h"
00029 #include "qgscoordinatereferencesystem.h"
00030
00031 #include "gdalwarper.h"
00032 #include "cpl_conv.h"
00033
00034 #include "qgspseudocolorshader.h"
00035 #include "qgsfreakoutshader.h"
00036 #include "qgscolorrampshader.h"
00037
00038 #include <cstdio>
00039 #include <cmath>
00040 #include <limits>
00041
00042 #include <QApplication>
00043 #include <QCursor>
00044 #include <QDomElement>
00045 #include <QDomNode>
00046 #include <QFile>
00047 #include <QFileInfo>
00048 #include <QFont>
00049 #include <QFontMetrics>
00050 #include <QFrame>
00051 #include <QImage>
00052 #include <QLabel>
00053 #include <QList>
00054 #include <QMatrix>
00055 #include <QMessageBox>
00056 #include <QLibrary>
00057 #include <QPainter>
00058 #include <QPixmap>
00059 #include <QRegExp>
00060 #include <QSlider>
00061 #include <QSettings>
00062 #include "qgslogger.h"
00063
00064
00065 #ifdef _MSC_VER
00066 # ifdef max
00067 # undef max
00068 # endif
00069 #endif
00070
00071
00072
00073
00074
00075 #define TINY_VALUE std::numeric_limits<double>::epsilon() * 20
00076
00077 #if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1800
00078 #define TO8F(x) (x).toUtf8().constData()
00079 #else
00080 #define TO8F(x) QFile::encodeName( x ).constData()
00081 #endif
00082
00083 QgsRasterLayer::QgsRasterLayer(
00084 QString const & path,
00085 QString const & baseName,
00086 bool loadDefaultStyleFlag )
00087 : QgsMapLayer( RasterLayer, baseName, path )
00088
00089 , QSTRING_NOT_SET( "Not Set" )
00090 , TRSTRING_NOT_SET( tr( "Not Set" ) )
00091 , mStandardDeviations( 0 )
00092 , mDataProvider( 0 )
00093 , mWidth( std::numeric_limits<int>::max() )
00094 , mHeight( std::numeric_limits<int>::max() )
00095 , mInvertColor( false )
00096 {
00097
00098 mRasterType = QgsRasterLayer::GrayOrUndefined;
00099
00100 mRedBandName = TRSTRING_NOT_SET;
00101 mGreenBandName = TRSTRING_NOT_SET;
00102 mBlueBandName = TRSTRING_NOT_SET;
00103 mGrayBandName = TRSTRING_NOT_SET;
00104 mTransparencyBandName = TRSTRING_NOT_SET;
00105
00106
00107 mUserDefinedRGBMinimumMaximum = false;
00108 mUserDefinedGrayMinimumMaximum = false;
00109 mRGBMinimumMaximumEstimated = true;
00110 mGrayMinimumMaximumEstimated = true;
00111
00112 mDrawingStyle = QgsRasterLayer::UndefinedDrawingStyle;
00113 mContrastEnhancementAlgorithm = QgsContrastEnhancement::NoEnhancement;
00114 mColorShadingAlgorithm = QgsRasterLayer::UndefinedShader;
00115 mRasterShader = new QgsRasterShader();
00116
00117 mBandCount = 0;
00118 mHasPyramids = false;
00119 mNoDataValue = -9999.0;
00120 mValidNoDataValue = false;
00121
00122 mGdalBaseDataset = 0;
00123 mGdalDataset = 0;
00124
00125
00126 mGeoTransform[0] = 0;
00127 mGeoTransform[1] = 1;
00128 mGeoTransform[2] = 0;
00129 mGeoTransform[3] = 0;
00130 mGeoTransform[4] = 0;
00131 mGeoTransform[5] = -1;
00132
00133
00134
00135 if ( ! baseName.isEmpty() )
00136 {
00137 setLayerName( baseName );
00138 }
00139
00140
00141 if ( ! path.isEmpty() )
00142 {
00143 readFile( path );
00144
00145
00146
00147 if ( loadDefaultStyleFlag )
00148 {
00149 bool defaultLoadedFlag = false;
00150 loadDefaultStyle( defaultLoadedFlag );
00151 if ( defaultLoadedFlag )
00152 {
00153 return;
00154 }
00155 }
00156 }
00157
00158
00159 mLastViewPort.rectXOffset = 0;
00160 mLastViewPort.rectXOffsetFloat = 0.0;
00161 mLastViewPort.rectYOffset = 0;
00162 mLastViewPort.rectYOffsetFloat = 0.0;
00163 mLastViewPort.clippedXMin = 0.0;
00164 mLastViewPort.clippedXMax = 0.0;
00165 mLastViewPort.clippedYMin = 0.0;
00166 mLastViewPort.clippedYMax = 0.0;
00167 mLastViewPort.clippedWidth = 0;
00168 mLastViewPort.clippedHeight = 0;
00169 mLastViewPort.drawableAreaXDim = 0;
00170 mLastViewPort.drawableAreaYDim = 0;
00171
00172 }
00173
00178 QgsRasterLayer::QgsRasterLayer( int dummy,
00179 QString const & rasterLayerPath,
00180 QString const & baseName,
00181 QString const & providerKey,
00182 QStringList const & layers,
00183 QStringList const & styles,
00184 QString const & format,
00185 QString const & crs )
00186 : QgsMapLayer( RasterLayer, baseName, rasterLayerPath )
00187 , mStandardDeviations( 0 )
00188 , mDataProvider( 0 )
00189 , mEditable( false )
00190 , mWidth( std::numeric_limits<int>::max() )
00191 , mHeight( std::numeric_limits<int>::max() )
00192 , mInvertColor( false )
00193 , mModified( false )
00194 , mProviderKey( providerKey )
00195 {
00196 QgsDebugMsg( "(8 arguments) starting. with layer list of " +
00197 layers.join( ", " ) + " and style list of " + styles.join( ", " ) + " and format of " +
00198 format + " and CRS of " + crs );
00199
00200 mBandCount = 0;
00201 mRasterShader = new QgsRasterShader();
00202
00203
00204 mGeoTransform[0] = 0;
00205 mGeoTransform[1] = 1;
00206 mGeoTransform[2] = 0;
00207 mGeoTransform[3] = 0;
00208 mGeoTransform[4] = 0;
00209 mGeoTransform[5] = -1;
00210
00211
00212 if ( ! providerKey.isEmpty() )
00213 {
00214 setDataProvider( providerKey, layers, styles, format, crs );
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 #if 0
00233 connect(
00234 mDataProvider, SIGNAL( statusChanged( QString ) ),
00235 this, SLOT( showStatusMessage( QString ) )
00236 );
00237 #endif
00238 QgsDebugMsg( "(8 arguments) exiting." );
00239
00240 emit statusChanged( tr( "QgsRasterLayer created" ) );
00241 }
00242
00243 QgsRasterLayer::~QgsRasterLayer()
00244 {
00245
00246 if ( mProviderKey.isEmpty() )
00247 {
00248 if ( mGdalBaseDataset )
00249 {
00250 GDALDereferenceDataset( mGdalBaseDataset );
00251 }
00252
00253 if ( mGdalDataset )
00254 {
00255 GDALClose( mGdalDataset );
00256 }
00257 }
00258 delete mRasterShader;
00259 }
00260
00261
00262
00263
00264
00266
00267
00268
00270
00280 void QgsRasterLayer::buildSupportedRasterFileFilter( QString & theFileFiltersString )
00281 {
00282
00283 registerGdalDrivers();
00284
00285
00286
00287
00288 GDALDriverH myGdalDriver;
00289
00290 char **myGdalDriverMetadata;
00291
00292 QString myGdalDriverLongName( "" );
00293 QString myGdalDriverExtension( "" );
00294 QString myGdalDriverDescription;
00295
00296 QStringList metadataTokens;
00297
00298 QStringList catchallFilter;
00299
00300
00301 GDALDriverH jp2Driver = NULL;
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 theFileFiltersString = tr( "[GDAL] All files (*)" );
00316
00317 for ( int i = 0; i < GDALGetDriverCount(); ++i )
00318 {
00319 myGdalDriver = GDALGetDriver( i );
00320
00321 Q_CHECK_PTR( myGdalDriver );
00322
00323 if ( !myGdalDriver )
00324 {
00325 QgsLogger::warning( "unable to get driver " + QString::number( i ) );
00326 continue;
00327 }
00328
00329
00330
00331 myGdalDriverDescription = GDALGetDescription( myGdalDriver );
00332
00333
00334
00335 myGdalDriverMetadata = GDALGetMetadata( myGdalDriver, NULL );
00336
00337
00338
00339 while ( myGdalDriverMetadata && '\0' != myGdalDriverMetadata[0] )
00340 {
00341 metadataTokens = QString( *myGdalDriverMetadata ).split( "=", QString::SkipEmptyParts );
00342
00343
00344
00345
00346
00347
00348
00349
00350 if ( metadataTokens.count() > 1 )
00351 {
00352 if ( "DMD_EXTENSION" == metadataTokens[0] )
00353 {
00354 myGdalDriverExtension = metadataTokens[1];
00355
00356 }
00357 else if ( "DMD_LONGNAME" == metadataTokens[0] )
00358 {
00359 myGdalDriverLongName = metadataTokens[1];
00360
00361
00362
00363
00364 myGdalDriverLongName.remove( QRegExp( "\\(.*\\)$" ) );
00365 }
00366 }
00367
00368
00369
00370
00371 if ( !( myGdalDriverExtension.isEmpty() || myGdalDriverLongName.isEmpty() ) )
00372 {
00373
00374 QString glob = "*." + myGdalDriverExtension.replace( "/", " *." );
00375
00376 if ( myGdalDriverDescription == "JPEG2000" ||
00377 myGdalDriverDescription.startsWith( "JP2" ) )
00378 {
00379 if ( jp2Driver )
00380 break;
00381
00382 jp2Driver = myGdalDriver;
00383 glob += " *.j2k";
00384 }
00385 else if ( myGdalDriverDescription == "GTiff" )
00386 {
00387 glob += " *.tiff";
00388 }
00389 else if ( myGdalDriverDescription == "JPEG" )
00390 {
00391 glob += " *.jpeg";
00392 }
00393
00394 theFileFiltersString += ";;[GDAL] " + myGdalDriverLongName + " (" + glob.toLower() + " " + glob.toUpper() + ")";
00395
00396 break;
00397 }
00398
00399 ++myGdalDriverMetadata;
00400
00401 }
00402
00403 if ( myGdalDriverExtension.isEmpty() && !myGdalDriverLongName.isEmpty() )
00404 {
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417 if ( myGdalDriverDescription.startsWith( "USGSDEM" ) )
00418 {
00419 QString glob = "*.dem";
00420 theFileFiltersString += ";;[GDAL] " + myGdalDriverLongName + " (" + glob.toLower() + " " + glob.toUpper() + ")";
00421 }
00422 else if ( myGdalDriverDescription.startsWith( "DTED" ) )
00423 {
00424
00425 QString glob = "*.dt0";
00426 glob += " *.dt1";
00427 glob += " *.dt2";
00428 theFileFiltersString += ";;[GDAL] " + myGdalDriverLongName + " (" + glob.toLower() + " " + glob.toUpper() + ")";
00429 }
00430 else if ( myGdalDriverDescription.startsWith( "MrSID" ) )
00431 {
00432
00433 QString glob = "*.sid";
00434 theFileFiltersString += ";;[GDAL] " + myGdalDriverLongName + " (" + glob.toLower() + " " + glob.toUpper() + ")";
00435 }
00436 else
00437 {
00438 catchallFilter << QString( GDALGetDescription( myGdalDriver ) );
00439 }
00440 }
00441
00442 myGdalDriverExtension = myGdalDriverLongName = "";
00443
00444 }
00445
00446 QgsDebugMsg( "Raster filter list built: " + theFileFiltersString );
00447 }
00448
00452 bool QgsRasterLayer::isValidRasterFileName( QString const & theFileNameQString, QString & retErrMsg )
00453 {
00454 GDALDatasetH myDataset;
00455 registerGdalDrivers();
00456
00457 CPLErrorReset();
00458
00459
00460 myDataset = GDALOpen( TO8F( theFileNameQString ), GA_ReadOnly );
00461 if ( myDataset == NULL )
00462 {
00463 if ( CPLGetLastErrorNo() != CPLE_OpenFailed )
00464 retErrMsg = QString::fromUtf8( CPLGetLastErrorMsg() );
00465 return false;
00466 }
00467 else if ( GDALGetRasterCount( myDataset ) == 0 )
00468 {
00469 QStringList layers = subLayers( myDataset );
00470 if ( layers.size() == 0 )
00471 {
00472 GDALClose( myDataset );
00473 myDataset = NULL;
00474 retErrMsg = tr( "This raster file has no bands and is invalid as a raster layer." );
00475 return false;
00476 }
00477 return true;
00478 }
00479 else
00480 {
00481 GDALClose( myDataset );
00482 return true;
00483 }
00484 }
00485
00486 bool QgsRasterLayer::isValidRasterFileName( QString const & theFileNameQString )
00487 {
00488 QString retErrMsg;
00489 return isValidRasterFileName( theFileNameQString, retErrMsg );
00490 }
00491
00492 QDateTime QgsRasterLayer::lastModified( QString const & name )
00493 {
00494 QgsDebugMsg( "name=" + name );
00495 QDateTime t;
00496
00497 QFileInfo fi( name );
00498
00499
00500 if ( !fi.exists() ) return t;
00501
00502 t = fi.lastModified();
00503
00504 QgsDebugMsg( "last modified = " + t.toString() );
00505
00506 return t;
00507 }
00508
00509
00510
00511 void QgsRasterLayer::registerGdalDrivers()
00512 {
00513 if ( GDALGetDriverCount() == 0 )
00514 GDALAllRegister();
00515 }
00516
00517
00518
00519
00521
00522
00523
00525
00526
00527 static QString makeTableCell_( QString const & value )
00528 {
00529 return "<p>\n" + value + "</p>\n";
00530 }
00531
00532
00533
00534
00535 static QString makeTableCells_( QStringList const & values )
00536 {
00537 QString s( "<tr>" );
00538
00539 for ( QStringList::const_iterator i = values.begin();
00540 i != values.end();
00541 ++i )
00542 {
00543 s += makeTableCell_( *i );
00544 }
00545
00546 s += "</tr>";
00547
00548 return s;
00549 }
00550
00551
00552
00553
00554 static QStringList cStringList2Q_( char ** stringList )
00555 {
00556 QStringList strings;
00557
00558
00559 for ( size_t i = 0; stringList[i]; ++i )
00560 {
00561 strings.append( stringList[i] );
00562 }
00563
00564 return strings;
00565
00566 }
00567
00568
00569
00570 typedef QgsDataProvider * classFactoryFunction_t( const QString * );
00571
00572
00573
00574
00575
00576 int CPL_STDCALL progressCallback( double dfComplete,
00577 const char * pszMessage,
00578 void * pProgressArg )
00579 {
00580 static double dfLastComplete = -1.0;
00581
00582 QgsRasterLayer * mypLayer = ( QgsRasterLayer * ) pProgressArg;
00583
00584 if ( dfLastComplete > dfComplete )
00585 {
00586 if ( dfLastComplete >= 1.0 )
00587 dfLastComplete = -1.0;
00588 else
00589 dfLastComplete = dfComplete;
00590 }
00591
00592 if ( floor( dfLastComplete*10 ) != floor( dfComplete*10 ) )
00593 {
00594 int nPercent = ( int ) floor( dfComplete * 100 );
00595
00596 if ( nPercent == 0 && pszMessage != NULL )
00597 {
00598
00599 }
00600
00601 if ( nPercent == 100 )
00602 {
00603
00604 mypLayer->showProgress( 100 );
00605 }
00606 else
00607 {
00608 int myProgress = ( int ) floor( dfComplete * 100 );
00609
00610 mypLayer->showProgress( myProgress );
00611
00612 }
00613 }
00614 dfLastComplete = dfComplete;
00615
00616 return true;
00617 }
00618
00619
00620
00621
00623
00624
00625
00627
00628 unsigned int QgsRasterLayer::bandCount()
00629 {
00630 return mBandCount;
00631 }
00632
00633 const QString QgsRasterLayer::bandName( int theBandNo )
00634 {
00635 if ( theBandNo <= mRasterStatsList.size() && theBandNo > 0 )
00636 {
00637
00638 return mRasterStatsList[theBandNo - 1].bandName;
00639 }
00640 else
00641 {
00642 return QString( "" );
00643 }
00644 }
00645
00646 int QgsRasterLayer::bandNumber( QString const & theBandName )
00647 {
00648 for ( int myIterator = 0; myIterator < mRasterStatsList.size(); ++myIterator )
00649 {
00650
00651 QgsRasterBandStats myRasterBandStats = mRasterStatsList[myIterator];
00652 QgsDebugMsg( "myRasterBandStats.bandName: " + myRasterBandStats.bandName + " :: theBandName: "
00653 + theBandName );
00654
00655 if ( myRasterBandStats.bandName == theBandName )
00656 {
00657 QgsDebugMsg( "********** band " + QString::number( myRasterBandStats.bandNumber ) +
00658 " was found in bandNumber " + theBandName );
00659
00660 return myRasterBandStats.bandNumber;
00661 }
00662 }
00663 QgsDebugMsg( "********** no band was found in bandNumber " + theBandName );
00664
00665 return 0;
00666 }
00667
00668
00688 const QgsRasterBandStats QgsRasterLayer::bandStatistics( int theBandNo )
00689 {
00690
00691 if (( GDALGetRasterCount( mGdalDataset ) < theBandNo ) && mRasterType != Palette )
00692 {
00693
00694 QgsRasterBandStats myNullReturnStats;
00695 return myNullReturnStats;
00696 }
00697 if ( mRasterType == Palette && ( theBandNo > 3 ) )
00698 {
00699
00700 QgsRasterBandStats myNullReturnStats;
00701 return myNullReturnStats;
00702 }
00703
00704
00705 if ( theBandNo < 1 || theBandNo > mRasterStatsList.size() )
00706 {
00707
00708 QgsRasterBandStats myNullReturnStats;
00709 return myNullReturnStats;
00710 }
00711
00712 QgsRasterBandStats myRasterBandStats = mRasterStatsList[theBandNo - 1];
00713 myRasterBandStats.bandNumber = theBandNo;
00714
00715
00716 if ( myRasterBandStats.statsGathered )
00717 {
00718 return myRasterBandStats;
00719 }
00720
00721 emit statusChanged( tr( "Retrieving stats for %1" ).arg( name() ) );
00722 qApp->processEvents();
00723 QgsDebugMsg( "stats for band " + QString::number( theBandNo ) );
00724 GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
00725
00726
00727 QString myColorerpretation = GDALGetColorInterpretationName( GDALGetRasterColorInterpretation( myGdalBand ) );
00728
00729
00730
00731
00732
00733 myRasterBandStats.elementCount = 0;
00734
00735 emit statusChanged( tr( "Calculating stats for %1" ).arg( name() ) );
00736
00737 emit drawingProgress( 0, 0 );
00738
00739
00740
00741
00742 GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
00743
00744 int myNXBlocks, myNYBlocks, myXBlockSize, myYBlockSize;
00745 GDALGetBlockSize( myGdalBand, &myXBlockSize, &myYBlockSize );
00746
00747 myNXBlocks = ( GDALGetRasterXSize( myGdalBand ) + myXBlockSize - 1 ) / myXBlockSize;
00748 myNYBlocks = ( GDALGetRasterYSize( myGdalBand ) + myYBlockSize - 1 ) / myYBlockSize;
00749
00750 void *myData = CPLMalloc( myXBlockSize * myYBlockSize * ( GDALGetDataTypeSize( myDataType ) / 8 ) );
00751
00752
00753 bool myFirstIterationFlag = true;
00754
00755
00756 #ifdef QGISDEBUG
00757 int success;
00758 double GDALminimum = GDALGetRasterMinimum( myGdalBand, &success );
00759
00760 if ( ! success )
00761 {
00762 QgsDebugMsg( "myGdalBand->GetMinimum() failed" );
00763 }
00764
00765 double GDALmaximum = GDALGetRasterMaximum( myGdalBand, &success );
00766
00767 if ( ! success )
00768 {
00769 QgsDebugMsg( "myGdalBand->GetMaximum() failed" );
00770 }
00771
00772 double GDALnodata = GDALGetRasterNoDataValue( myGdalBand, &success );
00773
00774 if ( ! success )
00775 {
00776 QgsDebugMsg( "myGdalBand->GetNoDataValue() failed" );
00777 }
00778
00779 QgsLogger::debug( "GDALminium: ", GDALminimum, __FILE__, __FUNCTION__, __LINE__ );
00780 QgsLogger::debug( "GDALmaximum: ", GDALmaximum, __FILE__, __FUNCTION__, __LINE__ );
00781 QgsLogger::debug( "GDALnodata: ", GDALnodata, __FILE__, __FUNCTION__, __LINE__ );
00782
00783 double GDALrange[2];
00784
00785
00786 GDALComputeRasterMinMax( myGdalBand, 1, GDALrange );
00787 QgsLogger::debug( "approximate computed GDALminium:", GDALrange[0], __FILE__, __FUNCTION__, __LINE__, 1 );
00788 QgsLogger::debug( "approximate computed GDALmaximum:", GDALrange[1], __FILE__, __FUNCTION__, __LINE__, 1 );
00789
00790 GDALComputeRasterMinMax( myGdalBand, 0, GDALrange );
00791 QgsLogger::debug( "exactly computed GDALminium:", GDALrange[0] );
00792 QgsLogger::debug( "exactly computed GDALmaximum:", GDALrange[1] );
00793
00794 QgsDebugMsg( "starting manual stat computation" );
00795 #endif
00796
00797 int myGdalBandXSize = GDALGetRasterXSize( myGdalBand );
00798 int myGdalBandYSize = GDALGetRasterYSize( myGdalBand );
00799 for ( int iYBlock = 0; iYBlock < myNYBlocks; iYBlock++ )
00800 {
00801 emit drawingProgress( iYBlock, myNYBlocks * 2 );
00802
00803 for ( int iXBlock = 0; iXBlock < myNXBlocks; iXBlock++ )
00804 {
00805 int nXValid, nYValid;
00806 GDALReadBlock( myGdalBand, iXBlock, iYBlock, myData );
00807
00808
00809
00810 if (( iXBlock + 1 ) * myXBlockSize > myGdalBandXSize )
00811 nXValid = myGdalBandXSize - iXBlock * myXBlockSize;
00812 else
00813 nXValid = myXBlockSize;
00814
00815 if (( iYBlock + 1 ) * myYBlockSize > myGdalBandYSize )
00816 nYValid = myGdalBandYSize - iYBlock * myYBlockSize;
00817 else
00818 nYValid = myYBlockSize;
00819
00820
00821 for ( int iY = 0; iY < nYValid; iY++ )
00822 {
00823 for ( int iX = 0; iX < nXValid; iX++ )
00824 {
00825 double myValue = readValue( myData, myDataType, iX + ( iY * myXBlockSize ) );
00826
00827 if ( mValidNoDataValue && ( fabs( myValue - mNoDataValue ) <= TINY_VALUE || myValue != myValue ) )
00828 {
00829 continue;
00830 }
00831
00832 myRasterBandStats.sum += myValue;
00833 ++myRasterBandStats.elementCount;
00834
00835 if ( myFirstIterationFlag )
00836 {
00837
00838 myFirstIterationFlag = false;
00839 myRasterBandStats.minimumValue = myValue;
00840 myRasterBandStats.maximumValue = myValue;
00841 }
00842 else
00843 {
00844
00845 if ( myValue < myRasterBandStats.minimumValue )
00846 {
00847 myRasterBandStats.minimumValue = myValue;
00848 }
00849 if ( myValue > myRasterBandStats.maximumValue )
00850 {
00851 myRasterBandStats.maximumValue = myValue;
00852 }
00853 }
00854 }
00855 }
00856 }
00857 }
00858
00859
00860
00861 myRasterBandStats.range = myRasterBandStats.maximumValue - myRasterBandStats.minimumValue;
00862
00863 myRasterBandStats.mean = myRasterBandStats.sum / myRasterBandStats.elementCount;
00864
00865
00866 for ( int iYBlock = 0; iYBlock < myNYBlocks; iYBlock++ )
00867 {
00868 emit drawingProgress( iYBlock + myNYBlocks, myNYBlocks * 2 );
00869
00870 for ( int iXBlock = 0; iXBlock < myNXBlocks; iXBlock++ )
00871 {
00872 int nXValid, nYValid;
00873
00874 GDALReadBlock( myGdalBand, iXBlock, iYBlock, myData );
00875
00876
00877
00878 if (( iXBlock + 1 ) * myXBlockSize > myGdalBandXSize )
00879 nXValid = myGdalBandXSize - iXBlock * myXBlockSize;
00880 else
00881 nXValid = myXBlockSize;
00882
00883 if (( iYBlock + 1 ) * myYBlockSize > myGdalBandYSize )
00884 nYValid = myGdalBandYSize - iYBlock * myYBlockSize;
00885 else
00886 nYValid = myYBlockSize;
00887
00888
00889 for ( int iY = 0; iY < nYValid; iY++ )
00890 {
00891 for ( int iX = 0; iX < nXValid; iX++ )
00892 {
00893 double myValue = readValue( myData, myDataType, iX + ( iY * myXBlockSize ) );
00894
00895 if ( mValidNoDataValue && ( fabs( myValue - mNoDataValue ) <= TINY_VALUE || myValue != myValue ) )
00896 {
00897 continue;
00898 }
00899
00900 myRasterBandStats.sumOfSquares += static_cast < double >
00901 ( pow( myValue - myRasterBandStats.mean, 2 ) );
00902 }
00903 }
00904 }
00905 }
00906
00907
00908 myRasterBandStats.stdDev = static_cast < double >( sqrt( myRasterBandStats.sumOfSquares /
00909 ( myRasterBandStats.elementCount - 1 ) ) );
00910
00911 #ifdef QGISDEBUG
00912 QgsLogger::debug( "************ STATS **************", 1, __FILE__, __FUNCTION__, __LINE__ );
00913 QgsLogger::debug( "VALID NODATA", mValidNoDataValue, 1, __FILE__, __FUNCTION__, __LINE__ );
00914 QgsLogger::debug( "NULL", mNoDataValue, 1, __FILE__, __FUNCTION__, __LINE__ );
00915 QgsLogger::debug( "MIN", myRasterBandStats.minimumValue, 1, __FILE__, __FUNCTION__, __LINE__ );
00916 QgsLogger::debug( "MAX", myRasterBandStats.maximumValue, 1, __FILE__, __FUNCTION__, __LINE__ );
00917 QgsLogger::debug( "RANGE", myRasterBandStats.range, 1, __FILE__, __FUNCTION__, __LINE__ );
00918 QgsLogger::debug( "MEAN", myRasterBandStats.mean, 1, __FILE__, __FUNCTION__, __LINE__ );
00919 QgsLogger::debug( "STDDEV", myRasterBandStats.stdDev, 1, __FILE__, __FUNCTION__, __LINE__ );
00920 #endif
00921
00922 CPLFree( myData );
00923 myRasterBandStats.statsGathered = true;
00924
00925 QgsDebugMsg( "adding stats to stats collection at position " + QString::number( theBandNo - 1 ) );
00926
00927 mRasterStatsList[theBandNo - 1] = myRasterBandStats;
00928 emit drawingProgress( mHeight, mHeight );
00929
00930 QgsDebugMsg( "Stats collection completed returning" );
00931 return myRasterBandStats;
00932
00933 }
00934
00935 const QgsRasterBandStats QgsRasterLayer::bandStatistics( QString const & theBandName )
00936 {
00937
00938
00939
00940 for ( int i = 1; i <= GDALGetRasterCount( mGdalDataset ); i++ )
00941 {
00942 QgsRasterBandStats myRasterBandStats = bandStatistics( i );
00943 if ( myRasterBandStats.bandName == theBandName )
00944 {
00945 return myRasterBandStats;
00946 }
00947 }
00948
00949 return QgsRasterBandStats();
00950 }
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963 QString QgsRasterLayer::buildPyramids( RasterPyramidList const & theRasterPyramidList,
00964 QString const & theResamplingMethod, bool theTryInternalFlag )
00965 {
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977 emit drawingProgress( 0, 0 );
00978
00979 QFileInfo myQFile( mDataSource );
00980
00981 if ( !myQFile.isWritable() )
00982 {
00983 return "ERROR_WRITE_ACCESS";
00984 }
00985
00986 if ( mGdalDataset != mGdalBaseDataset )
00987 {
00988 QgsLogger::warning( "Pyramid building not currently supported for 'warped virtual dataset'." );
00989 return "ERROR_VIRTUAL";
00990 }
00991
00992 if ( theTryInternalFlag )
00993 {
00994
00995
00996
00997 const char* pszGTiffCreationOptions =
00998 GDALGetMetadataItem( GDALGetDriverByName( "GTiff" ), GDAL_DMD_CREATIONOPTIONLIST, "" );
00999 if ( strstr( pszGTiffCreationOptions, "BIGTIFF" ) == NULL )
01000 {
01001 QString myCompressionType = QString( GDALGetMetadataItem( mGdalDataset, "COMPRESSION", "IMAGE_STRUCTURE" ) );
01002 if ( "JPEG" == myCompressionType )
01003 {
01004 return "ERROR_JPEG_COMPRESSION";
01005 }
01006 }
01007
01008
01009 GDALClose( mGdalDataset );
01010 mGdalBaseDataset = GDALOpen( TO8F( mDataSource ), GA_Update );
01011
01012
01013 if ( !mGdalBaseDataset )
01014 {
01015 mGdalBaseDataset = GDALOpen( TO8F( mDataSource ), GA_ReadOnly );
01016
01017 mGdalDataset = mGdalBaseDataset;
01018 return "ERROR_WRITE_FORMAT";
01019 }
01020 }
01021
01022
01023
01024
01025
01026 CPLErr myError;
01027 int myCount = 1;
01028 int myTotal = theRasterPyramidList.count();
01029 RasterPyramidList::const_iterator myRasterPyramidIterator;
01030 for ( myRasterPyramidIterator = theRasterPyramidList.begin();
01031 myRasterPyramidIterator != theRasterPyramidList.end();
01032 ++myRasterPyramidIterator )
01033 {
01034 #ifdef QGISDEBUG
01035 QgsLogger::debug( "Build pyramids:: Level", ( *myRasterPyramidIterator ).level, 1, __FILE__, __FUNCTION__, __LINE__ );
01036 QgsLogger::debug( "x", ( *myRasterPyramidIterator ).xDim, 1, __FILE__, __FUNCTION__, __LINE__ );
01037 QgsLogger::debug( "y", ( *myRasterPyramidIterator ).yDim, 1, __FILE__, __FUNCTION__, __LINE__ );
01038 QgsLogger::debug( "exists :", ( *myRasterPyramidIterator ).exists, 1, __FILE__, __FUNCTION__, __LINE__ );
01039 #endif
01040 if (( *myRasterPyramidIterator ).build )
01041 {
01042 QgsDebugMsg( "Building....." );
01043 emit drawingProgress( myCount, myTotal );
01044 int myOverviewLevelsArray[1] = {( *myRasterPyramidIterator ).level };
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055 try
01056 {
01057
01058
01059
01060
01061
01062
01063 if ( theResamplingMethod == tr( "Average Magphase" ) )
01064 {
01065 myError = GDALBuildOverviews( mGdalBaseDataset, "MODE", 1, myOverviewLevelsArray, 0, NULL,
01066 progressCallback, this );
01067 }
01068 else if ( theResamplingMethod == tr( "Average" ) )
01069
01070 {
01071 myError = GDALBuildOverviews( mGdalBaseDataset, "AVERAGE", 1, myOverviewLevelsArray, 0, NULL,
01072 progressCallback, this );
01073 }
01074 else
01075 {
01076 myError = GDALBuildOverviews( mGdalBaseDataset, "NEAREST", 1, myOverviewLevelsArray, 0, NULL,
01077 progressCallback, this );
01078 }
01079
01080 if ( myError == CE_Failure || CPLGetLastErrorNo() == CPLE_NotSupported )
01081 {
01082
01083
01084 GDALClose( mGdalBaseDataset );
01085 mGdalBaseDataset = GDALOpen( TO8F( mDataSource ), GA_ReadOnly );
01086
01087 mGdalDataset = mGdalBaseDataset;
01088
01089 emit drawingProgress( 0, 0 );
01090 return "FAILED_NOT_SUPPORTED";
01091 }
01092 else
01093 {
01094
01095 mHasPyramids = true;
01096 }
01097 myCount++;
01098
01099 }
01100 catch ( CPLErr )
01101 {
01102 QgsLogger::warning( "Pyramid overview building failed!" );
01103 }
01104 }
01105 }
01106
01107 QgsDebugMsg( "Pyramid overviews built" );
01108 if ( theTryInternalFlag )
01109 {
01110
01111 GDALClose( mGdalBaseDataset );
01112 mGdalBaseDataset = GDALOpen( TO8F( mDataSource ), GA_ReadOnly );
01113
01114 mGdalDataset = mGdalBaseDataset;
01115 }
01116
01117 emit drawingProgress( 0, 0 );
01118 return NULL;
01119 }
01120
01121
01122 QgsRasterLayer::RasterPyramidList QgsRasterLayer::buildPyramidList()
01123 {
01124
01125
01126
01127 int myWidth = mWidth;
01128 int myHeight = mHeight;
01129 int myDivisor = 2;
01130
01131 if ( mDataProvider ) return mPyramidList;
01132
01133 GDALRasterBandH myGDALBand = GDALGetRasterBand( mGdalDataset, 1 );
01134
01135 mPyramidList.clear();
01136 QgsDebugMsg( "Building initial pyramid list" );
01137 while (( myWidth / myDivisor > 32 ) && (( myHeight / myDivisor ) > 32 ) )
01138 {
01139
01140 QgsRasterPyramid myRasterPyramid;
01141 myRasterPyramid.level = myDivisor;
01142 myRasterPyramid.xDim = ( int )( 0.5 + ( myWidth / ( double )myDivisor ) );
01143 myRasterPyramid.yDim = ( int )( 0.5 + ( myHeight / ( double )myDivisor ) );
01144 myRasterPyramid.exists = false;
01145 #ifdef QGISDEBUG
01146 QgsLogger::debug( "Pyramid", myRasterPyramid.level, 1, __FILE__, __FUNCTION__, __LINE__ );
01147 QgsLogger::debug( "xDim", myRasterPyramid.xDim, 1, __FILE__, __FUNCTION__, __LINE__ );
01148 QgsLogger::debug( "yDim", myRasterPyramid.yDim, 1, __FILE__, __FUNCTION__, __LINE__ );
01149 #endif
01150
01151
01152
01153
01154
01155
01156 const int myNearMatchLimit = 5;
01157 if ( GDALGetOverviewCount( myGDALBand ) > 0 )
01158 {
01159 int myOverviewCount;
01160 for ( myOverviewCount = 0;
01161 myOverviewCount < GDALGetOverviewCount( myGDALBand );
01162 ++myOverviewCount )
01163 {
01164 GDALRasterBandH myOverview;
01165 myOverview = GDALGetOverview( myGDALBand, myOverviewCount );
01166 int myOverviewXDim = GDALGetRasterBandXSize( myOverview );
01167 int myOverviewYDim = GDALGetRasterBandYSize( myOverview );
01168
01169
01170
01171
01172 QgsDebugMsg( "Checking whether " + QString::number( myRasterPyramid.xDim ) + " x " +
01173 QString::number( myRasterPyramid.yDim ) + " matches " +
01174 QString::number( myOverviewXDim ) + " x " + QString::number( myOverviewYDim ) );
01175
01176
01177 if (( myOverviewXDim <= ( myRasterPyramid.xDim + myNearMatchLimit ) ) &&
01178 ( myOverviewXDim >= ( myRasterPyramid.xDim - myNearMatchLimit ) ) &&
01179 ( myOverviewYDim <= ( myRasterPyramid.yDim + myNearMatchLimit ) ) &&
01180 ( myOverviewYDim >= ( myRasterPyramid.yDim - myNearMatchLimit ) ) )
01181 {
01182
01183 myRasterPyramid.xDim = myOverviewXDim;
01184 myRasterPyramid.yDim = myOverviewYDim;
01185 myRasterPyramid.exists = true;
01186 QgsDebugMsg( ".....YES!" );
01187 }
01188 else
01189 {
01190
01191 QgsDebugMsg( ".....no." );
01192 }
01193 }
01194 }
01195 mPyramidList.append( myRasterPyramid );
01196
01197 myDivisor = ( myDivisor * 2 );
01198 }
01199
01200 return mPyramidList;
01201 }
01202
01203 QString QgsRasterLayer::colorShadingAlgorithmAsString() const
01204 {
01205 switch ( mColorShadingAlgorithm )
01206 {
01207 case PseudoColorShader:
01208 return QString( "PseudoColorShader" );
01209 break;
01210 case FreakOutShader:
01211 return QString( "FreakOutShader" );
01212 break;
01213 case ColorRampShader:
01214 return QString( "ColorRampShader" );
01215 break;
01216 case UserDefinedShader:
01217 return QString( "UserDefinedShader" );
01218 break;
01219 default:
01220 break;
01221 }
01222
01223 return QString( "UndefinedShader" );
01224 }
01225
01230 void QgsRasterLayer::computeMinimumMaximumEstimates( int theBand, double* theMinMax )
01231 {
01232 if ( 0 == theMinMax ) { return; }
01233
01234 if ( 0 < theBand && theBand <= ( int ) bandCount() )
01235 {
01236 GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBand );
01237 GDALComputeRasterMinMax( myGdalBand, 1, theMinMax );
01238 }
01239 }
01240
01245 void QgsRasterLayer::computeMinimumMaximumEstimates( QString theBand, double* theMinMax )
01246 {
01247 computeMinimumMaximumEstimates( bandNumber( theBand ), theMinMax );
01248 }
01249
01250 void QgsRasterLayer::computeMinimumMaximumEstimates( int theBand, double& theMin, double& theMax )
01251 {
01252 double theMinMax[2];
01253 computeMinimumMaximumEstimates( theBand, theMinMax );
01254 theMin = theMinMax[0];
01255 theMax = theMinMax[1];
01256 }
01257
01262 void QgsRasterLayer::computeMinimumMaximumFromLastExtent( int theBand, double* theMinMax )
01263 {
01264 if ( 0 == theMinMax ) { return; }
01265
01266 GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBand );
01267 GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
01268 void* myGdalScanData = readData( myGdalBand, &mLastViewPort );
01269
01270
01271 if ( myGdalScanData == NULL )
01272 {
01273 return;
01274 }
01275
01276 if ( 0 < theBand && theBand <= ( int ) bandCount() )
01277 {
01278 float myMin = std::numeric_limits<float>::max();
01279 float myMax = -1 * std::numeric_limits<float>::max();
01280 float myValue = 0.0;
01281 for ( int myRow = 0; myRow < mLastViewPort.drawableAreaYDim; ++myRow )
01282 {
01283 for ( int myColumn = 0; myColumn < mLastViewPort.drawableAreaXDim; ++myColumn )
01284 {
01285 myValue = readValue( myGdalScanData, myDataType, myRow * mLastViewPort.drawableAreaXDim + myColumn );
01286 if ( mValidNoDataValue && ( fabs( myValue - mNoDataValue ) <= TINY_VALUE || myValue != myValue ) )
01287 {
01288 continue;
01289 }
01290 myMin = qMin( myMin, myValue );
01291 myMax = qMax( myMax, myValue );
01292 }
01293 }
01294 theMinMax[0] = myMin;
01295 theMinMax[1] = myMax;
01296 }
01297 }
01298
01303 void QgsRasterLayer::computeMinimumMaximumFromLastExtent( QString theBand, double* theMinMax )
01304 {
01305 computeMinimumMaximumFromLastExtent( bandNumber( theBand ), theMinMax );
01306 }
01307
01308 void QgsRasterLayer::computeMinimumMaximumFromLastExtent( int theBand, double& theMin, double& theMax )
01309 {
01310 double theMinMax[2];
01311 computeMinimumMaximumFromLastExtent( theBand, theMinMax );
01312 theMin = theMinMax[0];
01313 theMax = theMinMax[1];
01314 }
01315
01320 QgsContrastEnhancement* QgsRasterLayer::contrastEnhancement( unsigned int theBand )
01321 {
01322 if ( 0 < theBand && theBand <= bandCount() )
01323 {
01324 return &mContrastEnhancementList[theBand - 1];
01325 }
01326
01327 return 0;
01328 }
01329
01330 QString QgsRasterLayer::contrastEnhancementAlgorithmAsString() const
01331 {
01332 switch ( mContrastEnhancementAlgorithm )
01333 {
01334 case QgsContrastEnhancement::NoEnhancement:
01335 return QString( "NoEnhancement" );
01336 break;
01337 case QgsContrastEnhancement::StretchToMinimumMaximum:
01338 return QString( "StretchToMinimumMaximum" );
01339 break;
01340 case QgsContrastEnhancement::StretchAndClipToMinimumMaximum:
01341 return QString( "StretchAndClipToMinimumMaximum" );
01342 break;
01343 case QgsContrastEnhancement::ClipToMinimumMaximum:
01344 return QString( "ClipToMinimumMaximum" );
01345 break;
01346 case QgsContrastEnhancement::UserDefinedEnhancement:
01347 return QString( "UserDefined" );
01348 break;
01349 }
01350
01351 return QString( "NoEnhancement" );
01352 }
01353
01358 bool QgsRasterLayer::copySymbologySettings( const QgsMapLayer& theOther )
01359 {
01360
01361 if ( theOther.type() < 0 )
01362 {
01363 return false;
01364 }
01365 return false;
01366 }
01367
01372 QList<QgsColorRampShader::ColorRampItem>* QgsRasterLayer::colorTable( int theBandNo )
01373 {
01374 return &( mRasterStatsList[theBandNo-1].colorTable );
01375 }
01376
01380 QgsRasterDataProvider* QgsRasterLayer::dataProvider()
01381 {
01382 return mDataProvider;
01383 }
01384
01388 const QgsRasterDataProvider* QgsRasterLayer::dataProvider() const
01389 {
01390 return mDataProvider;
01391 }
01392
01393 void QgsRasterLayer::reload()
01394 {
01395 if ( mDataProvider )
01396 {
01397 mDataProvider->reloadData();
01398 }
01399 }
01400
01401 bool QgsRasterLayer::draw( QgsRenderContext& rendererContext )
01402 {
01403 QgsDebugMsg( "entered. (renderContext)" );
01404
01405
01406 if ( mTransparencyLevel == 0 )
01407 return true;
01408
01409 QgsDebugMsg( "checking timestamp." );
01410
01411
01412 if ( !update() )
01413 {
01414 return false;
01415 }
01416
01417 const QgsMapToPixel& theQgsMapToPixel = rendererContext.mapToPixel();
01418 const QgsRectangle& theViewExtent = rendererContext.extent();
01419 QPainter* theQPainter = rendererContext.painter();
01420
01421 if ( !theQPainter )
01422 {
01423 return false;
01424 }
01425
01426
01427 QgsRectangle myRasterExtent = theViewExtent.intersect( &mLayerExtent );
01428 if ( myRasterExtent.isEmpty() )
01429 {
01430 QgsDebugMsg( "draw request outside view extent." );
01431
01432 return true;
01433 }
01434
01435 QgsDebugMsg( "theViewExtent is " + theViewExtent.toString() );
01436 QgsDebugMsg( "myRasterExtent is " + myRasterExtent.toString() );
01437
01438
01439
01440
01441
01442
01443
01444
01445 QgsRasterViewPort *myRasterViewPort = new QgsRasterViewPort();
01446
01447
01448
01449
01450
01451 myRasterViewPort->rectXOffsetFloat = ( theViewExtent.xMinimum() - mLayerExtent.xMinimum() ) / fabs( mGeoTransform[1] );
01452 myRasterViewPort->rectYOffsetFloat = ( mLayerExtent.yMaximum() - theViewExtent.yMaximum() ) / fabs( mGeoTransform[5] );
01453
01454 if ( myRasterViewPort->rectXOffsetFloat < 0 )
01455 {
01456 myRasterViewPort->rectXOffsetFloat = 0;
01457 }
01458
01459 if ( myRasterViewPort->rectYOffsetFloat < 0 )
01460 {
01461 myRasterViewPort->rectYOffsetFloat = 0;
01462 }
01463
01464 myRasterViewPort->rectXOffset = static_cast < int >( myRasterViewPort->rectXOffsetFloat );
01465 myRasterViewPort->rectYOffset = static_cast < int >( myRasterViewPort->rectYOffsetFloat );
01466
01467 QgsDebugMsgLevel( QString( "mGeoTransform: %1, %2, %3, %4, %5, %6" )
01468 .arg( mGeoTransform[0] )
01469 .arg( mGeoTransform[1] )
01470 .arg( mGeoTransform[2] )
01471 .arg( mGeoTransform[3] )
01472 .arg( mGeoTransform[4] )
01473 .arg( mGeoTransform[5] ), 3 );
01474
01475
01476
01477
01478
01479 myRasterViewPort->clippedXMin = ( myRasterExtent.xMinimum() - mGeoTransform[0] ) / mGeoTransform[1];
01480 myRasterViewPort->clippedXMax = ( myRasterExtent.xMaximum() - mGeoTransform[0] ) / mGeoTransform[1];
01481 myRasterViewPort->clippedYMin = ( myRasterExtent.yMinimum() - mGeoTransform[3] ) / mGeoTransform[5];
01482 myRasterViewPort->clippedYMax = ( myRasterExtent.yMaximum() - mGeoTransform[3] ) / mGeoTransform[5];
01483
01484
01485 if ( myRasterViewPort->clippedYMin > myRasterViewPort->clippedYMax )
01486 {
01487 double t = myRasterViewPort->clippedYMin;
01488 myRasterViewPort->clippedYMin = myRasterViewPort->clippedYMax;
01489 myRasterViewPort->clippedYMax = t;
01490 }
01491
01492
01493
01494 myRasterViewPort->clippedWidth =
01495 static_cast<int>( ceil( myRasterViewPort->clippedXMax ) - floor( myRasterViewPort->clippedXMin ) );
01496
01497 myRasterViewPort->clippedHeight =
01498 static_cast<int>( ceil( myRasterViewPort->clippedYMax ) - floor( myRasterViewPort->clippedYMin ) );
01499
01500
01501
01502
01503 if (( myRasterViewPort->rectXOffset + myRasterViewPort->clippedWidth )
01504 > mWidth )
01505 {
01506 myRasterViewPort->clippedWidth =
01507 mWidth - myRasterViewPort->rectXOffset;
01508 }
01509 if (( myRasterViewPort->rectYOffset + myRasterViewPort->clippedHeight )
01510 > mHeight )
01511 {
01512 myRasterViewPort->clippedHeight =
01513 mHeight - myRasterViewPort->rectYOffset;
01514 }
01515
01516
01517 myRasterViewPort->topLeftPoint = theQgsMapToPixel.transform( myRasterExtent.xMinimum(), myRasterExtent.yMaximum() );
01518 myRasterViewPort->bottomRightPoint = theQgsMapToPixel.transform( myRasterExtent.xMaximum(), myRasterExtent.yMinimum() );
01519
01520 myRasterViewPort->drawableAreaXDim = static_cast<int>( fabs(( myRasterViewPort->clippedWidth / theQgsMapToPixel.mapUnitsPerPixel() * mGeoTransform[1] ) ) + 0.5 );
01521 myRasterViewPort->drawableAreaYDim = static_cast<int>( fabs(( myRasterViewPort->clippedHeight / theQgsMapToPixel.mapUnitsPerPixel() * mGeoTransform[5] ) ) + 0.5 );
01522
01523
01524
01525
01526 if ( 2 >= myRasterViewPort->clippedWidth && 2 >= myRasterViewPort->clippedHeight )
01527 {
01528 myRasterViewPort->drawableAreaXDim = myRasterViewPort->clippedWidth;
01529 myRasterViewPort->drawableAreaYDim = myRasterViewPort->clippedHeight;
01530 }
01531
01532 QgsDebugMsgLevel( QString( "mapUnitsPerPixel = %1" ).arg( theQgsMapToPixel.mapUnitsPerPixel() ), 3 );
01533 QgsDebugMsgLevel( QString( "mWidth = %1" ).arg( mWidth ), 3 );
01534 QgsDebugMsgLevel( QString( "mHeight = %1" ).arg( mHeight ), 3 );
01535 QgsDebugMsgLevel( QString( "rectXOffset = %1" ).arg( myRasterViewPort->rectXOffset ), 3 );
01536 QgsDebugMsgLevel( QString( "rectXOffsetFloat = %1" ).arg( myRasterViewPort->rectXOffsetFloat ), 3 );
01537 QgsDebugMsgLevel( QString( "rectYOffset = %1" ).arg( myRasterViewPort->rectYOffset ), 3 );
01538 QgsDebugMsgLevel( QString( "rectYOffsetFloat = %1" ).arg( myRasterViewPort->rectYOffsetFloat ), 3 );
01539
01540 QgsDebugMsgLevel( QString( "myRasterExtent.xMinimum() = %1" ).arg( myRasterExtent.xMinimum() ), 3 );
01541 QgsDebugMsgLevel( QString( "myRasterExtent.xMaximum() = %1" ).arg( myRasterExtent.xMaximum() ), 3 );
01542 QgsDebugMsgLevel( QString( "myRasterExtent.yMinimum() = %1" ).arg( myRasterExtent.yMinimum() ), 3 );
01543 QgsDebugMsgLevel( QString( "myRasterExtent.yMaximum() = %1" ).arg( myRasterExtent.yMaximum() ), 3 );
01544
01545 QgsDebugMsgLevel( QString( "topLeftPoint.x() = %1" ).arg( myRasterViewPort->topLeftPoint.x() ), 3 );
01546 QgsDebugMsgLevel( QString( "bottomRightPoint.x() = %1" ).arg( myRasterViewPort->bottomRightPoint.x() ), 3 );
01547 QgsDebugMsgLevel( QString( "topLeftPoint.y() = %1" ).arg( myRasterViewPort->topLeftPoint.y() ), 3 );
01548 QgsDebugMsgLevel( QString( "bottomRightPoint.y() = %1" ).arg( myRasterViewPort->bottomRightPoint.y() ), 3 );
01549
01550 QgsDebugMsgLevel( QString( "clippedXMin = %1" ).arg( myRasterViewPort->clippedXMin ), 3 );
01551 QgsDebugMsgLevel( QString( "clippedXMax = %1" ).arg( myRasterViewPort->clippedXMax ), 3 );
01552 QgsDebugMsgLevel( QString( "clippedYMin = %1" ).arg( myRasterViewPort->clippedYMin ), 3 );
01553 QgsDebugMsgLevel( QString( "clippedYMax = %1" ).arg( myRasterViewPort->clippedYMax ), 3 );
01554
01555 QgsDebugMsgLevel( QString( "clippedWidth = %1" ).arg( myRasterViewPort->clippedWidth ), 3 );
01556 QgsDebugMsgLevel( QString( "clippedHeight = %1" ).arg( myRasterViewPort->clippedHeight ), 3 );
01557 QgsDebugMsgLevel( QString( "drawableAreaXDim = %1" ).arg( myRasterViewPort->drawableAreaXDim ), 3 );
01558 QgsDebugMsgLevel( QString( "drawableAreaYDim = %1" ).arg( myRasterViewPort->drawableAreaYDim ), 3 );
01559
01560 QgsDebugMsgLevel( "ReadXml: gray band name : " + mGrayBandName, 3 );
01561 QgsDebugMsgLevel( "ReadXml: red band name : " + mRedBandName, 3 );
01562 QgsDebugMsgLevel( "ReadXml: green band name : " + mGreenBandName, 3 );
01563 QgsDebugMsgLevel( "ReadXml: blue band name : " + mBlueBandName, 3 );
01564
01565
01566
01567 mLastViewPort = *myRasterViewPort;
01568
01569
01570
01571 QgsDebugMsg( "Checking for provider key." );
01572
01573 if ( !mProviderKey.isEmpty() )
01574 {
01575 QgsDebugMsg( "Wanting a '" + mProviderKey + "' provider to draw this." );
01576
01577 mDataProvider->setDpi( rendererContext.rasterScaleFactor() * 25.4 * rendererContext.scaleFactor() );
01578
01579
01580
01581 int totalPixelWidth = fabs(( myRasterViewPort->clippedXMax - myRasterViewPort->clippedXMin )
01582 / theQgsMapToPixel.mapUnitsPerPixel() * mGeoTransform[1] ) + 1;
01583 int totalPixelHeight = fabs(( myRasterViewPort->clippedYMax - myRasterViewPort->clippedYMin )
01584 / theQgsMapToPixel.mapUnitsPerPixel() * mGeoTransform[5] ) + 1;
01585 int numParts = totalPixelWidth * totalPixelHeight / 5000000 + 1.0;
01586 int numRowsPerPart = totalPixelHeight / numParts + 1.0;
01587
01588
01589 int currentPixelOffsetY = 0;
01590
01591 int pixelWidth = ( myRasterExtent.xMaximum() - myRasterExtent.xMinimum() ) / theQgsMapToPixel.mapUnitsPerPixel() + 0.5;
01592 for ( int i = 0; i < numParts; ++i )
01593 {
01594
01595 QgsRectangle rasterPartRect( myRasterExtent.xMinimum(), myRasterExtent.yMaximum() - ( currentPixelOffsetY + numRowsPerPart + 2 ) * theQgsMapToPixel.mapUnitsPerPixel(),
01596 myRasterExtent.xMaximum(), myRasterExtent.yMaximum() - currentPixelOffsetY * theQgsMapToPixel.mapUnitsPerPixel() );
01597
01598 int pixelHeight = rasterPartRect.height() / theQgsMapToPixel.mapUnitsPerPixel() + 0.5;
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608 QImage* image = mDataProvider->draw( rasterPartRect, pixelWidth, pixelHeight );
01609
01610 if ( !image )
01611 {
01612
01613 mErrorCaption = mDataProvider->lastErrorTitle();
01614 mError = mDataProvider->lastError();
01615
01616 delete myRasterViewPort;
01617 return false;
01618 }
01619
01620 QgsDebugMsg( "done mDataProvider->draw." );
01621
01622 QgsDebugMsgLevel( QString( "image stats: depth=%1 bytes=%2 width=%3 height=%4" ).arg( image->depth() )
01623 .arg( image->numBytes() )
01624 .arg( image->width() )
01625 .arg( image->height() ),
01626 3 );
01627
01628 QgsDebugMsgLevel( QString( "Want to theQPainter->drawImage with origin x: %1 (%2) %3 (%4)" )
01629 .arg( myRasterViewPort->topLeftPoint.x() ).arg( static_cast<int>( myRasterViewPort->topLeftPoint.x() ) )
01630 .arg( myRasterViewPort->topLeftPoint.y() ).arg( static_cast<int>( myRasterViewPort->topLeftPoint.y() ) ),
01631 3 );
01632
01633
01634
01635
01636
01637 if ( mTransparencyLevel != 255 )
01638 {
01639 QImage* transparentImageCopy = new QImage( *image );
01640 image = transparentImageCopy;
01641 int myWidth = image->width();
01642 int myHeight = image->height();
01643 QRgb myRgb;
01644 int newTransparency;
01645 for ( int myHeightRunner = 0; myHeightRunner < myHeight; myHeightRunner++ )
01646 {
01647 QRgb* myLineBuffer = ( QRgb* ) transparentImageCopy->scanLine( myHeightRunner );
01648 for ( int myWidthRunner = 0; myWidthRunner < myWidth; myWidthRunner++ )
01649 {
01650 myRgb = image->pixel( myWidthRunner, myHeightRunner );
01651
01652 newTransparency = ( double ) mTransparencyLevel / 255.0 * ( double )( qAlpha( myRgb ) );
01653 myLineBuffer[ myWidthRunner ] = qRgba( qRed( myRgb ), qGreen( myRgb ), qBlue( myRgb ), newTransparency );
01654 }
01655 }
01656 }
01657
01658 theQPainter->drawImage( myRasterViewPort->topLeftPoint.x(), myRasterViewPort->topLeftPoint.y() + currentPixelOffsetY, *image );
01659 currentPixelOffsetY += numRowsPerPart;
01660
01661 if ( mTransparencyLevel != 255 )
01662 {
01663 delete image;
01664 }
01665 }
01666 }
01667 else
01668 {
01669
01670
01671
01672
01673
01674
01675
01676 draw( theQPainter, myRasterViewPort, &theQgsMapToPixel );
01677
01678 }
01679
01680 delete myRasterViewPort;
01681 QgsDebugMsg( "exiting." );
01682
01683 return true;
01684
01685 }
01686
01687 void QgsRasterLayer::draw( QPainter * theQPainter,
01688 QgsRasterViewPort * theRasterViewPort,
01689 const QgsMapToPixel* theQgsMapToPixel )
01690 {
01691 QgsDebugMsg( " 3 arguments" );
01692
01693
01694
01695
01696
01697
01698
01699 switch ( mDrawingStyle )
01700 {
01701
01702 case SingleBandGray:
01703
01704 if ( mGrayBandName == TRSTRING_NOT_SET )
01705 {
01706 break;
01707 }
01708 else
01709 {
01710 drawSingleBandGray( theQPainter, theRasterViewPort,
01711 theQgsMapToPixel, bandNumber( mGrayBandName ) );
01712 break;
01713 }
01714
01715 case SingleBandPseudoColor:
01716
01717 if ( mGrayBandName == TRSTRING_NOT_SET )
01718 {
01719 break;
01720 }
01721 else
01722 {
01723 drawSingleBandPseudoColor( theQPainter, theRasterViewPort,
01724 theQgsMapToPixel, bandNumber( mGrayBandName ) );
01725 break;
01726 }
01727
01728 case PalettedColor:
01729
01730 if ( mGrayBandName == TRSTRING_NOT_SET )
01731 {
01732 break;
01733 }
01734 else
01735 {
01736 QgsDebugMsg( "PalettedColor drawing type detected..." );
01737
01738 drawPalettedSingleBandColor( theQPainter, theRasterViewPort,
01739 theQgsMapToPixel, bandNumber( mGrayBandName ) );
01740
01741 break;
01742 }
01743
01744 case PalettedSingleBandGray:
01745
01746 if ( mGrayBandName == TRSTRING_NOT_SET )
01747 {
01748 break;
01749 }
01750 else
01751 {
01752 QgsDebugMsg( "PalettedSingleBandGray drawing type detected..." );
01753
01754 int myBandNo = 1;
01755 drawPalettedSingleBandGray( theQPainter, theRasterViewPort,
01756 theQgsMapToPixel, myBandNo );
01757
01758 break;
01759 }
01760
01761 case PalettedSingleBandPseudoColor:
01762
01763 if ( mGrayBandName == TRSTRING_NOT_SET )
01764 {
01765 break;
01766 }
01767 else
01768 {
01769
01770 int myBandNo = 1;
01771 drawPalettedSingleBandPseudoColor( theQPainter, theRasterViewPort,
01772 theQgsMapToPixel, myBandNo );
01773 break;
01774 }
01775
01776 case PalettedMultiBandColor:
01777 drawPalettedMultiBandColor( theQPainter, theRasterViewPort,
01778 theQgsMapToPixel, 1 );
01779 break;
01780
01781 case MultiBandSingleBandGray:
01782 QgsDebugMsg( "MultiBandSingleBandGray drawing type detected..." );
01783
01784 if ( mGrayBandName == TRSTRING_NOT_SET )
01785 {
01786 QgsDebugMsg( "MultiBandSingleBandGray Not Set detected..." + mGrayBandName );
01787 break;
01788 }
01789 else
01790 {
01791
01792
01793 drawMultiBandSingleBandGray( theQPainter, theRasterViewPort,
01794 theQgsMapToPixel, bandNumber( mGrayBandName ) );
01795 break;
01796 }
01797
01798 case MultiBandSingleBandPseudoColor:
01799
01800 if ( mGrayBandName == TRSTRING_NOT_SET )
01801 {
01802 break;
01803 }
01804 else
01805 {
01806
01807 drawMultiBandSingleBandPseudoColor( theQPainter, theRasterViewPort,
01808 theQgsMapToPixel, bandNumber( mGrayBandName ) );
01809 break;
01810 }
01811
01812
01813
01814 case MultiBandColor:
01815 if ( mRedBandName == TRSTRING_NOT_SET ||
01816 mGreenBandName == TRSTRING_NOT_SET ||
01817 mBlueBandName == TRSTRING_NOT_SET )
01818 {
01819 break;
01820 }
01821 else
01822 {
01823 drawMultiBandColor( theQPainter, theRasterViewPort,
01824 theQgsMapToPixel );
01825 }
01826 break;
01827
01828 default:
01829 break;
01830
01831 }
01832
01833 }
01834
01835 QString QgsRasterLayer::drawingStyleAsString() const
01836 {
01837 switch ( mDrawingStyle )
01838 {
01839 case SingleBandGray:
01840 return QString( "SingleBandGray" );
01841 break;
01842 case SingleBandPseudoColor:
01843 return QString( "SingleBandPseudoColor" );
01844 break;
01845 case PalettedColor:
01846 return QString( "PalettedColor" );
01847 break;
01848 case PalettedSingleBandGray:
01849 return QString( "PalettedSingleBandGray" );
01850 break;
01851 case PalettedSingleBandPseudoColor:
01852 return QString( "PalettedSingleBandPseudoColor" );
01853 break;
01854 case PalettedMultiBandColor:
01855 return QString( "PalettedMultiBandColor" );
01856 break;
01857 case MultiBandSingleBandGray:
01858 return QString( "MultiBandSingleBandGray" );
01859 break;
01860 case MultiBandSingleBandPseudoColor:
01861 return QString( "MultiBandSingleBandPseudoColor" );
01862 break;
01863 case MultiBandColor:
01864 return QString( "MultiBandColor" );
01865 break;
01866 default:
01867 break;
01868 }
01869
01870 return QString( "UndefinedDrawingStyle" );
01871
01872 }
01873
01878 bool QgsRasterLayer::hasCompatibleSymbology( const QgsMapLayer& theOther ) const
01879 {
01880
01881 if ( theOther.type() < 0 )
01882 {
01883 return false;
01884 }
01885 return false;
01886 }
01887
01892 bool QgsRasterLayer::hasStatistics( int theBandNo )
01893 {
01894 if ( theBandNo <= mRasterStatsList.size() && theBandNo > 0 )
01895 {
01896
01897 return mRasterStatsList[theBandNo - 1].statsGathered;
01898 }
01899 else
01900 {
01901 return false;
01902 }
01903 }
01904
01910 bool QgsRasterLayer::identify( const QgsPoint& thePoint, QMap<QString, QString>& theResults )
01911 {
01912 theResults.clear();
01913 if ( mProviderKey == "wms" )
01914 {
01915 return false;
01916 }
01917
01918 QgsDebugMsg( thePoint.toString() );
01919
01920 if ( !mProviderKey.isEmpty() )
01921 {
01922 QgsDebugMsg( "identify provider : " + mProviderKey ) ;
01923 return ( mDataProvider->identify( thePoint, theResults ) );
01924 }
01925
01926 if ( !mLayerExtent.contains( thePoint ) )
01927 {
01928
01929 for ( int i = 1; i <= GDALGetRasterCount( mGdalDataset ); i++ )
01930 {
01931 theResults[ generateBandName( i )] = tr( "out of extent" );
01932 }
01933 }
01934 else
01935 {
01936 double x = thePoint.x();
01937 double y = thePoint.y();
01938
01939
01940 double xres = ( mLayerExtent.xMaximum() - mLayerExtent.xMinimum() ) / mWidth;
01941 double yres = ( mLayerExtent.yMaximum() - mLayerExtent.yMinimum() ) / mHeight;
01942
01943
01944 int col = ( int ) floor(( x - mLayerExtent.xMinimum() ) / xres );
01945 int row = ( int ) floor(( mLayerExtent.yMaximum() - y ) / yres );
01946
01947 QgsDebugMsg( "row = " + QString::number( row ) + " col = " + QString::number( col ) );
01948
01949 for ( int i = 1; i <= GDALGetRasterCount( mGdalDataset ); i++ )
01950 {
01951 GDALRasterBandH gdalBand = GDALGetRasterBand( mGdalDataset, i );
01952 GDALDataType type = GDALGetRasterDataType( gdalBand );
01953 int size = GDALGetDataTypeSize( type ) / 8;
01954 void *data = CPLMalloc( size );
01955
01956 CPLErr err = GDALRasterIO( gdalBand, GF_Read, col, row, 1, 1,
01957 data, 1, 1, type, 0, 0 );
01958
01959 if ( err != CPLE_None )
01960 {
01961 QgsLogger::warning( "RasterIO error: " + QString::fromUtf8( CPLGetLastErrorMsg() ) );
01962 }
01963
01964 double value = readValue( data, type, 0 );
01965 #ifdef QGISDEBUG
01966 QgsLogger::debug( "value", value, 1, __FILE__, __FUNCTION__, __LINE__ );
01967 #endif
01968 QString v;
01969
01970 if ( mValidNoDataValue && ( fabs( value - mNoDataValue ) <= TINY_VALUE || value != value ) )
01971 {
01972 v = tr( "null (no data)" );
01973 }
01974 else
01975 {
01976 v.setNum( value );
01977 }
01978
01979 theResults[ generateBandName( i )] = v;
01980
01981 CPLFree( data );
01982 }
01983 }
01984
01985 return true;
01986 }
01987
01994 QString QgsRasterLayer::identifyAsText( const QgsPoint& thePoint )
01995 {
01996 if ( mProviderKey != "wms" )
01997 {
01998
01999 return QString();
02000 }
02001
02002 return mDataProvider->identifyAsText( thePoint );
02003 }
02004
02011 QString QgsRasterLayer::identifyAsHtml( const QgsPoint& thePoint )
02012 {
02013 if ( mProviderKey != "wms" )
02014 {
02015
02016 return QString();
02017 }
02018
02019 return mDataProvider->identifyAsHtml( thePoint );
02020 }
02021
02026 bool QgsRasterLayer::isEditable() const
02027 {
02028 return false;
02029 }
02030
02031 QString QgsRasterLayer::lastError()
02032 {
02033 return mError;
02034 }
02035
02036 QString QgsRasterLayer::lastErrorTitle()
02037 {
02038 return mErrorCaption;
02039 }
02040
02045 QPixmap QgsRasterLayer::legendAsPixmap()
02046 {
02047 return legendAsPixmap( false );
02048 }
02049
02054 QPixmap QgsRasterLayer::legendAsPixmap( bool theWithNameFlag )
02055 {
02056 QgsDebugMsg( "called (" + drawingStyleAsString() + ")" );
02057
02058 QPixmap myLegendQPixmap;
02059 QPainter myQPainter;
02060
02061
02062 if ( !mProviderKey.isEmpty() )
02063 {
02064 QgsDebugMsg( "provider Key (" + mProviderKey + ")" );
02065 myLegendQPixmap = QPixmap( 3, 1 );
02066 myQPainter.begin( &myLegendQPixmap );
02067
02068 myQPainter.setPen( QPen( QColor( 255, 0, 0 ), 0 ) );
02069 myQPainter.drawPoint( 0, 0 );
02070
02071 myQPainter.setPen( QPen( QColor( 0, 255, 0 ), 0 ) );
02072 myQPainter.drawPoint( 1, 0 );
02073
02074 myQPainter.setPen( QPen( QColor( 0, 0, 255 ), 0 ) );
02075 myQPainter.drawPoint( 2, 0 );
02076
02077 }
02078 else
02079 {
02080
02081
02082
02083
02084
02085 GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, 1 );
02086 QString myColorerpretation = GDALGetColorInterpretationName( GDALGetRasterColorInterpretation( myGdalBand ) );
02087
02088
02089
02090
02091
02092
02093 if ( mDrawingStyle == MultiBandSingleBandGray || mDrawingStyle == PalettedSingleBandGray || mDrawingStyle == SingleBandGray )
02094 {
02095
02096 myLegendQPixmap = QPixmap( 100, 1 );
02097 myQPainter.begin( &myLegendQPixmap );
02098 int myPos = 0;
02099 for ( double my = 0; my < 255; my += 2.55 )
02100 {
02101 if ( !mInvertColor )
02102 {
02103
02104 int myGray = static_cast < int >( my );
02105 myQPainter.setPen( QPen( QColor( myGray, myGray, myGray ), 0 ) );
02106 }
02107 else
02108 {
02109
02110 int myGray = 255 - static_cast < int >( my );
02111 myQPainter.setPen( QPen( QColor( myGray, myGray, myGray ), 0 ) );
02112 }
02113 myQPainter.drawPoint( myPos++, 0 );
02114 }
02115 }
02116 else if ( mDrawingStyle == MultiBandSingleBandPseudoColor ||
02117 mDrawingStyle == PalettedSingleBandPseudoColor || mDrawingStyle == SingleBandPseudoColor )
02118 {
02119
02120
02121 double myRangeSize = 90;
02122 double myBreakSize = myRangeSize / 3;
02123 double myClassBreakMin1 = 0;
02124 double myClassBreakMax1 = myClassBreakMin1 + myBreakSize;
02125 double myClassBreakMin2 = myClassBreakMax1;
02126 double myClassBreakMax2 = myClassBreakMin2 + myBreakSize;
02127 double myClassBreakMin3 = myClassBreakMax2;
02128
02129
02130
02131
02132 myLegendQPixmap = QPixmap( 100, 1 );
02133 myQPainter.begin( &myLegendQPixmap );
02134 int myPos = 0;
02135 for ( double my = 0; my < myRangeSize; my += myRangeSize / 100.0 )
02136 {
02137
02138 if ( !mInvertColor )
02139 {
02140
02141 if (( my >= myClassBreakMin1 ) && ( my < myClassBreakMax1 ) )
02142 {
02143 int myRed = 0;
02144 int myBlue = 255;
02145 int myGreen = static_cast < int >((( 255 / myRangeSize ) * ( my - myClassBreakMin1 ) ) * 3 );
02146
02147 if ( mColorShadingAlgorithm == FreakOutShader )
02148 {
02149 myRed = 255 - myGreen;
02150 }
02151 myQPainter.setPen( QPen( QColor( myRed, myGreen, myBlue ), 0 ) );
02152 }
02153
02154 else if (( my >= myClassBreakMin2 ) && ( my < myClassBreakMax2 ) )
02155 {
02156 int myRed = static_cast < int >((( 255 / myRangeSize ) * (( my - myClassBreakMin2 ) / 1 ) ) * 3 );
02157 int myBlue = static_cast < int >( 255 - ((( 255 / myRangeSize ) * (( my - myClassBreakMin2 ) / 1 ) ) * 3 ) );
02158 int myGreen = 255;
02159
02160 if ( mColorShadingAlgorithm == FreakOutShader )
02161 {
02162 myGreen = myBlue;
02163 }
02164 myQPainter.setPen( QPen( QColor( myRed, myGreen, myBlue ), 0 ) );
02165 }
02166
02167 else
02168 {
02169 int myRed = 255;
02170 int myBlue = 0;
02171 int myGreen = static_cast < int >( 255 - ((( 255 / myRangeSize ) * (( my - myClassBreakMin3 ) / 1 ) * 3 ) ) );
02172
02173 if ( mColorShadingAlgorithm == FreakOutShader )
02174 {
02175 myRed = myGreen;
02176 myGreen = 255 - myGreen;
02177 }
02178 myQPainter.setPen( QPen( QColor( myRed, myGreen, myBlue ), 0 ) );
02179 }
02180 }
02181 else
02182 {
02183
02184 if (( my >= myClassBreakMin1 ) && ( my < myClassBreakMax1 ) )
02185 {
02186 int myRed = 255;
02187 int myBlue = 0;
02188 int myGreen = static_cast < int >((( 255 / myRangeSize ) * (( my - myClassBreakMin1 ) / 1 ) * 3 ) );
02189
02190 if ( mColorShadingAlgorithm == FreakOutShader )
02191 {
02192 myRed = 255 - myGreen;
02193 }
02194 myQPainter.setPen( QPen( QColor( myRed, myGreen, myBlue ), 0 ) );
02195 }
02196
02197 else if (( my >= myClassBreakMin2 ) && ( my < myClassBreakMax2 ) )
02198 {
02199 int myRed = static_cast < int >( 255 - ((( 255 / myRangeSize ) * (( my - myClassBreakMin2 ) / 1 ) ) * 3 ) );
02200 int myBlue = static_cast < int >((( 255 / myRangeSize ) * (( my - myClassBreakMin2 ) / 1 ) ) * 3 );
02201 int myGreen = 255;
02202
02203 if ( mColorShadingAlgorithm == FreakOutShader )
02204 {
02205 myGreen = myBlue;
02206 }
02207 myQPainter.setPen( QPen( QColor( myRed, myGreen, myBlue ), 0 ) );
02208 }
02209
02210 else
02211 {
02212 int myRed = 0;
02213 int myBlue = 255;
02214 int myGreen = static_cast < int >( 255 - ((( 255 / myRangeSize ) * ( my - myClassBreakMin3 ) ) * 3 ) );
02215
02216 if ( mColorShadingAlgorithm == FreakOutShader )
02217 {
02218 myRed = 255 - myGreen;
02219 }
02220 myQPainter.setPen( QPen( QColor( myRed, myGreen, myBlue ), 0 ) );
02221 }
02222
02223 }
02224 myQPainter.drawPoint( myPos++, 0 );
02225 }
02226
02227 }
02228 else if ( mDrawingStyle == PalettedMultiBandColor || mDrawingStyle == MultiBandColor || mDrawingStyle == PalettedColor )
02229 {
02230
02231
02232
02233
02234 myLegendQPixmap = QPixmap( 3, 1 );
02235 myQPainter.begin( &myLegendQPixmap );
02236
02237 myQPainter.setPen( QPen( QColor( 224, 103, 103 ), 0 ) );
02238 myQPainter.drawPoint( 0, 0 );
02239
02240 myQPainter.setPen( QPen( QColor( 132, 224, 127 ), 0 ) );
02241 myQPainter.drawPoint( 1, 0 );
02242
02243 myQPainter.setPen( QPen( QColor( 127, 160, 224 ), 0 ) );
02244 myQPainter.drawPoint( 2, 0 );
02245 }
02246 }
02247
02248 myQPainter.end();
02249
02250
02251
02252 if ( theWithNameFlag )
02253 {
02254 QFont myQFont( "arial", 10, QFont::Normal );
02255 QFontMetrics myQFontMetrics( myQFont );
02256
02257 int myHeight = ( myQFontMetrics.height() + 10 > 35 ) ? myQFontMetrics.height() + 10 : 35;
02258
02259
02260 QMatrix myQWMatrix;
02261
02262
02263
02264
02265
02266 if ( myLegendQPixmap.width() == 3 )
02267 {
02268
02269 myQWMatrix.scale( 60, myHeight );
02270 }
02271 else
02272 {
02273
02274 myQWMatrix.scale( 1.8, myHeight );
02275 }
02276
02277 QPixmap myQPixmap2 = myLegendQPixmap.transformed( myQWMatrix );
02278 QPainter myQPainter( &myQPixmap2 );
02279
02280
02281 QString myThemePath = QgsApplication::activeThemePath();
02282 QPixmap myPyramidPixmap( myThemePath + "/mIconPyramid.png" );
02283 QPixmap myNoPyramidPixmap( myThemePath + "/mIconNoPyramid.png" );
02284
02285
02286
02287
02288 if ( mHasPyramids )
02289 {
02290 myQPainter.drawPixmap( 0, myHeight - myPyramidPixmap.height(), myPyramidPixmap );
02291 }
02292 else
02293 {
02294 myQPainter.drawPixmap( 0, myHeight - myNoPyramidPixmap.height(), myNoPyramidPixmap );
02295 }
02296
02297
02298
02299 if ( mDrawingStyle == MultiBandSingleBandGray || mDrawingStyle == PalettedSingleBandGray || mDrawingStyle == SingleBandGray )
02300 {
02301 myQPainter.setPen( Qt::white );
02302 }
02303 else
02304 {
02305 myQPainter.setPen( Qt::black );
02306 }
02307 myQPainter.setFont( myQFont );
02308 myQPainter.drawText( 25, myHeight - 10, name() );
02309
02310
02311
02312 myLegendQPixmap = myQPixmap2;
02313 myQPainter.end();
02314 }
02315
02316
02317 return myLegendQPixmap;
02318
02319 }
02320
02325 QPixmap QgsRasterLayer::legendAsPixmap( int theLabelCount )
02326 {
02327 QgsDebugMsg( "entered." );
02328 QFont myQFont( "arial", 10, QFont::Normal );
02329 QFontMetrics myQFontMetrics( myQFont );
02330
02331 int myFontHeight = ( myQFontMetrics.height() );
02332 const int myerLabelSpacing = 5;
02333 int myImageHeight = (( myFontHeight + ( myerLabelSpacing * 2 ) ) * theLabelCount );
02334
02335
02336
02337 const int myColorBarWidth = 10;
02338
02339
02340
02341 GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, 1 );
02342 QString myColorerpretation = GDALGetColorInterpretationName( GDALGetRasterColorInterpretation( myGdalBand ) );
02343 QPixmap myLegendQPixmap;
02344 QPainter myQPainter;
02345
02346
02347
02348 if ( mDrawingStyle == MultiBandSingleBandGray || mDrawingStyle == PalettedSingleBandGray || mDrawingStyle == SingleBandGray )
02349 {
02350
02351 myLegendQPixmap = QPixmap( 1, myImageHeight );
02352 const double myIncrement = static_cast<double>( myImageHeight ) / 255.0;
02353 myQPainter.begin( &myLegendQPixmap );
02354 int myPos = 0;
02355 for ( double my = 0; my < 255; my += myIncrement )
02356 {
02357 if ( !mInvertColor )
02358 {
02359
02360 int myGray = static_cast < int >( my );
02361 myQPainter.setPen( QPen( QColor( myGray, myGray, myGray ), 0 ) );
02362 }
02363 else
02364 {
02365
02366 int myGray = 255 - static_cast < int >( my );
02367 myQPainter.setPen( QPen( QColor( myGray, myGray, myGray ), 0 ) );
02368 }
02369 myQPainter.drawPoint( 0, myPos++ );
02370 }
02371 }
02372 else if ( mDrawingStyle == MultiBandSingleBandPseudoColor ||
02373 mDrawingStyle == PalettedSingleBandPseudoColor || mDrawingStyle == SingleBandPseudoColor )
02374 {
02375
02376
02377 double myRangeSize = 90;
02378 double myBreakSize = myRangeSize / 3;
02379 double myClassBreakMin1 = 0;
02380 double myClassBreakMax1 = myClassBreakMin1 + myBreakSize;
02381 double myClassBreakMin2 = myClassBreakMax1;
02382 double myClassBreakMax2 = myClassBreakMin2 + myBreakSize;
02383 double myClassBreakMin3 = myClassBreakMax2;
02384
02385
02386
02387
02388 myLegendQPixmap = QPixmap( 1, myImageHeight );
02389 const double myIncrement = myImageHeight / myRangeSize;
02390 myQPainter.begin( &myLegendQPixmap );
02391 int myPos = 0;
02392 for ( double my = 0; my < 255; my += myIncrement )
02393 for ( double my = 0; my < myRangeSize; my += myIncrement )
02394 {
02395
02396 if ( !mInvertColor )
02397 {
02398
02399 if (( my >= myClassBreakMin1 ) && ( my < myClassBreakMax1 ) )
02400 {
02401 int myRed = 0;
02402 int myBlue = 255;
02403 int myGreen = static_cast < int >((( 255 / myRangeSize ) * ( my - myClassBreakMin1 ) ) * 3 );
02404
02405 if ( mColorShadingAlgorithm == FreakOutShader )
02406 {
02407 myRed = 255 - myGreen;
02408 }
02409 myQPainter.setPen( QPen( QColor( myRed, myGreen, myBlue ), 0 ) );
02410 }
02411
02412 else if (( my >= myClassBreakMin2 ) && ( my < myClassBreakMax2 ) )
02413 {
02414 int myRed = static_cast < int >((( 255 / myRangeSize ) * (( my - myClassBreakMin2 ) / 1 ) ) * 3 );
02415 int myBlue = static_cast < int >( 255 - ((( 255 / myRangeSize ) * (( my - myClassBreakMin2 ) / 1 ) ) * 3 ) );
02416 int myGreen = 255;
02417
02418 if ( mColorShadingAlgorithm == FreakOutShader )
02419 {
02420 myGreen = myBlue;
02421 }
02422 myQPainter.setPen( QPen( QColor( myRed, myGreen, myBlue ), 0 ) );
02423 }
02424
02425 else
02426 {
02427 int myRed = 255;
02428 int myBlue = 0;
02429 int myGreen = static_cast < int >( 255 - ((( 255 / myRangeSize ) * (( my - myClassBreakMin3 ) / 1 ) * 3 ) ) );
02430
02431 if ( mColorShadingAlgorithm == FreakOutShader )
02432 {
02433 myRed = myGreen;
02434 myGreen = 255 - myGreen;
02435 }
02436 myQPainter.setPen( QPen( QColor( myRed, myGreen, myBlue ), 0 ) );
02437 }
02438 }
02439 else
02440 {
02441
02442 if (( my >= myClassBreakMin1 ) && ( my < myClassBreakMax1 ) )
02443 {
02444 int myRed = 255;
02445 int myBlue = 0;
02446 int myGreen = static_cast < int >((( 255 / myRangeSize ) * (( my - myClassBreakMin1 ) / 1 ) * 3 ) );
02447
02448 if ( mColorShadingAlgorithm == FreakOutShader )
02449 {
02450 myRed = 255 - myGreen;
02451 }
02452 myQPainter.setPen( QPen( QColor( myRed, myGreen, myBlue ), 0 ) );
02453 }
02454
02455 else if (( my >= myClassBreakMin2 ) && ( my < myClassBreakMax2 ) )
02456 {
02457 int myRed = static_cast < int >( 255 - ((( 255 / myRangeSize ) * (( my - myClassBreakMin2 ) / 1 ) ) * 3 ) );
02458 int myBlue = static_cast < int >((( 255 / myRangeSize ) * (( my - myClassBreakMin2 ) / 1 ) ) * 3 );
02459 int myGreen = 255;
02460
02461 if ( mColorShadingAlgorithm == FreakOutShader )
02462 {
02463 myGreen = myBlue;
02464 }
02465 myQPainter.setPen( QPen( QColor( myRed, myGreen, myBlue ), 0 ) );
02466 }
02467
02468 else
02469 {
02470 int myRed = 0;
02471 int myBlue = 255;
02472 int myGreen = static_cast < int >( 255 - ((( 255 / myRangeSize ) * ( my - myClassBreakMin3 ) ) * 3 ) );
02473
02474 if ( mColorShadingAlgorithm == FreakOutShader )
02475 {
02476 myRed = 255 - myGreen;
02477 }
02478 myQPainter.setPen( QPen( QColor( myRed, myGreen, myBlue ), 0 ) );
02479 }
02480
02481 }
02482 myQPainter.drawPoint( 0, myPos++ );
02483 }
02484
02485 }
02486 else if ( mDrawingStyle == PalettedMultiBandColor || mDrawingStyle == MultiBandColor )
02487 {
02488
02489
02490
02491
02492 myLegendQPixmap = QPixmap( 1, 3 );
02493 myQPainter.begin( &myLegendQPixmap );
02494
02495 myQPainter.setPen( QPen( QColor( 224, 103, 103 ), 0 ) );
02496 myQPainter.drawPoint( 0, 0 );
02497
02498 myQPainter.setPen( QPen( QColor( 132, 224, 127 ), 0 ) );
02499 myQPainter.drawPoint( 0, 1 );
02500
02501 myQPainter.setPen( QPen( QColor( 127, 160, 224 ), 0 ) );
02502 myQPainter.drawPoint( 0, 2 );
02503 }
02504
02505
02506 myQPainter.end();
02507
02508
02509
02510
02511 QMatrix myQWMatrix;
02512
02513
02514
02515
02516
02517 if ( myLegendQPixmap.height() == 3 )
02518 {
02519 myQWMatrix.scale( myColorBarWidth, 2 );
02520 }
02521 else
02522 {
02523 myQWMatrix.scale( myColorBarWidth, 2 );
02524 }
02525
02526 QPixmap myQPixmap2 = myLegendQPixmap.transformed( myQWMatrix );
02527 QPainter myQPainter2( &myQPixmap2 );
02528
02529
02530
02531 if ( mDrawingStyle == MultiBandSingleBandGray || mDrawingStyle == PalettedSingleBandGray || mDrawingStyle == SingleBandGray )
02532 {
02533 myQPainter2.setPen( Qt::white );
02534 }
02535 else
02536 {
02537 myQPainter2.setPen( Qt::black );
02538 }
02539 myQPainter2.setFont( myQFont );
02540 myQPainter2.drawText( 25, myImageHeight - 10, name() );
02541
02542
02543
02544 myLegendQPixmap = myQPixmap2;
02545 myQPainter2.end();
02546
02547
02548 return myLegendQPixmap;
02549
02550 }
02551
02556 double QgsRasterLayer::maximumValue( unsigned int theBand )
02557 {
02558 if ( 0 < theBand && theBand <= bandCount() )
02559 {
02560 return mContrastEnhancementList[theBand - 1].maximumValue();
02561 }
02562
02563 return 0.0;
02564 }
02565
02570 double QgsRasterLayer::maximumValue( QString theBand )
02571 {
02572 if ( theBand != tr( "Not Set" ) )
02573 {
02574 return maximumValue( bandNumber( theBand ) );
02575 }
02576
02577 return 0.0;
02578 }
02579
02580
02581 QString QgsRasterLayer::metadata()
02582 {
02583 QString myMetadata ;
02584 myMetadata += "<p class=\"glossy\">" + tr( "Driver:" ) + "</p>\n";
02585 myMetadata += "<p>";
02586 if ( mProviderKey.isEmpty() )
02587 {
02588 myMetadata += QString( GDALGetDescription( GDALGetDatasetDriver( mGdalDataset ) ) );
02589 myMetadata += "<br>";
02590 myMetadata += QString( GDALGetMetadataItem( GDALGetDatasetDriver( mGdalDataset ), GDAL_DMD_LONGNAME, NULL ) );
02591 }
02592 else
02593 {
02594 myMetadata += mDataProvider->description();
02595 }
02596 myMetadata += "</p>\n";
02597
02598 if ( !mProviderKey.isEmpty() )
02599 {
02600
02601 myMetadata += mDataProvider->metadata();
02602 }
02603 else
02604 {
02605
02606
02607
02608 myMetadata += "<p class=\"glossy\">";
02609 myMetadata += tr( "Dataset Description" );
02610 myMetadata += "</p>\n";
02611 myMetadata += "<p>";
02612 myMetadata += QFile::decodeName( GDALGetDescription( mGdalDataset ) );
02613 myMetadata += "</p>\n";
02614
02615
02616 char ** GDALmetadata = GDALGetMetadata( mGdalDataset, NULL );
02617
02618 if ( GDALmetadata )
02619 {
02620 QStringList metadata = cStringList2Q_( GDALmetadata );
02621 myMetadata += makeTableCells_( metadata );
02622 }
02623 else
02624 {
02625 QgsDebugMsg( "dataset has no metadata" );
02626 }
02627
02628 for ( int i = 1; i <= GDALGetRasterCount( mGdalDataset ); ++i )
02629 {
02630 myMetadata += "<p class=\"glossy\">" + tr( "Band %1" ).arg( i ) + "</p>\n";
02631 GDALRasterBandH gdalBand = GDALGetRasterBand( mGdalDataset, i );
02632 GDALmetadata = GDALGetMetadata( gdalBand, NULL );
02633
02634 if ( GDALmetadata )
02635 {
02636 QStringList metadata = cStringList2Q_( GDALmetadata );
02637 myMetadata += makeTableCells_( metadata );
02638 }
02639 else
02640 {
02641 QgsDebugMsg( "band " + QString::number( i ) + " has no metadata" );
02642 }
02643
02644 char ** GDALcategories = GDALGetRasterCategoryNames( gdalBand );
02645
02646 if ( GDALcategories )
02647 {
02648 QStringList categories = cStringList2Q_( GDALcategories );
02649 myMetadata += makeTableCells_( categories );
02650 }
02651 else
02652 {
02653 QgsDebugMsg( "band " + QString::number( i ) + " has no categories" );
02654 }
02655
02656 }
02657
02658
02659
02660 myMetadata += "<p class=\"glossy\">";
02661 myMetadata += tr( "Dimensions:" );
02662 myMetadata += "</p>\n";
02663 myMetadata += "<p>";
02664 myMetadata += tr( "X: %1 Y: %2 Bands: %3" )
02665 .arg( GDALGetRasterXSize( mGdalDataset ) )
02666 .arg( GDALGetRasterYSize( mGdalDataset ) )
02667 .arg( GDALGetRasterCount( mGdalDataset ) );
02668 myMetadata += "</p>\n";
02669
02670
02671 GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, 1 );
02672
02673 myMetadata += "<p class=\"glossy\">";
02674 myMetadata += tr( "No Data Value" );
02675 myMetadata += "</p>\n";
02676 myMetadata += "<p>";
02677 if ( mValidNoDataValue )
02678 {
02679 myMetadata += QString::number( mNoDataValue );
02680 }
02681 else
02682 {
02683 myMetadata += "*" + tr( "NoDataValue not set" ) + "*";
02684 }
02685 myMetadata += "</p>\n";
02686
02687 myMetadata += "</p>\n";
02688 myMetadata += "<p class=\"glossy\">";
02689 myMetadata += tr( "Data Type:" );
02690 myMetadata += "</p>\n";
02691 myMetadata += "<p>";
02692 switch ( GDALGetRasterDataType( myGdalBand ) )
02693 {
02694 case GDT_Byte:
02695 myMetadata += tr( "GDT_Byte - Eight bit unsigned integer" );
02696 break;
02697 case GDT_UInt16:
02698 myMetadata += tr( "GDT_UInt16 - Sixteen bit unsigned integer " );
02699 break;
02700 case GDT_Int16:
02701 myMetadata += tr( "GDT_Int16 - Sixteen bit signed integer " );
02702 break;
02703 case GDT_UInt32:
02704 myMetadata += tr( "GDT_UInt32 - Thirty two bit unsigned integer " );
02705 break;
02706 case GDT_Int32:
02707 myMetadata += tr( "GDT_Int32 - Thirty two bit signed integer " );
02708 break;
02709 case GDT_Float32:
02710 myMetadata += tr( "GDT_Float32 - Thirty two bit floating point " );
02711 break;
02712 case GDT_Float64:
02713 myMetadata += tr( "GDT_Float64 - Sixty four bit floating point " );
02714 break;
02715 case GDT_CInt16:
02716 myMetadata += tr( "GDT_CInt16 - Complex Int16 " );
02717 break;
02718 case GDT_CInt32:
02719 myMetadata += tr( "GDT_CInt32 - Complex Int32 " );
02720 break;
02721 case GDT_CFloat32:
02722 myMetadata += tr( "GDT_CFloat32 - Complex Float32 " );
02723 break;
02724 case GDT_CFloat64:
02725 myMetadata += tr( "GDT_CFloat64 - Complex Float64 " );
02726 break;
02727 default:
02728 myMetadata += tr( "Could not determine raster data type." );
02729 }
02730 myMetadata += "</p>\n";
02731
02732 myMetadata += "<p class=\"glossy\">";
02733 myMetadata += tr( "Pyramid overviews:" );
02734 myMetadata += "</p>\n";
02735 myMetadata += "<p>";
02736
02737 if ( GDALGetOverviewCount( myGdalBand ) > 0 )
02738 {
02739 int myOverviewInt;
02740 for ( myOverviewInt = 0;
02741 myOverviewInt < GDALGetOverviewCount( myGdalBand );
02742 myOverviewInt++ )
02743 {
02744 GDALRasterBandH myOverview;
02745 myOverview = GDALGetOverview( myGdalBand, myOverviewInt );
02746 myMetadata += "<p>X : " + QString::number( GDALGetRasterBandXSize( myOverview ) );
02747 myMetadata += ",Y " + QString::number( GDALGetRasterBandYSize( myOverview ) ) + "</p>";
02748 }
02749 }
02750 myMetadata += "</p>\n";
02751 }
02752
02753 myMetadata += "<p class=\"glossy\">";
02754 myMetadata += tr( "Layer Spatial Reference System: " );
02755 myMetadata += "</p>\n";
02756 myMetadata += "<p>";
02757 myMetadata += mCRS->toProj4();
02758 myMetadata += "</p>\n";
02759
02760
02761
02762 #if 0
02763 myMetadata += "<tr><td class=\"glossy\">";
02764 myMetadata += tr( "Project Spatial Reference System: " );
02765 myMetadata += "</p>\n";
02766 myMetadata += "<p>";
02767 myMetadata += mCoordinateTransform->destCRS().toProj4();
02768 myMetadata += "</p>\n";
02769 #endif
02770
02771 if ( mProviderKey.isEmpty() )
02772 {
02773 if ( GDALGetGeoTransform( mGdalDataset, mGeoTransform ) != CE_None )
02774 {
02775
02776
02777 mGeoTransform[5] = -1;
02778 }
02779 else
02780 {
02781 myMetadata += "<p class=\"glossy\">";
02782 myMetadata += tr( "Origin:" );
02783 myMetadata += "</p>\n";
02784 myMetadata += "<p>";
02785 myMetadata += QString::number( mGeoTransform[0] );
02786 myMetadata += ",";
02787 myMetadata += QString::number( mGeoTransform[3] );
02788 myMetadata += "</p>\n";
02789
02790 myMetadata += "<p class=\"glossy\">";
02791 myMetadata += tr( "Pixel Size:" );
02792 myMetadata += "</p>\n";
02793 myMetadata += "<p>";
02794 myMetadata += QString::number( mGeoTransform[1] );
02795 myMetadata += ",";
02796 myMetadata += QString::number( mGeoTransform[5] );
02797 myMetadata += "</p>\n";
02798 }
02799
02800
02801
02802
02803 int myBandCountInt = bandCount();
02804 for ( int myIteratorInt = 1; myIteratorInt <= myBandCountInt; ++myIteratorInt )
02805 {
02806 QgsDebugMsg( "Raster properties : checking if band " + QString::number( myIteratorInt ) + " has stats? " );
02807
02808 myMetadata += "<p class=\"glossy\">\n";
02809 myMetadata += tr( "Band" );
02810 myMetadata += "</p>\n";
02811 myMetadata += "<p>";
02812 myMetadata += bandName( myIteratorInt );
02813 myMetadata += "</p>\n";
02814
02815 myMetadata += "<p>";
02816 myMetadata += tr( "Band No" );
02817 myMetadata += "</p>\n";
02818 myMetadata += "<p>\n";
02819 myMetadata += QString::number( myIteratorInt );
02820 myMetadata += "</p>\n";
02821
02822
02823 if ( !hasStatistics( myIteratorInt ) )
02824 {
02825 QgsDebugMsg( ".....no" );
02826
02827 myMetadata += "<p>";
02828 myMetadata += tr( "No Stats" );
02829 myMetadata += "</p>\n";
02830 myMetadata += "<p>\n";
02831 myMetadata += tr( "No stats collected yet" );
02832 myMetadata += "</p>\n";
02833 }
02834 else
02835 {
02836 QgsDebugMsg( ".....yes" );
02837
02838 QgsRasterBandStats myRasterBandStats = bandStatistics( myIteratorInt );
02839
02840 myMetadata += "<p>";
02841 myMetadata += tr( "Min Val" );
02842 myMetadata += "</p>\n";
02843 myMetadata += "<p>\n";
02844 myMetadata += QString::number( myRasterBandStats.minimumValue, 'f', 10 );
02845 myMetadata += "</p>\n";
02846
02847
02848 myMetadata += "<p>";
02849 myMetadata += tr( "Max Val" );
02850 myMetadata += "</p>\n";
02851 myMetadata += "<p>\n";
02852 myMetadata += QString::number( myRasterBandStats.maximumValue, 'f', 10 );
02853 myMetadata += "</p>\n";
02854
02855
02856 myMetadata += "<p>";
02857 myMetadata += tr( "Range" );
02858 myMetadata += "</p>\n";
02859 myMetadata += "<p>\n";
02860 myMetadata += QString::number( myRasterBandStats.range, 'f', 10 );
02861 myMetadata += "</p>\n";
02862
02863
02864 myMetadata += "<p>";
02865 myMetadata += tr( "Mean" );
02866 myMetadata += "</p>\n";
02867 myMetadata += "<p>\n";
02868 myMetadata += QString::number( myRasterBandStats.mean, 'f', 10 );
02869 myMetadata += "</p>\n";
02870
02871
02872 myMetadata += "<p>";
02873 myMetadata += tr( "Sum of squares" );
02874 myMetadata += "</p>\n";
02875 myMetadata += "<p>\n";
02876 myMetadata += QString::number( myRasterBandStats.sumOfSquares, 'f', 10 );
02877 myMetadata += "</p>\n";
02878
02879
02880 myMetadata += "<p>";
02881 myMetadata += tr( "Standard Deviation" );
02882 myMetadata += "</p>\n";
02883 myMetadata += "<p>\n";
02884 myMetadata += QString::number( myRasterBandStats.stdDev, 'f', 10 );
02885 myMetadata += "</p>\n";
02886
02887
02888 myMetadata += "<p>";
02889 myMetadata += tr( "Sum of all cells" );
02890 myMetadata += "</p>\n";
02891 myMetadata += "<p>\n";
02892 myMetadata += QString::number( myRasterBandStats.sum, 'f', 10 );
02893 myMetadata += "</p>\n";
02894
02895
02896 myMetadata += "<p>";
02897 myMetadata += tr( "Cell Count" );
02898 myMetadata += "</p>\n";
02899 myMetadata += "<p>\n";
02900 myMetadata += QString::number( myRasterBandStats.elementCount );
02901 myMetadata += "</p>\n";
02902 }
02903 }
02904 }
02905
02906 QgsDebugMsg( myMetadata );
02907 return myMetadata;
02908 }
02909
02914 double QgsRasterLayer::minimumValue( unsigned int theBand )
02915 {
02916 if ( 0 < theBand && theBand <= bandCount() )
02917 {
02918 return mContrastEnhancementList[theBand - 1].minimumValue();
02919 }
02920
02921 return 0.0;
02922 }
02923
02928 double QgsRasterLayer::minimumValue( QString theBand )
02929 {
02930 return minimumValue( bandNumber( theBand ) );
02931 }
02932
02937 QPixmap QgsRasterLayer::paletteAsPixmap( int theBandNumber )
02938 {
02939
02940 QgsDebugMsg( "entered." );
02941
02942
02943
02944 if ( mProviderKey.isEmpty() && hasBand( "Palette" ) && theBandNumber > 0 )
02945 {
02946 QgsDebugMsg( "....found paletted image" );
02947 QgsColorRampShader myShader;
02948 QList<QgsColorRampShader::ColorRampItem> myColorRampItemList = myShader.colorRampItemList();
02949
02950 if ( readColorTable( 1, &myColorRampItemList ) )
02951 {
02952 QgsDebugMsg( "....got color ramp item list" );
02953 myShader.setColorRampItemList( myColorRampItemList );
02954 myShader.setColorRampType( QgsColorRampShader::DISCRETE );
02955
02956 int mySize = 100;
02957 QPixmap myPalettePixmap( mySize, mySize );
02958 QPainter myQPainter( &myPalettePixmap );
02959
02960 QImage myQImage = QImage( mySize, mySize, QImage::Format_RGB32 );
02961 myQImage.fill( 0 );
02962 myPalettePixmap.fill();
02963
02964 double myStep = (( double )myColorRampItemList.size() - 1 ) / ( double )( mySize * mySize );
02965 double myValue = 0.0;
02966 for ( int myRow = 0; myRow < mySize; myRow++ )
02967 {
02968 QRgb* myLineBuffer = ( QRgb* )myQImage.scanLine( myRow );
02969 for ( int myCol = 0; myCol < mySize; myCol++ )
02970 {
02971 myValue = myStep * ( double )( myCol + myRow * mySize );
02972 int c1, c2, c3;
02973 myShader.shade( myValue, &c1, &c2, &c3 );
02974 myLineBuffer[ myCol ] = qRgb( c1, c2, c3 );
02975 }
02976 }
02977
02978 myQPainter.drawImage( 0, 0, myQImage );
02979 return myPalettePixmap;
02980 }
02981 QPixmap myNullPixmap;
02982 return myNullPixmap;
02983 }
02984 else
02985 {
02986
02987 QPixmap myNullPixmap;
02988 return myNullPixmap;
02989 }
02990 }
02991
02992
02993
02994
02995
02996
02997
02998 void QgsRasterLayer::populateHistogram( int theBandNo, int theBinCount, bool theIgnoreOutOfRangeFlag, bool theHistogramEstimatedFlag )
02999 {
03000
03001 GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
03002 QgsRasterBandStats myRasterBandStats = bandStatistics( theBandNo );
03003
03004
03005
03006
03007
03008 if ( myRasterBandStats.histogramVector->size() != theBinCount ||
03009 theIgnoreOutOfRangeFlag != myRasterBandStats.isHistogramOutOfRange ||
03010 theHistogramEstimatedFlag != myRasterBandStats.isHistogramEstimated )
03011 {
03012 myRasterBandStats.histogramVector->clear();
03013 myRasterBandStats.isHistogramEstimated = theHistogramEstimatedFlag;
03014 myRasterBandStats.isHistogramOutOfRange = theIgnoreOutOfRangeFlag;
03015 int *myHistogramArray = new int[theBinCount];
03016
03017
03018
03019
03020
03021
03022
03023
03024
03025
03026
03027
03028
03029
03030 double myerval = ( myRasterBandStats.maximumValue - myRasterBandStats.minimumValue ) / theBinCount;
03031 GDALGetRasterHistogram( myGdalBand, myRasterBandStats.minimumValue - 0.1*myerval,
03032 myRasterBandStats.maximumValue + 0.1*myerval, theBinCount, myHistogramArray,
03033 theIgnoreOutOfRangeFlag, theHistogramEstimatedFlag, progressCallback,
03034 this );
03035
03036 for ( int myBin = 0; myBin < theBinCount; myBin++ )
03037 {
03038 myRasterBandStats.histogramVector->push_back( myHistogramArray[myBin] );
03039 QgsDebugMsg( "Added " + QString::number( myHistogramArray[myBin] ) + " to histogram vector" );
03040 }
03041
03042 }
03043 QgsDebugMsg( ">>>>> Histogram vector now contains " + QString::number( myRasterBandStats.histogramVector->size() ) +
03044 " elements" );
03045 }
03046
03047
03048 QString QgsRasterLayer::providerKey()
03049 {
03050 if ( mProviderKey.isEmpty() )
03051 {
03052 return QString();
03053 }
03054 else
03055 {
03056 return mProviderKey;
03057 }
03058 }
03059
03063 double QgsRasterLayer::rasterUnitsPerPixel()
03064 {
03065
03066
03067
03068
03069
03070
03071 return fabs( mGeoTransform[1] );
03072 }
03073
03079 bool QgsRasterLayer::readColorTable( int theBandNumber, QList<QgsColorRampShader::ColorRampItem>* theList )
03080 {
03081 QgsDebugMsg( "entered." );
03082
03083 if ( 0 >= theBandNumber || 0 == theList )
03084 {
03085 QgsDebugMsg( "Invalid parameter" );
03086 return false;
03087 }
03088
03089 GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNumber );
03090 GDALColorTableH myGdalColorTable = GDALGetRasterColorTable( myGdalBand );
03091
03092 if ( myGdalColorTable )
03093 {
03094 QgsDebugMsg( "Color table found" );
03095 int myEntryCount = GDALGetColorEntryCount( myGdalColorTable );
03096 GDALColorInterp myColorInterpretation = GDALGetRasterColorInterpretation( myGdalBand );
03097 QgsDebugMsg( "Color Interpretation: " + QString::number(( int )myColorInterpretation ) );
03098 GDALPaletteInterp myPaletteInterpretation = GDALGetPaletteInterpretation( myGdalColorTable );
03099 QgsDebugMsg( "Palette Interpretation: " + QString::number(( int )myPaletteInterpretation ) );
03100
03101 const GDALColorEntry* myColorEntry = 0;
03102 for ( int myIterator = 0; myIterator < myEntryCount; myIterator++ )
03103 {
03104 myColorEntry = GDALGetColorEntry( myGdalColorTable, myIterator );
03105
03106 if ( !myColorEntry )
03107 {
03108 continue;
03109 }
03110 else
03111 {
03112
03113 if ( myColorInterpretation == GCI_GrayIndex )
03114 {
03115 QgsColorRampShader::ColorRampItem myColorRampItem;
03116 myColorRampItem.label = "";
03117 myColorRampItem.value = ( double )myIterator;
03118 myColorRampItem.color = QColor::fromRgb( myColorEntry->c1, myColorEntry->c1, myColorEntry->c1, myColorEntry->c4 );
03119 theList->append( myColorRampItem );
03120 }
03121 else if ( myColorInterpretation == GCI_PaletteIndex )
03122 {
03123 QgsColorRampShader::ColorRampItem myColorRampItem;
03124 myColorRampItem.label = "";
03125 myColorRampItem.value = ( double )myIterator;
03126
03127 if ( myPaletteInterpretation == GPI_RGB )
03128 {
03129 myColorRampItem.color = QColor::fromRgb( myColorEntry->c1, myColorEntry->c2, myColorEntry->c3, myColorEntry->c4 );
03130 }
03131 else if ( myPaletteInterpretation == GPI_CMYK )
03132 {
03133 myColorRampItem.color = QColor::fromCmyk( myColorEntry->c1, myColorEntry->c2, myColorEntry->c3, myColorEntry->c4 );
03134 }
03135 else if ( myPaletteInterpretation == GPI_HLS )
03136 {
03137 myColorRampItem.color = QColor::fromHsv( myColorEntry->c1, myColorEntry->c3, myColorEntry->c2, myColorEntry->c4 );
03138 }
03139 else
03140 {
03141 myColorRampItem.color = QColor::fromRgb( myColorEntry->c1, myColorEntry->c1, myColorEntry->c1, myColorEntry->c4 );
03142 }
03143 theList->append( myColorRampItem );
03144 }
03145 else
03146 {
03147 QgsDebugMsg( "Color interpretation type not supported yet" );
03148 return false;
03149 }
03150 }
03151 }
03152 }
03153 else
03154 {
03155 QgsDebugMsg( "No color table found for band " + QString::number( theBandNumber ) );
03156 return false;
03157 }
03158
03159 QgsDebugMsg( "Color table loaded sucessfully" );
03160 return true;
03161 }
03162
03163 void QgsRasterLayer::resetNoDataValue()
03164 {
03165 mNoDataValue = std::numeric_limits<int>::max();
03166 mValidNoDataValue = false;
03167 if ( mGdalDataset != NULL && GDALGetRasterCount( mGdalDataset ) > 0 )
03168 {
03169 int myRequestValid;
03170 double myValue = GDALGetRasterNoDataValue(
03171 GDALGetRasterBand( mGdalDataset, 1 ), &myRequestValid );
03172
03173 if ( 0 != myRequestValid )
03174 {
03175 setNoDataValue( myValue );
03176 }
03177 else
03178 {
03179 setNoDataValue( -9999.0 );
03180 mValidNoDataValue = false;
03181 }
03182 }
03183 }
03184
03185
03186 void QgsRasterLayer::setBlueBandName( QString const & theBandName )
03187 {
03188 mBlueBandName = validateBandName( theBandName );
03189 }
03190
03194 void QgsRasterLayer::setDataProvider( QString const & provider,
03195 QStringList const & layers,
03196 QStringList const & styles,
03197 QString const & format,
03198 QString const & crs )
03199 {
03200
03201
03202
03203 mProviderKey = provider;
03204
03205
03206
03207 QgsProviderRegistry * pReg = QgsProviderRegistry::instance();
03208 QString ogrlib = pReg->library( provider );
03209
03210
03211
03212 #ifdef TESTPROVIDERLIB
03213 const char *cOgrLib = ( const char * ) ogrlib;
03214
03215
03216 void *handle = dlopen( cOgrLib, RTLD_LAZY | RTLD_GLOBAL );
03217 if ( !handle )
03218 {
03219 QgsLogger::warning( "Error in dlopen: " );
03220 }
03221 else
03222 {
03223 QgsDebugMsg( "dlopen suceeded" );
03224 dlclose( handle );
03225 }
03226
03227 #endif
03228
03229
03230 mLib = new QLibrary( ogrlib );
03231 QgsDebugMsg( "Library name is " + mLib->fileName() );
03232 bool loaded = mLib->load();
03233
03234 if ( loaded )
03235 {
03236 QgsDebugMsg( "Loaded data provider library" );
03237 QgsDebugMsg( "Attempting to resolve the classFactory function" );
03238 classFactoryFunction_t * classFactory = ( classFactoryFunction_t * ) cast_to_fptr( mLib->resolve( "classFactory" ) );
03239
03240 mValid = false;
03241
03242 if ( classFactory )
03243 {
03244 QgsDebugMsg( "Getting pointer to a mDataProvider object from the library" );
03245
03246
03247
03248
03249
03250
03251 mDataProvider = ( QgsRasterDataProvider* )( *classFactory )( &mDataSource );
03252
03253 if ( mDataProvider )
03254 {
03255 QgsDebugMsg( "Instantiated the data provider plugin" +
03256 QString( " with layer list of " ) + layers.join( ", " ) + " and style list of " + styles.join( ", " ) +
03257 " and format of " + format + " and CRS of " + crs );
03258 if ( mDataProvider->isValid() )
03259 {
03260 mValid = true;
03261
03262 mDataProvider->addLayers( layers, styles );
03263 mDataProvider->setImageEncoding( format );
03264 mDataProvider->setImageCrs( crs );
03265
03266
03267 QgsRectangle mbr = mDataProvider->extent();
03268
03269
03270 QString s = mbr.toString();
03271 QgsDebugMsg( "Extent of layer: " + s );
03272
03273 mLayerExtent.setXMaximum( mbr.xMaximum() );
03274 mLayerExtent.setXMinimum( mbr.xMinimum() );
03275 mLayerExtent.setYMaximum( mbr.yMaximum() );
03276 mLayerExtent.setYMinimum( mbr.yMinimum() );
03277
03278
03279 QgsDebugMsg( "mLayerName: " + name() );
03280
03281
03282 mDrawingStyle = MultiBandColor;
03283
03284
03285 if ( mProviderKey == "wms" )
03286 {
03287 *mCRS = QgsCoordinateReferenceSystem();
03288 mCRS->createFromOgcWmsCrs( crs );
03289 }
03290 else
03291 {
03292 *mCRS = QgsCoordinateReferenceSystem( mDataProvider->crs() );
03293 }
03294 }
03295 }
03296 else
03297 {
03298 QgsLogger::warning( "QgsRasterLayer::setDataProvider: Unable to instantiate the data provider plugin" );
03299 mValid = false;
03300 }
03301 }
03302 }
03303 else
03304 {
03305 mValid = false;
03306 QgsLogger::warning( "QgsRasterLayer::setDataProvider: Failed to load ../providers/libproviders.so" );
03307
03308 }
03309 QgsDebugMsg( "exiting." );
03310
03311 }
03312
03313 void QgsRasterLayer::setColorShadingAlgorithm( ColorShadingAlgorithm theShadingAlgorithm )
03314 {
03315 QgsDebugMsg( "called with [" + QString::number( theShadingAlgorithm ) + "]" );
03316 if ( mColorShadingAlgorithm != theShadingAlgorithm )
03317 {
03318 if ( 0 == mRasterShader )
03319 {
03320 mRasterShader = new QgsRasterShader();
03321 }
03322
03323 switch ( theShadingAlgorithm )
03324 {
03325 case PseudoColorShader:
03326 mRasterShader->setRasterShaderFunction( new QgsPseudoColorShader() );
03327 break;
03328 case FreakOutShader:
03329 mRasterShader->setRasterShaderFunction( new QgsFreakOutShader() );
03330 break;
03331 case ColorRampShader:
03332 mRasterShader->setRasterShaderFunction( new QgsColorRampShader() );
03333 break;
03334 case UserDefinedShader:
03335
03336 break;
03337 default:
03338 mRasterShader->setRasterShaderFunction( new QgsRasterShaderFunction() );
03339 break;
03340 }
03341
03342
03343 mColorShadingAlgorithm = theShadingAlgorithm;
03344 }
03345 QgsDebugMsg( "mColorShadingAlgorithm = " + QString::number( theShadingAlgorithm ) );
03346 }
03347
03348 void QgsRasterLayer::setColorShadingAlgorithm( QString theShaderAlgorithm )
03349 {
03350 QgsDebugMsg( "called with [" + theShaderAlgorithm + "]" );
03351
03352 if ( theShaderAlgorithm == "PseudoColorShader" )
03353 setColorShadingAlgorithm( PseudoColorShader );
03354 else if ( theShaderAlgorithm == "FreakOutShader" )
03355 setColorShadingAlgorithm( FreakOutShader );
03356 else if ( theShaderAlgorithm == "ColorRampShader" )
03357 setColorShadingAlgorithm( ColorRampShader );
03358 else if ( theShaderAlgorithm == "UserDefinedShader" )
03359 setColorShadingAlgorithm( UserDefinedShader );
03360 else
03361 setColorShadingAlgorithm( UndefinedShader );
03362 }
03363
03364 void QgsRasterLayer::setContrastEnhancementAlgorithm( QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm, bool theGenerateLookupTableFlag )
03365 {
03366 QList<QgsContrastEnhancement>::iterator myIterator = mContrastEnhancementList.begin();
03367 while ( myIterator != mContrastEnhancementList.end() )
03368 {
03369 ( *myIterator ).setContrastEnhancementAlgorithm( theAlgorithm, theGenerateLookupTableFlag );
03370 ++myIterator;
03371 }
03372 mContrastEnhancementAlgorithm = theAlgorithm;
03373 }
03374
03375 void QgsRasterLayer::setContrastEnhancementAlgorithm( QString theAlgorithm, bool theGenerateLookupTableFlag )
03376 {
03377 QgsDebugMsg( "called with [" + theAlgorithm + "] and flag=" + QString::number(( int )theGenerateLookupTableFlag ) );
03378
03379 if ( theAlgorithm == "NoEnhancement" )
03380 {
03381 setContrastEnhancementAlgorithm( QgsContrastEnhancement::NoEnhancement, theGenerateLookupTableFlag );
03382 }
03383 else if ( theAlgorithm == "StretchToMinimumMaximum" )
03384 {
03385 setContrastEnhancementAlgorithm( QgsContrastEnhancement::StretchToMinimumMaximum, theGenerateLookupTableFlag );
03386 }
03387 else if ( theAlgorithm == "StretchAndClipToMinimumMaximum" )
03388 {
03389 setContrastEnhancementAlgorithm( QgsContrastEnhancement::StretchAndClipToMinimumMaximum, theGenerateLookupTableFlag );
03390 }
03391 else if ( theAlgorithm == "ClipToMinimumMaximum" )
03392 {
03393 setContrastEnhancementAlgorithm( QgsContrastEnhancement::ClipToMinimumMaximum, theGenerateLookupTableFlag );
03394 }
03395 else if ( theAlgorithm == "UserDefined" )
03396 {
03397 setContrastEnhancementAlgorithm( QgsContrastEnhancement::UserDefinedEnhancement, theGenerateLookupTableFlag );
03398 }
03399 else
03400 {
03401 setContrastEnhancementAlgorithm( QgsContrastEnhancement::NoEnhancement, theGenerateLookupTableFlag );
03402 }
03403 }
03404
03405 void QgsRasterLayer::setContrastEnhancementFunction( QgsContrastEnhancementFunction* theFunction )
03406 {
03407 if ( theFunction )
03408 {
03409 QList<QgsContrastEnhancement>::iterator myIterator = mContrastEnhancementList.begin();
03410 while ( myIterator != mContrastEnhancementList.end() )
03411 {
03412 ( *myIterator ).setContrastEnhancementFunction( theFunction );
03413 ++myIterator;
03414 }
03415 }
03416 }
03417
03423 void QgsRasterLayer::setDrawingStyle( QString const & theDrawingStyleQString )
03424 {
03425 if ( theDrawingStyleQString == "SingleBandGray" )
03426 {
03427 mDrawingStyle = SingleBandGray;
03428 }
03429 else if ( theDrawingStyleQString == "SingleBandPseudoColor" )
03430 {
03431 mDrawingStyle = SingleBandPseudoColor;
03432 }
03433 else if ( theDrawingStyleQString == "PalettedColor" )
03434 {
03435 mDrawingStyle = PalettedColor;
03436 }
03437 else if ( theDrawingStyleQString == "PalettedSingleBandGray" )
03438 {
03439 mDrawingStyle = PalettedSingleBandGray;
03440 }
03441 else if ( theDrawingStyleQString == "PalettedSingleBandPseudoColor" )
03442 {
03443 mDrawingStyle = PalettedSingleBandPseudoColor;
03444 }
03445 else if ( theDrawingStyleQString == "PalettedMultiBandColor" )
03446 {
03447 mDrawingStyle = PalettedMultiBandColor;
03448 }
03449 else if ( theDrawingStyleQString == "MultiBandSingleBandGray" )
03450 {
03451 mDrawingStyle = MultiBandSingleBandGray;
03452 }
03453 else if ( theDrawingStyleQString == "MultiBandSingleBandPseudoColor" )
03454 {
03455 mDrawingStyle = MultiBandSingleBandPseudoColor;
03456 }
03457 else if ( theDrawingStyleQString == "MultiBandColor" )
03458 {
03459 mDrawingStyle = MultiBandColor;
03460 }
03461 else
03462 {
03463 mDrawingStyle = UndefinedDrawingStyle;
03464 }
03465 }
03466
03467 void QgsRasterLayer::setGrayBandName( QString const & theBandName )
03468 {
03469 mGrayBandName = validateBandName( theBandName );
03470 }
03471
03472 void QgsRasterLayer::setGreenBandName( QString const & theBandName )
03473 {
03474 mGreenBandName = validateBandName( theBandName );
03475 }
03476
03477 void QgsRasterLayer::setLayerOrder( QStringList const & layers )
03478 {
03479 QgsDebugMsg( "entered." );
03480
03481 if ( mDataProvider )
03482 {
03483 QgsDebugMsg( "About to mDataProvider->setLayerOrder(layers)." );
03484 mDataProvider->setLayerOrder( layers );
03485 }
03486
03487 }
03488
03489 void QgsRasterLayer::setMaximumValue( unsigned int theBand, double theValue, bool theGenerateLookupTableFlag )
03490 {
03491 if ( 0 < theBand && theBand <= bandCount() )
03492 {
03493 mContrastEnhancementList[theBand - 1].setMaximumValue( theValue, theGenerateLookupTableFlag );
03494 }
03495 }
03496
03497 void QgsRasterLayer::setMaximumValue( QString theBand, double theValue, bool theGenerateLookupTableFlag )
03498 {
03499 if ( theBand != tr( "Not Set" ) )
03500 {
03501 setMaximumValue( bandNumber( theBand ), theValue, theGenerateLookupTableFlag );
03502 }
03503 }
03504
03505 void QgsRasterLayer::setMinimumMaximumUsingLastExtent()
03506 {
03507 double myMinMax[2];
03508 if ( rasterType() == QgsRasterLayer::GrayOrUndefined || drawingStyle() == QgsRasterLayer::SingleBandGray || drawingStyle() == QgsRasterLayer::MultiBandSingleBandGray )
03509 {
03510 computeMinimumMaximumFromLastExtent( grayBandName(), myMinMax );
03511 setMinimumValue( grayBandName(), myMinMax[0] );
03512 setMaximumValue( grayBandName(), myMinMax[1] );
03513
03514 setUserDefinedGrayMinimumMaximum( true );
03515 }
03516 else if ( rasterType() == QgsRasterLayer::Multiband )
03517 {
03518 computeMinimumMaximumFromLastExtent( redBandName(), myMinMax );
03519 setMinimumValue( redBandName(), myMinMax[0], false );
03520 setMaximumValue( redBandName(), myMinMax[1], false );
03521
03522 computeMinimumMaximumFromLastExtent( greenBandName(), myMinMax );
03523 setMinimumValue( greenBandName(), myMinMax[0], false );
03524 setMaximumValue( greenBandName(), myMinMax[1], false );
03525
03526 computeMinimumMaximumFromLastExtent( blueBandName(), myMinMax );
03527 setMinimumValue( blueBandName(), myMinMax[0], false );
03528 setMaximumValue( blueBandName(), myMinMax[1], false );
03529
03530 setUserDefinedRGBMinimumMaximum( true );
03531 }
03532 }
03533
03534 void QgsRasterLayer::setMinimumValue( unsigned int theBand, double theValue, bool theGenerateLookupTableFlag )
03535 {
03536 if ( 0 < theBand && theBand <= bandCount() )
03537 {
03538 mContrastEnhancementList[theBand - 1].setMinimumValue( theValue, theGenerateLookupTableFlag );
03539 }
03540 }
03541
03542 void QgsRasterLayer::setMinimumValue( QString theBand, double theValue, bool theGenerateLookupTableFlag )
03543 {
03544 if ( theBand != tr( "Not Set" ) )
03545 {
03546 setMinimumValue( bandNumber( theBand ), theValue, theGenerateLookupTableFlag );
03547 }
03548
03549 }
03550
03551 void QgsRasterLayer::setNoDataValue( double theNoDataValue )
03552 {
03553 if ( theNoDataValue != mNoDataValue )
03554 {
03555 mNoDataValue = theNoDataValue;
03556 mValidNoDataValue = true;
03557
03558 QList<QgsRasterBandStats>::iterator myIterator = mRasterStatsList.begin();
03559 while ( myIterator != mRasterStatsList.end() )
03560 {
03561 ( *myIterator ).statsGathered = false;
03562 ++myIterator;
03563 }
03564 }
03565 }
03566
03567 void QgsRasterLayer::setRasterShaderFunction( QgsRasterShaderFunction* theFunction )
03568 {
03569 if ( theFunction )
03570 {
03571 mRasterShader->setRasterShaderFunction( theFunction );
03572 mColorShadingAlgorithm = QgsRasterLayer::UserDefinedShader;
03573 }
03574 else
03575 {
03576
03577 mRasterShader->setRasterShaderFunction( new QgsRasterShaderFunction() );
03578 mColorShadingAlgorithm = QgsRasterLayer::UndefinedShader;
03579 }
03580 }
03581
03582 void QgsRasterLayer::setRedBandName( QString const & theBandName )
03583 {
03584 QgsDebugMsg( "setRedBandName : " + theBandName );
03585 mRedBandName = validateBandName( theBandName );
03586 }
03587
03588 void QgsRasterLayer::setSubLayerVisibility( QString const & name, bool vis )
03589 {
03590
03591 if ( mDataProvider )
03592 {
03593 QgsDebugMsg( "About to mDataProvider->setSubLayerVisibility(name, vis)." );
03594 mDataProvider->setSubLayerVisibility( name, vis );
03595 }
03596
03597 }
03598
03599 void QgsRasterLayer::setTransparentBandName( QString const & theBandName )
03600 {
03601 mTransparencyBandName = validateBandName( theBandName );
03602 }
03603
03604 void QgsRasterLayer::showProgress( int theValue )
03605 {
03606 emit progressUpdate( theValue );
03607 }
03608
03609
03610 void QgsRasterLayer::showStatusMessage( QString const & theMessage )
03611 {
03612
03613
03614
03615
03616 emit statusChanged( theMessage );
03617 }
03618
03619 QStringList QgsRasterLayer::subLayers( GDALDatasetH dataset )
03620 {
03621 QStringList subLayers;
03622
03623 char **metadata = GDALGetMetadata( dataset, "SUBDATASETS" );
03624 if ( metadata )
03625 {
03626 for ( int i = 0; metadata[i] != NULL; i++ )
03627 {
03628 QString layer = QString::fromUtf8( metadata[i] );
03629
03630 int pos = layer.indexOf( "_NAME=" );
03631 if ( pos >= 0 )
03632 {
03633 subLayers << layer.mid( pos + 6 );
03634 }
03635 }
03636 }
03637
03638 QgsDebugMsg( "sublayers:\n " + subLayers.join( "\n " ) );
03639
03640 return subLayers;
03641 }
03642
03643 QStringList QgsRasterLayer::subLayers() const
03644 {
03645 if ( mDataProvider )
03646 {
03647 return mDataProvider->subLayers();
03648 }
03649 else
03650 {
03651 return subLayers( mGdalDataset );
03652 }
03653 }
03654
03655 void QgsRasterLayer::thumbnailAsPixmap( QPixmap * theQPixmap )
03656 {
03657
03658 if ( 0 == theQPixmap ) { return; }
03659
03660 theQPixmap->fill();
03661
03662
03663 if ( mProviderKey.isEmpty() )
03664 {
03665 QgsRasterViewPort *myRasterViewPort = new QgsRasterViewPort();
03666 myRasterViewPort->rectXOffset = 0;
03667 myRasterViewPort->rectYOffset = 0;
03668 myRasterViewPort->clippedXMin = 0;
03669 myRasterViewPort->clippedXMax = mWidth;
03670 myRasterViewPort->clippedYMin = mHeight;
03671 myRasterViewPort->clippedYMax = 0;
03672 myRasterViewPort->clippedWidth = mWidth;
03673 myRasterViewPort->clippedHeight = mHeight;
03674 myRasterViewPort->topLeftPoint = QgsPoint( 0, 0 );
03675 myRasterViewPort->bottomRightPoint = QgsPoint( theQPixmap->width(), theQPixmap->height() );
03676 myRasterViewPort->drawableAreaXDim = theQPixmap->width();
03677 myRasterViewPort->drawableAreaYDim = theQPixmap->height();
03678
03679 QPainter * myQPainter = new QPainter( theQPixmap );
03680 draw( myQPainter, myRasterViewPort );
03681 delete myRasterViewPort;
03682 myQPainter->end();
03683 delete myQPainter;
03684 }
03685
03686 }
03687
03688 void QgsRasterLayer::thumbnailAsImage( QImage * thepImage )
03689 {
03690
03691 if ( 0 == thepImage ) { return; }
03692
03693 thepImage->fill( Qt::white );
03694
03695
03696 if ( mProviderKey.isEmpty() )
03697 {
03698 QgsRasterViewPort *myRasterViewPort = new QgsRasterViewPort();
03699 myRasterViewPort->rectXOffset = 0;
03700 myRasterViewPort->rectYOffset = 0;
03701 myRasterViewPort->clippedXMin = 0;
03702 myRasterViewPort->clippedXMax = mWidth;
03703 myRasterViewPort->clippedYMin = mHeight;
03704 myRasterViewPort->clippedYMax = 0;
03705 myRasterViewPort->clippedWidth = mWidth;
03706 myRasterViewPort->clippedHeight = mHeight;
03707 myRasterViewPort->topLeftPoint = QgsPoint( 0, 0 );
03708 myRasterViewPort->bottomRightPoint = QgsPoint( thepImage->width(), thepImage->height() );
03709 myRasterViewPort->drawableAreaXDim = thepImage->width();
03710 myRasterViewPort->drawableAreaYDim = thepImage->height();
03711
03712 QPainter * myQPainter = new QPainter( thepImage );
03713 draw( myQPainter, myRasterViewPort );
03714 delete myRasterViewPort;
03715 myQPainter->end();
03716 delete myQPainter;
03717 }
03718
03719 }
03720
03721 void QgsRasterLayer::triggerRepaint()
03722 {
03723 emit repaintRequested();
03724 }
03725
03726 void QgsRasterLayer::updateProgress( int theProgress, int theMax )
03727 {
03728
03729 emit drawingProgress( theProgress, theMax );
03730 }
03731
03732
03733
03734
03736
03737
03738
03740
03741
03742
03743
03744
03745 bool QgsRasterLayer::readSymbology( const QDomNode& layer_node, QString& errorMessage )
03746 {
03747 QDomNode mnl = layer_node.namedItem( "rasterproperties" );
03748 QDomNode snode = mnl.namedItem( "mDrawingStyle" );
03749 QDomElement myElement = snode.toElement();
03750 setDrawingStyle( myElement.text() );
03751
03752 snode = mnl.namedItem( "mColorShadingAlgorithm" );
03753 myElement = snode.toElement();
03754 setColorShadingAlgorithm( myElement.text() );
03755
03756 snode = mnl.namedItem( "mInvertColor" );
03757 myElement = snode.toElement();
03758 QVariant myVariant = ( QVariant ) myElement.attribute( "boolean" );
03759 setInvertHistogram( myVariant.toBool() );
03760
03761 snode = mnl.namedItem( "mRedBandName" );
03762 myElement = snode.toElement();
03763 setRedBandName( myElement.text() );
03764
03765 snode = mnl.namedItem( "mGreenBandName" );
03766 myElement = snode.toElement();
03767 setGreenBandName( myElement.text() );
03768
03769 snode = mnl.namedItem( "mBlueBandName" );
03770 myElement = snode.toElement();
03771 setBlueBandName( myElement.text() );
03772
03773 snode = mnl.namedItem( "mGrayBandName" );
03774 myElement = snode.toElement();
03775 QgsDebugMsg( QString( " Setting gray band to : " ) + myElement.text() );
03776 setGrayBandName( myElement.text() );
03777
03778 snode = mnl.namedItem( "mStandardDeviations" );
03779 myElement = snode.toElement();
03780 setStandardDeviations( myElement.text().toDouble() );
03781
03782 snode = mnl.namedItem( "mUserDefinedRGBMinimumMaximum" );
03783 myElement = snode.toElement();
03784 myVariant = ( QVariant ) myElement.attribute( "boolean" );
03785 setUserDefinedRGBMinimumMaximum( myVariant.toBool() );
03786
03787 snode = mnl.namedItem( "mRGBMinimumMaximumEstimated" );
03788 myElement = snode.toElement();
03789 myVariant = ( QVariant ) myElement.attribute( "boolean" );
03790 setRGBMinimumMaximumEstimated( myVariant.toBool() );
03791
03792 snode = mnl.namedItem( "mUserDefinedGrayMinimumMaximum" );
03793 myElement = snode.toElement();
03794 myVariant = ( QVariant ) myElement.attribute( "boolean" );
03795 setUserDefinedGrayMinimumMaximum( myVariant.toBool() );
03796
03797 snode = mnl.namedItem( "mGrayMinimumMaximumEstimated" );
03798 myElement = snode.toElement();
03799 myVariant = ( QVariant ) myElement.attribute( "boolean" );
03800 setGrayMinimumMaximumEstimated( myVariant.toBool() );
03801
03802 snode = mnl.namedItem( "mContrastEnhancementAlgorithm" );
03803 myElement = snode.toElement();
03804 setContrastEnhancementAlgorithm( myElement.text(), false );
03805
03806 QDomNode contrastEnhancementMinMaxValues = mnl.namedItem( "contrastEnhancementMinMaxValues" );
03807 QDomNodeList minMaxValueList = contrastEnhancementMinMaxValues.toElement().elementsByTagName( "minMaxEntry" );
03808 for ( int i = 0; i < minMaxValueList.size(); ++i )
03809 {
03810 QDomNode minMaxEntry = minMaxValueList.at( i ).toElement();
03811 if ( minMaxEntry.isNull() )
03812 {
03813 continue;
03814 }
03815 QDomNode minEntry = minMaxEntry.namedItem( "min" );
03816 QDomNode maxEntry = minMaxEntry.namedItem( "max" );
03817
03818 setMinimumValue( i + 1, minEntry.toElement().text().toDouble(), false );
03819 setMaximumValue( i + 1, maxEntry.toElement().text().toDouble(), false );
03820 }
03821
03822 QgsDebugMsg( "ReadXml: gray band name " + mGrayBandName );
03823 QgsDebugMsg( "ReadXml: red band name " + mRedBandName );
03824 QgsDebugMsg( "ReadXml: green band name " + mGreenBandName );
03825 QgsDebugMsg( "Drawing style " + drawingStyleAsString() );
03826
03827
03828
03829
03830 snode = mnl.namedItem( "mNoDataValue" );
03831 myElement = snode.toElement();
03832 setNoDataValue( myElement.text().toDouble() );
03833 if ( myElement.attribute( "mValidNoDataValue", "false" ).compare( "true" ) )
03834 {
03835
03836 mValidNoDataValue = false;
03837 }
03838
03839 QDomNode singleValuePixelListNode = mnl.namedItem( "singleValuePixelList" );
03840 if ( !singleValuePixelListNode.isNull() )
03841 {
03842 QList<QgsRasterTransparency::TransparentSingleValuePixel> newSingleValuePixelList;
03843
03844
03845 QDomNodeList singleValuePixelList = singleValuePixelListNode.toElement().elementsByTagName( "pixelListEntry" );
03846 for ( int i = 0; i < singleValuePixelList.size(); ++i )
03847 {
03848 QgsRasterTransparency::TransparentSingleValuePixel myNewItem;
03849 QDomElement singleValuePixelListElement = singleValuePixelList.at( i ).toElement();
03850 if ( singleValuePixelListElement.isNull() )
03851 {
03852 continue;
03853 }
03854
03855 myNewItem.pixelValue = singleValuePixelListElement.attribute( "pixelValue" ).toDouble();
03856 myNewItem.percentTransparent = singleValuePixelListElement.attribute( "percentTransparent" ).toDouble();
03857
03858 newSingleValuePixelList.push_back( myNewItem );
03859 }
03860 mRasterTransparency.setTransparentSingleValuePixelList( newSingleValuePixelList );
03861 }
03862
03863 QDomNode threeValuePixelListNode = mnl.namedItem( "threeValuePixelList" );
03864 if ( !threeValuePixelListNode.isNull() )
03865 {
03866 QList<QgsRasterTransparency::TransparentThreeValuePixel> newThreeValuePixelList;
03867
03868
03869 QDomNodeList threeValuePixelList = threeValuePixelListNode.toElement().elementsByTagName( "pixelListEntry" );
03870 for ( int i = 0; i < threeValuePixelList.size(); ++i )
03871 {
03872 QgsRasterTransparency::TransparentThreeValuePixel myNewItem;
03873 QDomElement threeValuePixelListElement = threeValuePixelList.at( i ).toElement();
03874 if ( threeValuePixelListElement.isNull() )
03875 {
03876 continue;
03877 }
03878
03879 myNewItem.red = threeValuePixelListElement.attribute( "red" ).toDouble();
03880 myNewItem.green = threeValuePixelListElement.attribute( "green" ).toDouble();
03881 myNewItem.blue = threeValuePixelListElement.attribute( "blue" ).toDouble();
03882 myNewItem.percentTransparent = threeValuePixelListElement.attribute( "percentTransparent" ).toDouble();
03883
03884 newThreeValuePixelList.push_back( myNewItem );
03885 }
03886 mRasterTransparency.setTransparentThreeValuePixelList( newThreeValuePixelList );
03887 }
03888
03889
03890
03891
03892
03893 QDomNode customColorRampNode = mnl.namedItem( "customColorRamp" );
03894 if ( !customColorRampNode.isNull() )
03895 {
03896 QgsColorRampShader* myColorRampShader = ( QgsColorRampShader* ) mRasterShader->rasterShaderFunction();
03897
03898
03899 QDomNode customColorRampTypeNode = customColorRampNode.namedItem( "customColorRampType" );
03900 QDomNode colorRampTypeNode = customColorRampNode.namedItem( "colorRampType" );
03901 QString myRampType = "";
03902 if ( "" == customColorRampTypeNode.toElement().text() )
03903 {
03904 myRampType = colorRampTypeNode.toElement().text();
03905 }
03906 else
03907 {
03908 myRampType = customColorRampTypeNode.toElement().text();
03909 }
03910 myColorRampShader->setColorRampType( myRampType );
03911
03912
03913
03914 QList<QgsColorRampShader::ColorRampItem> myColorRampItemList;
03915 QDomNodeList colorRampEntryList = customColorRampNode.toElement().elementsByTagName( "colorRampEntry" );
03916 for ( int i = 0; i < colorRampEntryList.size(); ++i )
03917 {
03918 QgsColorRampShader::ColorRampItem myNewItem;
03919 QDomElement colorRampEntryElement = colorRampEntryList.at( i ).toElement();
03920 if ( colorRampEntryElement.isNull() )
03921 {
03922 continue;
03923 }
03924
03925 myNewItem.color = QColor( colorRampEntryElement.attribute( "red" ).toInt(), colorRampEntryElement.attribute( "green" ).toInt(), colorRampEntryElement.attribute( "blue" ).toInt() );
03926 myNewItem.label = colorRampEntryElement.attribute( "label" );
03927 myNewItem.value = colorRampEntryElement.attribute( "value" ).toDouble();
03928
03929 myColorRampItemList.push_back( myNewItem );
03930 }
03931 myColorRampShader->setColorRampItemList( myColorRampItemList );
03932 }
03933 return true;
03934 }
03935
03960 bool QgsRasterLayer::readXml( QDomNode & layer_node )
03961 {
03963
03964
03965 QDomNode pkeyNode = layer_node.namedItem( "provider" );
03966
03967 if ( pkeyNode.isNull() )
03968 {
03969 mProviderKey = "";
03970 }
03971 else
03972 {
03973 QDomElement pkeyElt = pkeyNode.toElement();
03974 mProviderKey = pkeyElt.text();
03975 }
03976
03977
03978
03979 if ( !mProviderKey.isEmpty() )
03980 {
03981
03982
03983
03984
03985 QDomNode rpNode = layer_node.namedItem( "rasterproperties" );
03986
03987
03988 QStringList layers;
03989 QStringList styles;
03990 QDomElement layerElement = rpNode.firstChildElement( "wmsSublayer" );
03991 while ( !layerElement.isNull() )
03992 {
03993
03994
03995
03996 layers += layerElement.namedItem( "name" ).toElement().text();
03997
03998
03999 styles += layerElement.namedItem( "style" ).toElement().text();
04000
04001 layerElement = layerElement.nextSiblingElement( "wmsSublayer" );
04002 }
04003
04004
04005 QString format = rpNode.namedItem( "wmsFormat" ).toElement().text();
04006
04007
04008 QString crs = srs().authid();
04009
04010 setDataProvider( mProviderKey, layers, styles, format, crs );
04011 }
04012 else
04013 {
04014
04015
04016 if ( !readFile( source() ) )
04017
04018 {
04019 QgsLogger::warning( QString( __FILE__ ) + ":" + QString( __LINE__ ) +
04020 " unable to read from raster file " + source() );
04021 return false;
04022 }
04023
04024 }
04025
04026 QString theError;
04027 return readSymbology( layer_node, theError );
04028
04029
04030 }
04031
04032
04033
04034
04035
04036
04037
04038
04039 bool QgsRasterLayer::writeSymbology( QDomNode & layer_node, QDomDocument & document, QString& errorMessage ) const
04040 {
04041
04042 QDomElement rasterPropertiesElement = document.createElement( "rasterproperties" );
04043 layer_node.appendChild( rasterPropertiesElement );
04044
04045 if ( !mProviderKey.isEmpty() )
04046 {
04047 QStringList sl = subLayers();
04048 QStringList sls = mDataProvider->subLayerStyles();
04049
04050 QStringList::const_iterator layerStyle = sls.begin();
04051
04052
04053 for ( QStringList::const_iterator layerName = sl.begin();
04054 layerName != sl.end();
04055 ++layerName )
04056 {
04057
04058 QgsDebugMsg( QString( "<rasterproperties><wmsSublayer> %1" ).arg( layerName->toLocal8Bit().data() ) );
04059
04060 QDomElement sublayerElement = document.createElement( "wmsSublayer" );
04061
04062
04063
04064
04065 QDomElement sublayerNameElement = document.createElement( "name" );
04066 QDomText sublayerNameText = document.createTextNode( *layerName );
04067 sublayerNameElement.appendChild( sublayerNameText );
04068 sublayerElement.appendChild( sublayerNameElement );
04069
04070
04071 QDomElement sublayerStyleElement = document.createElement( "style" );
04072 QDomText sublayerStyleText = document.createTextNode( *layerStyle );
04073 sublayerStyleElement.appendChild( sublayerStyleText );
04074 sublayerElement.appendChild( sublayerStyleElement );
04075
04076 rasterPropertiesElement.appendChild( sublayerElement );
04077
04078
04079 ++layerStyle;
04080 }
04081
04082
04083 QDomElement formatElement = document.createElement( "wmsFormat" );
04084 QDomText formatText =
04085 document.createTextNode( mDataProvider->imageEncoding() );
04086 formatElement.appendChild( formatText );
04087 rasterPropertiesElement.appendChild( formatElement );
04088
04089 }
04090
04091
04092 QDomElement drawStyleElement = document.createElement( "mDrawingStyle" );
04093 QDomText drawStyleText = document.createTextNode( drawingStyleAsString() );
04094
04095 drawStyleElement.appendChild( drawStyleText );
04096
04097 rasterPropertiesElement.appendChild( drawStyleElement );
04098
04099
04100 QDomElement colorShadingAlgorithmElement = document.createElement( "mColorShadingAlgorithm" );
04101 QDomText colorShadingAlgorithmText = document.createTextNode( colorShadingAlgorithmAsString() );
04102
04103 colorShadingAlgorithmElement.appendChild( colorShadingAlgorithmText );
04104
04105 rasterPropertiesElement.appendChild( colorShadingAlgorithmElement );
04106
04107
04108 QDomElement mInvertColorElement = document.createElement( "mInvertColor" );
04109
04110 if ( invertHistogram() )
04111 {
04112 mInvertColorElement.setAttribute( "boolean", "true" );
04113 }
04114 else
04115 {
04116 mInvertColorElement.setAttribute( "boolean", "false" );
04117 }
04118
04119 rasterPropertiesElement.appendChild( mInvertColorElement );
04120
04121
04122
04123 QDomElement mRedBandNameElement = document.createElement( "mRedBandName" );
04124 QString writtenRedBandName = redBandName();
04125 if ( writtenRedBandName == TRSTRING_NOT_SET )
04126 {
04127
04128 writtenRedBandName = QSTRING_NOT_SET;
04129 }
04130 QDomText mRedBandNameText = document.createTextNode( writtenRedBandName );
04131
04132 mRedBandNameElement.appendChild( mRedBandNameText );
04133
04134 rasterPropertiesElement.appendChild( mRedBandNameElement );
04135
04136
04137
04138 QDomElement mGreenBandNameElement = document.createElement( "mGreenBandName" );
04139 QString writtenGreenBandName = greenBandName();
04140 if ( writtenGreenBandName == TRSTRING_NOT_SET )
04141 {
04142
04143 writtenGreenBandName = QSTRING_NOT_SET;
04144 }
04145 QDomText mGreenBandNameText = document.createTextNode( writtenGreenBandName );
04146
04147 mGreenBandNameElement.appendChild( mGreenBandNameText );
04148
04149 rasterPropertiesElement.appendChild( mGreenBandNameElement );
04150
04151
04152
04153 QDomElement mBlueBandNameElement = document.createElement( "mBlueBandName" );
04154 QString writtenBlueBandName = blueBandName();
04155 if ( writtenBlueBandName == TRSTRING_NOT_SET )
04156 {
04157
04158 writtenBlueBandName = QSTRING_NOT_SET;
04159 }
04160 QDomText mBlueBandNameText = document.createTextNode( writtenBlueBandName );
04161
04162 mBlueBandNameElement.appendChild( mBlueBandNameText );
04163
04164 rasterPropertiesElement.appendChild( mBlueBandNameElement );
04165
04166
04167
04168 QDomElement mGrayBandNameElement = document.createElement( "mGrayBandName" );
04169 QString writtenGrayBandName = grayBandName();
04170 if ( writtenGrayBandName == TRSTRING_NOT_SET )
04171 {
04172
04173 writtenGrayBandName = QSTRING_NOT_SET;
04174 }
04175 QDomText mGrayBandNameText = document.createTextNode( writtenGrayBandName );
04176
04177 mGrayBandNameElement.appendChild( mGrayBandNameText );
04178 rasterPropertiesElement.appendChild( mGrayBandNameElement );
04179
04180
04181 QDomElement mStandardDeviationsElement = document.createElement( "mStandardDeviations" );
04182 QDomText mStandardDeviationsText = document.createTextNode( QString::number( standardDeviations() ) );
04183
04184 mStandardDeviationsElement.appendChild( mStandardDeviationsText );
04185
04186 rasterPropertiesElement.appendChild( mStandardDeviationsElement );
04187
04188
04189 QDomElement userDefinedRGBMinMaxFlag = document.createElement( "mUserDefinedRGBMinimumMaximum" );
04190
04191 if ( hasUserDefinedRGBMinimumMaximum() )
04192 {
04193 userDefinedRGBMinMaxFlag.setAttribute( "boolean", "true" );
04194 }
04195 else
04196 {
04197 userDefinedRGBMinMaxFlag.setAttribute( "boolean", "false" );
04198 }
04199
04200 rasterPropertiesElement.appendChild( userDefinedRGBMinMaxFlag );
04201
04202
04203 QDomElement RGBMinimumMaximumEstimated = document.createElement( "mRGBMinimumMaximumEstimated" );
04204
04205 if ( isRGBMinimumMaximumEstimated() )
04206 {
04207 RGBMinimumMaximumEstimated.setAttribute( "boolean", "true" );
04208 }
04209 else
04210 {
04211 RGBMinimumMaximumEstimated.setAttribute( "boolean", "false" );
04212 }
04213
04214 rasterPropertiesElement.appendChild( RGBMinimumMaximumEstimated );
04215
04216
04217 QDomElement userDefinedGrayMinMaxFlag = document.createElement( "mUserDefinedGrayMinimumMaximum" );
04218
04219 if ( hasUserDefinedGrayMinimumMaximum() )
04220 {
04221 userDefinedGrayMinMaxFlag.setAttribute( "boolean", "true" );
04222 }
04223 else
04224 {
04225 userDefinedGrayMinMaxFlag.setAttribute( "boolean", "false" );
04226 }
04227
04228 rasterPropertiesElement.appendChild( userDefinedGrayMinMaxFlag );
04229
04230
04231 QDomElement GrayMinimumMaximumEstimated = document.createElement( "mGrayMinimumMaximumEstimated" );
04232
04233 if ( isGrayMinimumMaximumEstimated() )
04234 {
04235 GrayMinimumMaximumEstimated.setAttribute( "boolean", "true" );
04236 }
04237 else
04238 {
04239 GrayMinimumMaximumEstimated.setAttribute( "boolean", "false" );
04240 }
04241
04242 rasterPropertiesElement.appendChild( GrayMinimumMaximumEstimated );
04243
04244
04245 QDomElement contrastEnhancementAlgorithmElement = document.createElement( "mContrastEnhancementAlgorithm" );
04246 QDomText contrastEnhancementAlgorithmText = document.createTextNode( contrastEnhancementAlgorithmAsString() );
04247
04248 contrastEnhancementAlgorithmElement.appendChild( contrastEnhancementAlgorithmText );
04249
04250 rasterPropertiesElement.appendChild( contrastEnhancementAlgorithmElement );
04251
04252
04253 QList<QgsContrastEnhancement>::const_iterator it;
04254 QDomElement contrastEnhancementMinMaxValuesElement = document.createElement( "contrastEnhancementMinMaxValues" );
04255 for ( it = mContrastEnhancementList.constBegin(); it != mContrastEnhancementList.constEnd(); ++it )
04256 {
04257 QDomElement minMaxEntry = document.createElement( "minMaxEntry" );
04258 QDomElement minEntry = document.createElement( "min" );
04259 QDomElement maxEntry = document.createElement( "max" );
04260
04261 QDomText minEntryText = document.createTextNode( QString::number( it->minimumValue() ) );
04262 minEntry.appendChild( minEntryText );
04263
04264 QDomText maxEntryText = document.createTextNode( QString::number( it->maximumValue() ) );
04265 maxEntry.appendChild( maxEntryText );
04266
04267 minMaxEntry.appendChild( minEntry );
04268 minMaxEntry.appendChild( maxEntry );
04269
04270 contrastEnhancementMinMaxValuesElement.appendChild( minMaxEntry );
04271 }
04272
04273 rasterPropertiesElement.appendChild( contrastEnhancementMinMaxValuesElement );
04274
04275
04276
04277
04278
04279 QDomElement mNoDataValueElement = document.createElement( "mNoDataValue" );
04280 QDomText mNoDataValueText = document.createTextNode( QString::number( mNoDataValue, 'f' ) );
04281 if ( mValidNoDataValue )
04282 {
04283 mNoDataValueElement.setAttribute( "mValidNoDataValue", "true" );
04284 }
04285 else
04286 {
04287 mNoDataValueElement.setAttribute( "mValidNoDataValue", "false" );
04288 }
04289
04290 mNoDataValueElement.appendChild( mNoDataValueText );
04291
04292 rasterPropertiesElement.appendChild( mNoDataValueElement );
04293
04294
04295 if ( mRasterTransparency.transparentSingleValuePixelList().count() > 0 )
04296 {
04297 QDomElement singleValuePixelListElement = document.createElement( "singleValuePixelList" );
04298
04299
04300 QList<QgsRasterTransparency::TransparentSingleValuePixel> myPixelList = mRasterTransparency.transparentSingleValuePixelList();
04301 QList<QgsRasterTransparency::TransparentSingleValuePixel>::iterator it;
04302 for ( it = myPixelList.begin(); it != myPixelList.end(); ++it )
04303 {
04304 QDomElement pixelListElement = document.createElement( "pixelListEntry" );
04305 pixelListElement.setAttribute( "pixelValue", QString::number( it->pixelValue, 'f' ) );
04306 pixelListElement.setAttribute( "percentTransparent", QString::number( it->percentTransparent ) );
04307
04308 singleValuePixelListElement.appendChild( pixelListElement );
04309 }
04310
04311 rasterPropertiesElement.appendChild( singleValuePixelListElement );
04312 }
04313
04314 if ( mRasterTransparency.transparentThreeValuePixelList().count() > 0 )
04315 {
04316 QDomElement threeValuePixelListElement = document.createElement( "threeValuePixelList" );
04317
04318
04319 QList<QgsRasterTransparency::TransparentThreeValuePixel> myPixelList = mRasterTransparency.transparentThreeValuePixelList();
04320 QList<QgsRasterTransparency::TransparentThreeValuePixel>::iterator it;
04321 for ( it = myPixelList.begin(); it != myPixelList.end(); ++it )
04322 {
04323 QDomElement pixelListElement = document.createElement( "pixelListEntry" );
04324 pixelListElement.setAttribute( "red", QString::number( it->red, 'f' ) );
04325 pixelListElement.setAttribute( "green", QString::number( it->green, 'f' ) );
04326 pixelListElement.setAttribute( "blue", QString::number( it->blue, 'f' ) );
04327 pixelListElement.setAttribute( "percentTransparent", QString::number( it->percentTransparent ) );
04328
04329 threeValuePixelListElement.appendChild( pixelListElement );
04330 }
04331
04332 rasterPropertiesElement.appendChild( threeValuePixelListElement );
04333 }
04334
04335
04336
04337
04338 if ( QgsRasterLayer::ColorRampShader == colorShadingAlgorithm() )
04339 {
04340 QDomElement customColorRampElement = document.createElement( "customColorRamp" );
04341
04342 QDomElement customColorRampType = document.createElement( "colorRampType" );
04343 QDomText customColorRampTypeText = document.createTextNode((( QgsColorRampShader* )mRasterShader->rasterShaderFunction() )->colorRampTypeAsQString() );
04344 customColorRampType.appendChild( customColorRampTypeText );
04345 customColorRampElement.appendChild( customColorRampType );
04346
04347 QList<QgsColorRampShader::ColorRampItem> myColorRampItemList = (( QgsColorRampShader* )mRasterShader->rasterShaderFunction() )->colorRampItemList();
04348 QList<QgsColorRampShader::ColorRampItem>::iterator it;
04349 for ( it = myColorRampItemList.begin(); it != myColorRampItemList.end(); ++it )
04350 {
04351 QDomElement colorRampEntryElement = document.createElement( "colorRampEntry" );
04352 colorRampEntryElement.setAttribute( "red", QString::number( it->color.red() ) );
04353 colorRampEntryElement.setAttribute( "green", QString::number( it->color.green() ) );
04354 colorRampEntryElement.setAttribute( "blue", QString::number( it->color.blue() ) );
04355 colorRampEntryElement.setAttribute( "value", QString::number( it->value, 'f' ) );
04356 colorRampEntryElement.setAttribute( "label", it->label );
04357
04358 customColorRampElement.appendChild( colorRampEntryElement );
04359 }
04360
04361 rasterPropertiesElement.appendChild( customColorRampElement );
04362 }
04363
04364 return true;
04365 }
04366
04367
04368
04369
04370
04371 bool QgsRasterLayer::writeXml( QDomNode & layer_node,
04372 QDomDocument & document )
04373 {
04374
04375
04376 QDomElement mapLayerNode = layer_node.toElement();
04377
04378 if ( mapLayerNode.isNull() || ( "maplayer" != mapLayerNode.nodeName() ) )
04379 {
04380 QgsLogger::warning( "QgsRasterLayer::writeXML() can't find <maplayer>" );
04381 return false;
04382 }
04383
04384 mapLayerNode.setAttribute( "type", "raster" );
04385
04386
04387
04388 QDomElement provider = document.createElement( "provider" );
04389 QDomText providerText = document.createTextNode( mProviderKey );
04390 provider.appendChild( providerText );
04391 layer_node.appendChild( provider );
04392
04393
04394 QString errorMsg;
04395 return writeSymbology( layer_node, document, errorMsg );
04396 }
04397
04398
04399
04400
04402
04403
04404
04406 void QgsRasterLayer::drawMultiBandColor( QPainter * theQPainter, QgsRasterViewPort * theRasterViewPort,
04407 const QgsMapToPixel* theQgsMapToPixel )
04408 {
04409 QgsDebugMsg( "entered." );
04410 int myRedBandNo = bandNumber( mRedBandName );
04411
04412 if ( 0 >= myRedBandNo )
04413 {
04414 return;
04415 }
04416
04417 int myGreenBandNo = bandNumber( mGreenBandName );
04418
04419 if ( 0 >= myGreenBandNo )
04420 {
04421 return;
04422 }
04423
04424 int myBlueBandNo = bandNumber( mBlueBandName );
04425
04426 if ( 0 >= myBlueBandNo )
04427 {
04428 return;
04429 }
04430
04431 GDALRasterBandH myGdalRedBand = GDALGetRasterBand( mGdalDataset, myRedBandNo );
04432 GDALRasterBandH myGdalGreenBand = GDALGetRasterBand( mGdalDataset, myGreenBandNo );
04433 GDALRasterBandH myGdalBlueBand = GDALGetRasterBand( mGdalDataset, myBlueBandNo );
04434
04435 GDALDataType myRedType = GDALGetRasterDataType( myGdalRedBand );
04436 GDALDataType myGreenType = GDALGetRasterDataType( myGdalGreenBand );
04437 GDALDataType myBlueType = GDALGetRasterDataType( myGdalBlueBand );
04438
04439 QRgb* redImageScanLine = 0;
04440 void* redRasterScanLine = 0;
04441 QRgb* greenImageScanLine = 0;
04442 void* greenRasterScanLine = 0;
04443 QRgb* blueImageScanLine = 0;
04444 void* blueRasterScanLine = 0;
04445
04446 QRgb myDefaultColor = qRgba( 255, 255, 255, 0 );
04447
04448 QgsRasterBandStats myRedBandStats;
04449 QgsRasterBandStats myGreenBandStats;
04450 QgsRasterBandStats myBlueBandStats;
04451
04452
04453
04454
04455
04456
04457 if ( QgsContrastEnhancement::NoEnhancement != contrastEnhancementAlgorithm() && !mUserDefinedRGBMinimumMaximum && mStandardDeviations > 0 )
04458 {
04459 myRedBandStats = bandStatistics( myRedBandNo );
04460 myGreenBandStats = bandStatistics( myGreenBandNo );
04461 myBlueBandStats = bandStatistics( myBlueBandNo );
04462 mRGBMinimumMaximumEstimated = false;
04463 setMaximumValue( myRedBandNo, myRedBandStats.mean + ( mStandardDeviations * myRedBandStats.stdDev ) );
04464 setMinimumValue( myRedBandNo, myRedBandStats.mean - ( mStandardDeviations * myRedBandStats.stdDev ) );
04465 setMaximumValue( myGreenBandNo, myGreenBandStats.mean + ( mStandardDeviations * myGreenBandStats.stdDev ) );
04466 setMinimumValue( myGreenBandNo, myGreenBandStats.mean - ( mStandardDeviations * myGreenBandStats.stdDev ) );
04467 setMaximumValue( myBlueBandNo, myBlueBandStats.mean + ( mStandardDeviations * myBlueBandStats.stdDev ) );
04468 setMinimumValue( myBlueBandNo, myBlueBandStats.mean - ( mStandardDeviations * myBlueBandStats.stdDev ) );
04469 }
04470 else if ( QgsContrastEnhancement::NoEnhancement != contrastEnhancementAlgorithm() && !mUserDefinedRGBMinimumMaximum )
04471 {
04472
04473
04474 double GDALrange[2];
04475 mRGBMinimumMaximumEstimated = true;
04476
04477 GDALComputeRasterMinMax( myGdalRedBand, 1, GDALrange );
04478 setMaximumValue( myRedBandNo, GDALrange[1] );
04479 setMinimumValue( myRedBandNo, GDALrange[0] );
04480
04481 GDALComputeRasterMinMax( myGdalGreenBand, 1, GDALrange );
04482 setMaximumValue( myGreenBandNo, GDALrange[1] );
04483 setMinimumValue( myGreenBandNo, GDALrange[0] );
04484
04485 GDALComputeRasterMinMax( myGdalBlueBand, 1, GDALrange );
04486 setMaximumValue( myBlueBandNo, GDALrange[1] );
04487 setMinimumValue( myBlueBandNo, GDALrange[0] );
04488 }
04489
04490
04491 double myRedValue = 0.0;
04492 double myGreenValue = 0.0;
04493 double myBlueValue = 0.0;
04494
04495 int myStretchedRedValue = 0;
04496 int myStretchedGreenValue = 0;
04497 int myStretchedBlueValue = 0;
04498 int myAlphaValue = 0;
04499 QgsContrastEnhancement* myRedContrastEnhancement = contrastEnhancement( myRedBandNo );
04500 QgsContrastEnhancement* myGreenContrastEnhancement = contrastEnhancement( myGreenBandNo );
04501 QgsContrastEnhancement* myBlueContrastEnhancement = contrastEnhancement( myBlueBandNo );
04502
04503 QgsRasterImageBuffer redImageBuffer( myGdalRedBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
04504 redImageBuffer.reset();
04505 QgsRasterImageBuffer greenImageBuffer( myGdalGreenBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
04506 greenImageBuffer.setWritingEnabled( false );
04507 greenImageBuffer.reset();
04508 QgsRasterImageBuffer blueImageBuffer( myGdalBlueBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
04509 blueImageBuffer.setWritingEnabled( false );
04510 blueImageBuffer.reset();
04511
04512 while ( redImageBuffer.nextScanLine( &redImageScanLine, &redRasterScanLine )
04513 && greenImageBuffer.nextScanLine( &greenImageScanLine, &greenRasterScanLine )
04514 && blueImageBuffer.nextScanLine( &blueImageScanLine, &blueRasterScanLine ) )
04515 {
04516 for ( int i = 0; i < theRasterViewPort->drawableAreaXDim; ++i )
04517 {
04518 myRedValue = readValue( redRasterScanLine, ( GDALDataType )myRedType, i );
04519 myGreenValue = readValue( greenRasterScanLine, ( GDALDataType )myGreenType, i );
04520 myBlueValue = readValue( blueRasterScanLine, ( GDALDataType )myBlueType, i );
04521
04522 if ( mValidNoDataValue &&
04523 (
04524 ( fabs( myRedValue - mNoDataValue ) <= TINY_VALUE || myRedValue != myRedValue ) ||
04525 ( fabs( myGreenValue - mNoDataValue ) <= TINY_VALUE || myGreenValue != myGreenValue ) ||
04526 ( fabs( myBlueValue - mNoDataValue ) <= TINY_VALUE || myBlueValue != myBlueValue )
04527 )
04528 )
04529 {
04530 redImageScanLine[ i ] = myDefaultColor;
04531 continue;
04532 }
04533
04534 if ( !myRedContrastEnhancement->isValueInDisplayableRange( myRedValue ) ||
04535 !myGreenContrastEnhancement->isValueInDisplayableRange( myGreenValue ) ||
04536 !myBlueContrastEnhancement->isValueInDisplayableRange( myBlueValue ) )
04537 {
04538 redImageScanLine[ i ] = myDefaultColor;
04539 continue;
04540 }
04541
04542 myAlphaValue = mRasterTransparency.alphaValue( myRedValue, myGreenValue, myBlueValue, mTransparencyLevel );
04543 if ( 0 == myAlphaValue )
04544 {
04545 redImageScanLine[ i ] = myDefaultColor;
04546 continue;
04547 }
04548
04549 myStretchedRedValue = myRedContrastEnhancement->enhanceContrast( myRedValue );
04550 myStretchedGreenValue = myGreenContrastEnhancement->enhanceContrast( myGreenValue );
04551 myStretchedBlueValue = myBlueContrastEnhancement->enhanceContrast( myBlueValue );
04552
04553 if ( mInvertColor )
04554 {
04555 myStretchedRedValue = 255 - myStretchedRedValue;
04556 myStretchedGreenValue = 255 - myStretchedGreenValue;
04557 myStretchedBlueValue = 255 - myStretchedBlueValue;
04558 }
04559
04560 redImageScanLine[ i ] = qRgba( myStretchedRedValue, myStretchedGreenValue, myStretchedBlueValue, myAlphaValue );
04561 }
04562 }
04563 }
04564
04565 void QgsRasterLayer::drawMultiBandSingleBandGray( QPainter * theQPainter, QgsRasterViewPort * theRasterViewPort,
04566 const QgsMapToPixel* theQgsMapToPixel, int theBandNo )
04567 {
04568
04569 drawSingleBandGray( theQPainter, theRasterViewPort, theQgsMapToPixel, theBandNo );
04570 }
04571
04572 void QgsRasterLayer::drawMultiBandSingleBandPseudoColor( QPainter * theQPainter, QgsRasterViewPort * theRasterViewPort,
04573 const QgsMapToPixel* theQgsMapToPixel, int theBandNo )
04574 {
04575
04576 drawSingleBandPseudoColor( theQPainter, theRasterViewPort, theQgsMapToPixel, theBandNo );
04577 }
04578
04586 void QgsRasterLayer::drawPalettedSingleBandColor( QPainter * theQPainter, QgsRasterViewPort * theRasterViewPort,
04587 const QgsMapToPixel* theQgsMapToPixel, int theBandNo )
04588 {
04589 QgsDebugMsg( "entered." );
04590
04591 if ( 0 >= theBandNo )
04592 {
04593 return;
04594 }
04595
04596 if ( NULL == mRasterShader )
04597 {
04598 return;
04599 }
04600
04601 GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
04602 GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
04603
04604 QgsRasterImageBuffer imageBuffer( myGdalBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
04605 imageBuffer.reset();
04606
04607 QRgb* imageScanLine = 0;
04608 void* rasterScanLine = 0;
04609
04610 QRgb myDefaultColor = qRgba( 255, 255, 255, 0 );
04611 double myPixelValue = 0.0;
04612 int myRedValue = 0;
04613 int myGreenValue = 0;
04614 int myBlueValue = 0;
04615 int myAlphaValue = 0;
04616
04617 while ( imageBuffer.nextScanLine( &imageScanLine, &rasterScanLine ) )
04618 {
04619 for ( int i = 0; i < theRasterViewPort->drawableAreaXDim; ++i )
04620 {
04621 myRedValue = 0;
04622 myGreenValue = 0;
04623 myBlueValue = 0;
04624 myPixelValue = readValue( rasterScanLine, ( GDALDataType )myDataType, i );
04625
04626 if ( mValidNoDataValue && ( fabs( myPixelValue - mNoDataValue ) <= TINY_VALUE || myPixelValue != myPixelValue ) )
04627 {
04628 imageScanLine[ i ] = myDefaultColor;
04629 continue;
04630 }
04631
04632 myAlphaValue = mRasterTransparency.alphaValue( myPixelValue, mTransparencyLevel );
04633 if ( 0 == myAlphaValue )
04634 {
04635 imageScanLine[ i ] = myDefaultColor;
04636 continue;
04637 }
04638
04639 if ( !mRasterShader->shade( myPixelValue, &myRedValue, &myGreenValue, &myBlueValue ) )
04640 {
04641 imageScanLine[ i ] = myDefaultColor;
04642 continue;
04643 }
04644
04645 if ( mInvertColor )
04646 {
04647
04648 imageScanLine[ i ] = qRgba( myBlueValue, myGreenValue, myRedValue, myAlphaValue );
04649 }
04650 else
04651 {
04652
04653 imageScanLine[ i ] = qRgba( myRedValue, myGreenValue, myBlueValue, myAlphaValue );
04654 }
04655 }
04656 }
04657 }
04658
04666 void QgsRasterLayer::drawPalettedSingleBandGray( QPainter * theQPainter, QgsRasterViewPort * theRasterViewPort,
04667 const QgsMapToPixel* theQgsMapToPixel, int theBandNo )
04668 {
04669 QgsDebugMsg( "entered." );
04670
04671 if ( 0 >= theBandNo )
04672 {
04673 return;
04674 }
04675
04676 if ( NULL == mRasterShader )
04677 {
04678 return;
04679 }
04680
04681 GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
04682 GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
04683
04684 QgsRasterImageBuffer imageBuffer( myGdalBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
04685 imageBuffer.reset();
04686
04687 QRgb* imageScanLine = 0;
04688 void* rasterScanLine = 0;
04689
04690 QRgb myDefaultColor = qRgba( 255, 255, 255, 0 );
04691 double myPixelValue = 0.0;
04692 int myRedValue = 0;
04693 int myGreenValue = 0;
04694 int myBlueValue = 0;
04695 int myAlphaValue = 0;
04696
04697 while ( imageBuffer.nextScanLine( &imageScanLine, &rasterScanLine ) )
04698 {
04699 for ( int i = 0; i < theRasterViewPort->drawableAreaXDim; ++i )
04700 {
04701 myRedValue = 0;
04702 myGreenValue = 0;
04703 myBlueValue = 0;
04704 myPixelValue = readValue( rasterScanLine, ( GDALDataType )myDataType, i );
04705
04706 if ( mValidNoDataValue && ( fabs( myPixelValue - mNoDataValue ) <= TINY_VALUE || myPixelValue != myPixelValue ) )
04707 {
04708 imageScanLine[ i ] = myDefaultColor;
04709 continue;
04710 }
04711
04712 myAlphaValue = mRasterTransparency.alphaValue( myPixelValue, mTransparencyLevel );
04713 if ( 0 == myAlphaValue )
04714 {
04715 imageScanLine[ i ] = myDefaultColor;
04716 continue;
04717 }
04718
04719 if ( !mRasterShader->shade( myPixelValue, &myRedValue, &myGreenValue, &myBlueValue ) )
04720 {
04721 imageScanLine[ i ] = myDefaultColor;
04722 continue;
04723 }
04724
04725 if ( mInvertColor )
04726 {
04727
04728 double myGrayValue = ( 0.3 * ( double )myRedValue ) + ( 0.59 * ( double )myGreenValue ) + ( 0.11 * ( double )myBlueValue );
04729 imageScanLine[ i ] = qRgba(( int )myGrayValue, ( int )myGrayValue, ( int )myGrayValue, myAlphaValue );
04730 }
04731 else
04732 {
04733
04734 double myGrayValue = ( 0.3 * ( double )myBlueValue ) + ( 0.59 * ( double )myGreenValue ) + ( 0.11 * ( double )myRedValue );
04735 imageScanLine[ i ] = qRgba(( int )myGrayValue, ( int )myGrayValue, ( int )myGrayValue, myAlphaValue );
04736 }
04737 }
04738 }
04739 }
04740
04750 void QgsRasterLayer::drawPalettedSingleBandPseudoColor( QPainter * theQPainter, QgsRasterViewPort * theRasterViewPort,
04751 const QgsMapToPixel* theQgsMapToPixel, int theBandNo )
04752 {
04753 QgsDebugMsg( "entered." );
04754
04755 if ( 0 >= theBandNo )
04756 {
04757 return;
04758 }
04759
04760 QgsRasterBandStats myRasterBandStats = bandStatistics( theBandNo );
04761 GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
04762 GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
04763
04764 QgsRasterImageBuffer imageBuffer( myGdalBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
04765 imageBuffer.reset();
04766
04767 QRgb* imageScanLine = 0;
04768 void* rasterScanLine = 0;
04769
04770 QRgb myDefaultColor = qRgba( 255, 255, 255, 0 );
04771 double myMinimumValue = 0.0;
04772 double myMaximumValue = 0.0;
04773
04774 if ( mStandardDeviations > 0 )
04775 {
04776 myMinimumValue = ( myRasterBandStats.mean - ( mStandardDeviations * myRasterBandStats.stdDev ) );
04777 myMaximumValue = ( myRasterBandStats.mean + ( mStandardDeviations * myRasterBandStats.stdDev ) );
04778 }
04779 else
04780 {
04781 myMinimumValue = myRasterBandStats.minimumValue;
04782 myMaximumValue = myRasterBandStats.maximumValue;
04783 }
04784
04785 mRasterShader->setMinimumValue( myMinimumValue );
04786 mRasterShader->setMaximumValue( myMaximumValue );
04787
04788 double myPixelValue = 0.0;
04789 int myRedValue = 0;
04790 int myGreenValue = 0;
04791 int myBlueValue = 0;
04792 int myAlphaValue = 0;
04793
04794 while ( imageBuffer.nextScanLine( &imageScanLine, &rasterScanLine ) )
04795 {
04796 for ( int i = 0; i < theRasterViewPort->drawableAreaXDim; ++i )
04797 {
04798 myRedValue = 0;
04799 myGreenValue = 0;
04800 myBlueValue = 0;
04801 myPixelValue = readValue( rasterScanLine, ( GDALDataType )myDataType, i );
04802
04803 if ( mValidNoDataValue && ( fabs( myPixelValue - mNoDataValue ) <= TINY_VALUE || myPixelValue != myPixelValue ) )
04804 {
04805 imageScanLine[ i ] = myDefaultColor;
04806 continue;
04807 }
04808
04809 myAlphaValue = mRasterTransparency.alphaValue( myPixelValue, mTransparencyLevel );
04810 if ( 0 == myAlphaValue )
04811 {
04812 imageScanLine[ i ] = myDefaultColor;
04813 continue;
04814 }
04815
04816 if ( !mRasterShader->shade( myPixelValue, &myRedValue, &myGreenValue, &myBlueValue ) )
04817 {
04818 imageScanLine[ i ] = myDefaultColor;
04819 continue;
04820 }
04821
04822 if ( mInvertColor )
04823 {
04824
04825 imageScanLine[ i ] = qRgba( myBlueValue, myGreenValue, myRedValue, myAlphaValue );
04826 }
04827 else
04828 {
04829
04830 imageScanLine[ i ] = qRgba( myRedValue, myGreenValue, myBlueValue, myAlphaValue );
04831 }
04832 }
04833 }
04834 }
04835
04844 void QgsRasterLayer::drawPalettedMultiBandColor( QPainter * theQPainter, QgsRasterViewPort * theRasterViewPort,
04845 const QgsMapToPixel* theQgsMapToPixel, int theBandNo )
04846 {
04847 QgsDebugMsg( "Not supported at this time" );
04848 }
04849
04850 void QgsRasterLayer::drawSingleBandGray( QPainter * theQPainter, QgsRasterViewPort * theRasterViewPort, const QgsMapToPixel* theQgsMapToPixel, int theBandNo )
04851 {
04852 QgsDebugMsg( "layer=" + QString::number( theBandNo ) );
04853
04854 if ( 0 >= theBandNo )
04855 {
04856 return;
04857 }
04858
04859 GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
04860 GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
04861 QgsRasterImageBuffer imageBuffer( myGdalBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
04862 imageBuffer.reset();
04863
04864 QRgb* imageScanLine = 0;
04865 void* rasterScanLine = 0;
04866
04867 QRgb myDefaultColor = qRgba( 255, 255, 255, 0 );
04868 double myGrayValue = 0.0;
04869 int myGrayVal = 0;
04870 int myAlphaValue = 0;
04871 QgsContrastEnhancement* myContrastEnhancement = contrastEnhancement( theBandNo );
04872
04873 QgsRasterBandStats myGrayBandStats;
04874 if ( QgsContrastEnhancement::NoEnhancement != contrastEnhancementAlgorithm() && !mUserDefinedGrayMinimumMaximum && mStandardDeviations > 0 )
04875 {
04876 mGrayMinimumMaximumEstimated = false;
04877 myGrayBandStats = bandStatistics( theBandNo );
04878 setMaximumValue( theBandNo, myGrayBandStats.mean + ( mStandardDeviations * myGrayBandStats.stdDev ) );
04879 setMinimumValue( theBandNo, myGrayBandStats.mean - ( mStandardDeviations * myGrayBandStats.stdDev ) );
04880 }
04881 else if ( QgsContrastEnhancement::NoEnhancement != contrastEnhancementAlgorithm() && !mUserDefinedGrayMinimumMaximum )
04882 {
04883
04884
04885 double GDALrange[2];
04886 GDALComputeRasterMinMax( myGdalBand, 1, GDALrange );
04887 mGrayMinimumMaximumEstimated = true;
04888 setMaximumValue( theBandNo, GDALrange[1] );
04889 setMinimumValue( theBandNo, GDALrange[0] );
04890
04891 }
04892
04893 while ( imageBuffer.nextScanLine( &imageScanLine, &rasterScanLine ) )
04894 {
04895 for ( int i = 0; i < theRasterViewPort->drawableAreaXDim; ++i )
04896 {
04897 myGrayValue = readValue( rasterScanLine, ( GDALDataType )myDataType, i );
04898
04899 if ( mValidNoDataValue && ( fabs( myGrayValue - mNoDataValue ) <= TINY_VALUE || myGrayValue != myGrayValue ) )
04900 {
04901 imageScanLine[ i ] = myDefaultColor;
04902 continue;
04903 }
04904
04905 if ( !myContrastEnhancement->isValueInDisplayableRange( myGrayValue ) )
04906 {
04907 imageScanLine[ i ] = myDefaultColor;
04908 continue;
04909 }
04910
04911 myAlphaValue = mRasterTransparency.alphaValue( myGrayValue, mTransparencyLevel );
04912 if ( 0 == myAlphaValue )
04913 {
04914 imageScanLine[ i ] = myDefaultColor;
04915 continue;
04916 }
04917
04918
04919 myGrayVal = myContrastEnhancement->enhanceContrast( myGrayValue );
04920
04921 if ( mInvertColor )
04922 {
04923 myGrayVal = 255 - myGrayVal;
04924 }
04925
04926 imageScanLine[ i ] = qRgba( myGrayVal, myGrayVal, myGrayVal, myAlphaValue );
04927 }
04928 }
04929 }
04930
04931 void QgsRasterLayer::drawSingleBandPseudoColor( QPainter * theQPainter,
04932 QgsRasterViewPort * theRasterViewPort,
04933 const QgsMapToPixel* theQgsMapToPixel,
04934 int theBandNo )
04935 {
04936 QgsDebugMsg( "entered." );
04937
04938 if ( 0 >= theBandNo )
04939 {
04940 return;
04941 }
04942
04943 QgsRasterBandStats myRasterBandStats = bandStatistics( theBandNo );
04944 GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
04945 GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
04946
04947 QgsRasterImageBuffer imageBuffer( myGdalBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
04948 imageBuffer.reset();
04949
04950 QRgb* imageScanLine = 0;
04951 void* rasterScanLine = 0;
04952
04953 QRgb myDefaultColor = qRgba( 255, 255, 255, 0 );
04954 if ( NULL == mRasterShader )
04955 {
04956 return;
04957 }
04958
04959 double myMinimumValue = 0.0;
04960 double myMaximumValue = 0.0;
04961
04962 if ( mStandardDeviations > 0 )
04963 {
04964 myMinimumValue = ( myRasterBandStats.mean - ( mStandardDeviations * myRasterBandStats.stdDev ) );
04965 myMaximumValue = ( myRasterBandStats.mean + ( mStandardDeviations * myRasterBandStats.stdDev ) );
04966 }
04967 else
04968 {
04969 myMinimumValue = myRasterBandStats.minimumValue;
04970 myMaximumValue = myRasterBandStats.maximumValue;
04971 }
04972
04973 mRasterShader->setMinimumValue( myMinimumValue );
04974 mRasterShader->setMaximumValue( myMaximumValue );
04975
04976 int myRedValue = 255;
04977 int myGreenValue = 255;
04978 int myBlueValue = 255;
04979
04980 double myPixelValue = 0.0;
04981 int myAlphaValue = 0;
04982
04983 while ( imageBuffer.nextScanLine( &imageScanLine, &rasterScanLine ) )
04984 {
04985 for ( int i = 0; i < theRasterViewPort->drawableAreaXDim; ++i )
04986 {
04987 myPixelValue = readValue( rasterScanLine, myDataType, i );
04988
04989 if ( mValidNoDataValue && ( fabs( myPixelValue - mNoDataValue ) <= TINY_VALUE || myPixelValue != myPixelValue ) )
04990 {
04991 imageScanLine[ i ] = myDefaultColor;
04992 continue;
04993 }
04994
04995 myAlphaValue = mRasterTransparency.alphaValue( myPixelValue, mTransparencyLevel );
04996 if ( 0 == myAlphaValue )
04997 {
04998 imageScanLine[ i ] = myDefaultColor;
04999 continue;
05000 }
05001
05002 if ( !mRasterShader->shade( myPixelValue, &myRedValue, &myGreenValue, &myBlueValue ) )
05003 {
05004 imageScanLine[ i ] = myDefaultColor;
05005 continue;
05006 }
05007
05008 if ( mInvertColor )
05009 {
05010
05011 imageScanLine[ i ] = qRgba( myBlueValue, myGreenValue, myRedValue, myAlphaValue );
05012 }
05013 else
05014 {
05015
05016 imageScanLine[ i ] = qRgba( myRedValue, myGreenValue, myBlueValue, myAlphaValue );
05017 }
05018 }
05019 }
05020 }
05021
05022
05023 void QgsRasterLayer::closeDataset()
05024 {
05025 if ( !mValid ) return;
05026 mValid = false;
05027
05028 GDALDereferenceDataset( mGdalBaseDataset );
05029 mGdalBaseDataset = NULL;
05030
05031 GDALClose( mGdalDataset );
05032 mGdalDataset = NULL;
05033
05034 mHasPyramids = false;
05035 mPyramidList.clear();
05036
05037 mRasterStatsList.clear();
05038 }
05039
05040 QString QgsRasterLayer::generateBandName( int theBandNumber )
05041 {
05042 return tr( "Band" ) + QString( " %1" ) .arg( theBandNumber, 1 + ( int ) log10(( float ) bandCount() ), 10, QChar( '0' ) );
05043 }
05044
05049 bool QgsRasterLayer::hasBand( QString const & theBandName )
05050 {
05051
05052 QgsDebugMsg( "Looking for band : " + theBandName );
05053
05054 for ( int i = 1; i <= GDALGetRasterCount( mGdalDataset ); i++ )
05055 {
05056 GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, i );
05057 QString myColorQString = GDALGetColorInterpretationName( GDALGetRasterColorInterpretation( myGdalBand ) );
05058 #ifdef QGISDEBUG
05059 QgsLogger::debug( "band", i, __FILE__, __FUNCTION__, __LINE__, 2 );
05060 #endif
05061
05062 if ( myColorQString == theBandName )
05063 {
05064 #ifdef QGISDEBUG
05065 QgsLogger::debug( "band", i, __FILE__, __FUNCTION__, __LINE__, 2 );
05066 QgsDebugMsgLevel( "Found band : " + theBandName, 2 );
05067 #endif
05068
05069 return true;
05070 }
05071 QgsDebugMsgLevel( "Found unmatched band : " + QString::number( i ) + " " + myColorQString, 2 );
05072 }
05073 return false;
05074 }
05075
05076 void QgsRasterLayer::paintImageToCanvas( QPainter* theQPainter, QgsRasterViewPort * theRasterViewPort, const QgsMapToPixel* theQgsMapToPixel, QImage* theImage )
05077 {
05078
05079
05080 int paintXoffset = 0;
05081 int paintYoffset = 0;
05082
05083 if ( theQgsMapToPixel )
05084 {
05085 paintXoffset = static_cast<int>(
05086 ( theRasterViewPort->rectXOffsetFloat -
05087 theRasterViewPort->rectXOffset )
05088 / theQgsMapToPixel->mapUnitsPerPixel()
05089 * fabs( mGeoTransform[1] )
05090 );
05091
05092 paintYoffset = static_cast<int>(
05093 ( theRasterViewPort->rectYOffsetFloat -
05094 theRasterViewPort->rectYOffset )
05095 / theQgsMapToPixel->mapUnitsPerPixel()
05096 * fabs( mGeoTransform[5] )
05097 );
05098 }
05099
05100
05101
05102 QgsDebugMsg( "painting image to canvas from "
05103 + QString::number( paintXoffset ) + ", " + QString::number( paintYoffset )
05104 + " to "
05105 + QString::number( static_cast<int>( theRasterViewPort->topLeftPoint.x() + 0.5 ) )
05106 + ", "
05107 + QString::number( static_cast<int>( theRasterViewPort->topLeftPoint.y() + 0.5 ) )
05108 + "." );
05109
05110
05111
05112 if ( 1 == theRasterViewPort->clippedWidth && 1 == theRasterViewPort->clippedHeight )
05113 {
05114 QColor myColor( theImage->pixel( 0, 0 ) );
05115 myColor.setAlpha( qAlpha( theImage->pixel( 0, 0 ) ) );
05116 theQPainter->fillRect( static_cast<int>( theRasterViewPort->topLeftPoint.x() + 0.5 ),
05117 static_cast<int>( theRasterViewPort->topLeftPoint.y() + 0.5 ),
05118 static_cast<int>( theRasterViewPort->bottomRightPoint.x() ),
05119 static_cast<int>( theRasterViewPort->bottomRightPoint.y() ),
05120 QBrush( myColor ) );
05121 }
05122
05123 else if ( 2 >= theRasterViewPort->clippedWidth && 2 >= theRasterViewPort->clippedHeight )
05124 {
05125 int myPixelBoundaryX = 0;
05126 int myPixelBoundaryY = 0;
05127 if ( theQgsMapToPixel )
05128 {
05129 myPixelBoundaryX = static_cast<int>( theRasterViewPort->topLeftPoint.x() + 0.5 ) + static_cast<int>( fabs( mGeoTransform[1] / theQgsMapToPixel->mapUnitsPerPixel() ) ) - paintXoffset;
05130 myPixelBoundaryY = static_cast<int>( theRasterViewPort->topLeftPoint.y() + 0.5 ) + static_cast<int>( fabs( mGeoTransform[5] / theQgsMapToPixel->mapUnitsPerPixel() ) ) - paintYoffset;
05131 }
05132
05133
05134 if ( 1 == theRasterViewPort->clippedWidth )
05135 {
05136 QColor myColor( theImage->pixel( 0, 0 ) );
05137 myColor.setAlpha( qAlpha( theImage->pixel( 0, 0 ) ) );
05138 theQPainter->fillRect( static_cast<int>( theRasterViewPort->topLeftPoint.x() + 0.5 ),
05139 static_cast<int>( theRasterViewPort->topLeftPoint.y() + 0.5 ),
05140 static_cast<int>( theRasterViewPort->bottomRightPoint.x() ),
05141 static_cast<int>( myPixelBoundaryY ),
05142 QBrush( myColor ) );
05143 myColor = QColor( theImage->pixel( 0, 1 ) );
05144 myColor.setAlpha( qAlpha( theImage->pixel( 0, 1 ) ) );
05145 theQPainter->fillRect( static_cast<int>( theRasterViewPort->topLeftPoint.x() + 0.5 ),
05146 static_cast<int>( myPixelBoundaryY ),
05147 static_cast<int>( theRasterViewPort->bottomRightPoint.x() ),
05148 static_cast<int>( theRasterViewPort->bottomRightPoint.y() ),
05149 QBrush( myColor ) );
05150 }
05151 else
05152 {
05153
05154 if ( 1 == theRasterViewPort->clippedHeight )
05155 {
05156 QColor myColor( theImage->pixel( 0, 0 ) );
05157 myColor.setAlpha( qAlpha( theImage->pixel( 0, 0 ) ) );
05158 theQPainter->fillRect( static_cast<int>( theRasterViewPort->topLeftPoint.x() + 0.5 ),
05159 static_cast<int>( theRasterViewPort->topLeftPoint.y() + 0.5 ),
05160 static_cast<int>( myPixelBoundaryX ),
05161 static_cast<int>( theRasterViewPort->bottomRightPoint.y() ),
05162 QBrush( myColor ) );
05163 myColor = QColor( theImage->pixel( 1, 0 ) );
05164 myColor.setAlpha( qAlpha( theImage->pixel( 1, 0 ) ) );
05165 theQPainter->fillRect( static_cast<int>( myPixelBoundaryX ),
05166 static_cast<int>( theRasterViewPort->topLeftPoint.y() + 0.5 ),
05167 static_cast<int>( theRasterViewPort->bottomRightPoint.x() ),
05168 static_cast<int>( theRasterViewPort->bottomRightPoint.y() ),
05169 QBrush( myColor ) );
05170 }
05171
05172 else
05173 {
05174 QColor myColor( theImage->pixel( 0, 0 ) );
05175 myColor.setAlpha( qAlpha( theImage->pixel( 0, 0 ) ) );
05176 theQPainter->fillRect( static_cast<int>( theRasterViewPort->topLeftPoint.x() + 0.5 ),
05177 static_cast<int>( theRasterViewPort->topLeftPoint.y() + 0.5 ),
05178 static_cast<int>( myPixelBoundaryX ),
05179 static_cast<int>( myPixelBoundaryY ),
05180 QBrush( myColor ) );
05181 myColor = QColor( theImage->pixel( 1, 0 ) );
05182 myColor.setAlpha( qAlpha( theImage->pixel( 1, 0 ) ) );
05183 theQPainter->fillRect( static_cast<int>( myPixelBoundaryX ),
05184 static_cast<int>( theRasterViewPort->topLeftPoint.y() + 0.5 ),
05185 static_cast<int>( theRasterViewPort->bottomRightPoint.x() ),
05186 static_cast<int>( myPixelBoundaryY ),
05187 QBrush( myColor ) );
05188 myColor = QColor( theImage->pixel( 0, 1 ) );
05189 myColor.setAlpha( qAlpha( theImage->pixel( 0, 1 ) ) );
05190 theQPainter->fillRect( static_cast<int>( theRasterViewPort->topLeftPoint.x() + 0.5 ),
05191 static_cast<int>( myPixelBoundaryY ),
05192 static_cast<int>( myPixelBoundaryX ),
05193 static_cast<int>( theRasterViewPort->bottomRightPoint.y() ),
05194 QBrush( myColor ) );
05195 myColor = QColor( theImage->pixel( 1, 1 ) );
05196 myColor.setAlpha( qAlpha( theImage->pixel( 1, 1 ) ) );
05197 theQPainter->fillRect( static_cast<int>( myPixelBoundaryX ),
05198 static_cast<int>( myPixelBoundaryY ),
05199 static_cast<int>( theRasterViewPort->bottomRightPoint.x() ),
05200 static_cast<int>( theRasterViewPort->bottomRightPoint.y() ),
05201 QBrush( myColor ) );
05202 }
05203 }
05204
05205 }
05206
05207 else
05208 {
05209 theQPainter->drawImage( static_cast<int>( theRasterViewPort->topLeftPoint.x() + 0.5 ),
05210 static_cast<int>( theRasterViewPort->topLeftPoint.y() + 0.5 ),
05211 *theImage,
05212 paintXoffset,
05213 paintYoffset );
05214 }
05215 }
05216
05217 QString QgsRasterLayer::projectionWkt()
05218 {
05219 QString myWktString;
05220 QgsCoordinateReferenceSystem myCRS;
05221 myWktString = QString( GDALGetProjectionRef( mGdalDataset ) );
05222 myCRS.createFromWkt( myWktString );
05223 if ( !myCRS.isValid() )
05224 {
05225
05226 myWktString = QString( GDALGetGCPProjection( mGdalDataset ) );
05227
05228
05229
05230
05231
05232
05233
05234
05235
05236
05237 }
05238
05239 return myWktString;
05240 }
05241
05242
05243
05244
05245
05246 void *QgsRasterLayer::readData( GDALRasterBandH gdalBand, QgsRasterViewPort *viewPort )
05247 {
05248 GDALDataType type = GDALGetRasterDataType( gdalBand );
05249 int size = GDALGetDataTypeSize( type ) / 8;
05250
05251 QgsDebugMsg( "calling RasterIO with " +
05252 QString( ", source NW corner: " ) + QString::number( viewPort->rectXOffset ) +
05253 ", " + QString::number( viewPort->rectYOffset ) +
05254 ", source size: " + QString::number( viewPort->clippedWidth ) +
05255 ", " + QString::number( viewPort->clippedHeight ) +
05256 ", dest size: " + QString::number( viewPort->drawableAreaXDim ) +
05257 ", " + QString::number( viewPort->drawableAreaYDim ) );
05258
05259 void *data = VSIMalloc( size * viewPort->drawableAreaXDim * viewPort->drawableAreaYDim );
05260
05261
05262 if ( data == NULL )
05263 {
05264 QgsDebugMsg( "Layer " + name() + " couldn't allocate enough memory. Ignoring" );
05265 }
05266 else
05267 {
05268 CPLErr myErr = GDALRasterIO( gdalBand, GF_Read,
05269 viewPort->rectXOffset,
05270 viewPort->rectYOffset,
05271 viewPort->clippedWidth,
05272 viewPort->clippedHeight,
05273 data,
05274 viewPort->drawableAreaXDim,
05275 viewPort->drawableAreaYDim,
05276 type, 0, 0 );
05277 if ( myErr != CPLE_None )
05278 {
05279 QgsLogger::warning( "RasterIO error: " + QString::fromUtf8( CPLGetLastErrorMsg() ) );
05280 }
05281 }
05282 return data;
05283 }
05284
05285
05286
05287
05288
05289
05290
05291 bool QgsRasterLayer::readFile( QString const &theFilename )
05292 {
05293 registerGdalDrivers();
05294
05295 mGdalDataset = NULL;
05296
05297
05298 mGdalBaseDataset = GDALOpen( TO8F( theFilename ), GA_ReadOnly );
05299
05300 if ( mGdalBaseDataset == NULL )
05301 {
05302 mValid = false;
05303 return false;
05304 }
05305
05306
05307 mLastModified = lastModified( theFilename );
05308
05309
05310 if (( GDALGetGeoTransform( mGdalBaseDataset, mGeoTransform ) == CE_None
05311 && ( mGeoTransform[1] < 0.0
05312 || mGeoTransform[2] != 0.0
05313 || mGeoTransform[4] != 0.0
05314 || mGeoTransform[5] > 0.0 ) )
05315 || GDALGetGCPCount( mGdalBaseDataset ) > 0 )
05316 {
05317 QgsLogger::warning( "Creating Warped VRT." );
05318
05319 mGdalDataset =
05320 GDALAutoCreateWarpedVRT( mGdalBaseDataset, NULL, NULL,
05321 GRA_NearestNeighbour, 0.2, NULL );
05322 if ( mGdalDataset == NULL )
05323 {
05324 QgsLogger::warning( "Warped VRT Creation failed." );
05325 mGdalDataset = mGdalBaseDataset;
05326 GDALReferenceDataset( mGdalDataset );
05327 }
05328 }
05329 else
05330 {
05331 mGdalDataset = mGdalBaseDataset;
05332 GDALReferenceDataset( mGdalDataset );
05333 }
05334
05335 if ( subLayers().size() > 0 )
05336 {
05337
05338 mValid = false;
05339 return true;
05340 }
05341
05342
05343 GDALRasterBandH myGDALBand = GDALGetRasterBand( mGdalDataset, 1 );
05344 if ( myGDALBand == NULL )
05345 {
05346 GDALDereferenceDataset( mGdalBaseDataset );
05347 mGdalBaseDataset = NULL;
05348
05349 GDALClose( mGdalDataset );
05350 mGdalDataset = NULL;
05351 mValid = false;
05352 return false;
05353 }
05354
05355 mHasPyramids = GDALGetOverviewCount( myGDALBand ) > 0;
05356
05357
05358 buildPyramidList();
05359
05360
05361
05362
05363
05364 QString mySourceWkt = projectionWkt();
05365
05366 QgsDebugMsg( "--------------------------------------------------------------------------------------" );
05367 QgsDebugMsg( "using wkt:\n" + mySourceWkt );
05368 QgsDebugMsg( "--------------------------------------------------------------------------------------" );
05369
05370 mCRS->createFromWkt( mySourceWkt );
05371
05372
05373 if ( !mCRS->isValid() )
05374 {
05375 mCRS->setValidationHint( tr( "Specify CRS for layer %1" ).arg( name() ) );
05376 mCRS->validate();
05377 }
05378
05379
05380
05381
05382 QgsDebugMsg( "Layer registry has " + QString::number( QgsMapLayerRegistry::instance()->count() ) + "layers" );
05383
05384 metadata();
05385
05386
05387
05388 double myXMax = mGeoTransform[0] +
05389 GDALGetRasterXSize( mGdalDataset ) * mGeoTransform[1] +
05390 GDALGetRasterYSize( mGdalDataset ) * mGeoTransform[2];
05391 double myYMin = mGeoTransform[3] +
05392 GDALGetRasterXSize( mGdalDataset ) * mGeoTransform[4] +
05393 GDALGetRasterYSize( mGdalDataset ) * mGeoTransform[5];
05394
05395 mLayerExtent.setXMaximum( myXMax );
05396
05397
05398 mLayerExtent.setXMinimum( mGeoTransform[0] );
05399 mLayerExtent.setYMaximum( mGeoTransform[3] );
05400 mLayerExtent.setYMinimum( myYMin );
05401
05402
05403
05404
05405 mWidth = GDALGetRasterXSize( mGdalDataset );
05406 mHeight = GDALGetRasterYSize( mGdalDataset );
05407
05408
05409
05410
05411 mNoDataValue = -9999.0;
05412 mValidNoDataValue = false;
05413 int isValid = false;
05414 double myNoDataValue = GDALGetRasterNoDataValue( GDALGetRasterBand( mGdalDataset, 1 ), &isValid );
05415 if ( isValid )
05416 {
05417 mNoDataValue = myNoDataValue;
05418 mValidNoDataValue = true;
05419 }
05420
05421 if ( mValidNoDataValue )
05422 {
05423 mRasterTransparency.initializeTransparentPixelList( mNoDataValue, mNoDataValue, mNoDataValue );
05424 mRasterTransparency.initializeTransparentPixelList( mNoDataValue );
05425 }
05426
05427 mBandCount = GDALGetRasterCount( mGdalDataset );
05428 for ( int i = 1; i <= mBandCount; i++ )
05429 {
05430 GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, i );
05431 QgsRasterBandStats myRasterBandStats;
05432 myRasterBandStats.bandName = generateBandName( i );
05433 myRasterBandStats.bandNumber = i;
05434 myRasterBandStats.statsGathered = false;
05435 myRasterBandStats.histogramVector = new QgsRasterBandStats::HistogramVector();
05436
05437 readColorTable( i, &myRasterBandStats.colorTable );
05438
05439 mRasterStatsList.push_back( myRasterBandStats );
05440
05441
05442 QgsContrastEnhancement myContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )GDALGetRasterDataType( myGdalBand ) );
05443 mContrastEnhancementList.append( myContrastEnhancement );
05444 }
05445
05446
05447
05448 QSettings myQSettings;
05449 setContrastEnhancementAlgorithm( myQSettings.value( "/Raster/defaultContrastEnhancementAlgorithm", "StretchToMinimumMaximum" ).toString() );
05450
05451
05452
05453 if (( GDALGetRasterCount( mGdalDataset ) > 1 ) )
05454 {
05455 mRasterType = Multiband;
05456 }
05457
05458 else if ( hasBand( "Palette" ) )
05459 {
05460 mRasterType = Palette;
05461 }
05462 else
05463 {
05464 mRasterType = GrayOrUndefined;
05465 }
05466
05467 if ( mRasterType == Palette )
05468 {
05469 mRedBandName = TRSTRING_NOT_SET;
05470 mGreenBandName = TRSTRING_NOT_SET;
05471 mBlueBandName = TRSTRING_NOT_SET;
05472 mTransparencyBandName = TRSTRING_NOT_SET;
05473 mGrayBandName = bandName( 1 );
05474 QgsDebugMsg( mGrayBandName );
05475
05476 mDrawingStyle = PalettedColor;
05477
05478
05479 setColorShadingAlgorithm( ColorRampShader );
05480 QgsColorRampShader* myColorRampShader = ( QgsColorRampShader* ) mRasterShader->rasterShaderFunction();
05481
05482
05483 myColorRampShader->setColorRampType( QgsColorRampShader::INTERPOLATED );
05484 myColorRampShader->setColorRampItemList( *colorTable( 1 ) );
05485 }
05486 else if ( mRasterType == Multiband )
05487 {
05488
05489 mRedBandName = bandName( myQSettings.value( "/Raster/defaultRedBand", 1 ).toInt() );
05490 mGreenBandName = bandName( myQSettings.value( "/Raster/defaultGreenBand", 2 ).toInt() );
05491
05492
05493 if ( mRedBandName.isEmpty() )
05494 {
05495 mRedBandName = bandName( 1 );
05496 }
05497
05498 if ( mGreenBandName.isEmpty() )
05499 {
05500 mGreenBandName = bandName( 2 );
05501 }
05502
05503
05504 if ( GDALGetRasterCount( mGdalDataset ) > 2 )
05505 {
05506 mBlueBandName = bandName( myQSettings.value( "/Raster/defaultBlueBand", 3 ).toInt() );
05507 if ( mBlueBandName.isEmpty() )
05508 {
05509 mBlueBandName = bandName( 3 );
05510 }
05511 }
05512 else
05513 {
05514 mBlueBandName = bandName( myQSettings.value( "/Raster/defaultBlueBand", 2 ).toInt() );
05515 if ( mBlueBandName.isEmpty() )
05516 {
05517 mBlueBandName = bandName( 2 );
05518 }
05519 }
05520
05521
05522 mTransparencyBandName = TRSTRING_NOT_SET;
05523 mGrayBandName = TRSTRING_NOT_SET;
05524 mDrawingStyle = MultiBandColor;
05525 }
05526 else
05527 {
05528 mRedBandName = TRSTRING_NOT_SET;
05529 mGreenBandName = TRSTRING_NOT_SET;
05530 mBlueBandName = TRSTRING_NOT_SET;
05531 mTransparencyBandName = TRSTRING_NOT_SET;
05532 mDrawingStyle = SingleBandGray;
05533 mGrayBandName = bandName( 1 );
05534 }
05535
05536
05537 mValid = true;
05538 return true;
05539
05540 }
05541
05542
05543
05544
05545 double QgsRasterLayer::readValue( void *data, GDALDataType type, int index )
05546 {
05547 if ( !data )
05548 return mValidNoDataValue ? mNoDataValue : 0.0;
05549
05550 switch ( type )
05551 {
05552 case GDT_Byte:
05553 return ( double )(( GByte * )data )[index];
05554 break;
05555 case GDT_UInt16:
05556 return ( double )(( GUInt16 * )data )[index];
05557 break;
05558 case GDT_Int16:
05559 return ( double )(( GInt16 * )data )[index];
05560 break;
05561 case GDT_UInt32:
05562 return ( double )(( GUInt32 * )data )[index];
05563 break;
05564 case GDT_Int32:
05565 return ( double )(( GInt32 * )data )[index];
05566 break;
05567 case GDT_Float32:
05568 return ( double )(( float * )data )[index];
05569 break;
05570 case GDT_Float64:
05571 return ( double )(( double * )data )[index];
05572 break;
05573 default:
05574 QgsLogger::warning( "GDAL data type is not supported" );
05575 }
05576
05577 return mValidNoDataValue ? mNoDataValue : 0.0;
05578 }
05579
05580 bool QgsRasterLayer::update()
05581 {
05582 QgsDebugMsg( "entered." );
05583
05584 if ( mLastModified < QgsRasterLayer::lastModified( source() ) )
05585 {
05586 if ( !usesProvider() )
05587 {
05588 QgsDebugMsg( "Outdated -> reload" );
05589 closeDataset();
05590 return readFile( source() );
05591 }
05592 }
05593 return true;
05594 }
05595
05596 bool QgsRasterLayer::usesProvider()
05597 {
05598 return !mProviderKey.isEmpty();
05599 }
05600
05601 QString QgsRasterLayer::validateBandName( QString const & theBandName )
05602 {
05603 QgsDebugMsg( "Checking..." );
05604
05605 if ( theBandName == TRSTRING_NOT_SET || theBandName == QSTRING_NOT_SET )
05606 {
05607 QgsDebugMsg( "Band name is '" + QSTRING_NOT_SET + "'. Nothing to do." );
05608
05609 return TRSTRING_NOT_SET;
05610 }
05611
05612
05613 QgsDebugMsg( "Looking through raster band stats for matching band name" );
05614 for ( int myIterator = 0; myIterator < mRasterStatsList.size(); ++myIterator )
05615 {
05616
05617 if ( mRasterStatsList[myIterator].bandName == theBandName )
05618 {
05619 QgsDebugMsg( "Matching band name found" );
05620 return theBandName;
05621 }
05622 }
05623 QgsDebugMsg( "No matching band name found in raster band stats" );
05624
05625 QgsDebugMsg( "Testing for non zero-buffered names" );
05626
05627 QStringList myBandNameComponents = theBandName.split( " " );
05628 if ( myBandNameComponents.size() == 2 )
05629 {
05630 int myBandNumber = myBandNameComponents.at( 1 ).toInt();
05631 if ( myBandNumber > 0 )
05632 {
05633 QString myBandName = generateBandName( myBandNumber );
05634 for ( int myIterator = 0; myIterator < mRasterStatsList.size(); ++myIterator )
05635 {
05636
05637 if ( mRasterStatsList[myIterator].bandName == myBandName )
05638 {
05639 QgsDebugMsg( "Matching band name found" );
05640 return myBandName;
05641 }
05642 }
05643 }
05644 }
05645
05646 QgsDebugMsg( "Testing older naming format" );
05647
05648
05649 myBandNameComponents.clear();
05650 if ( theBandName.contains( ':' ) )
05651 {
05652 myBandNameComponents = theBandName.split( ":" );
05653 if ( myBandNameComponents.size() == 2 )
05654 {
05655 int myBandNumber = myBandNameComponents.at( 0 ).toInt();
05656 if ( myBandNumber > 0 )
05657 {
05658 QgsDebugMsg( "Transformed older name format to current format" );
05659 return "Band " + QString::number( myBandNumber );
05660 }
05661 }
05662 }
05663
05664
05665 QgsDebugMsg( "All checks failed, returning '" + QSTRING_NOT_SET + "'" );
05666 return TRSTRING_NOT_SET;
05667 }
05668
05669 QgsRasterImageBuffer::QgsRasterImageBuffer( GDALRasterBandH rasterBand, QPainter* p, QgsRasterViewPort* viewPort, const QgsMapToPixel* mapToPixel, double* geoTransform ):
05670 mRasterBand( rasterBand ), mPainter( p ), mViewPort( viewPort ), mMapToPixel( mapToPixel ), mGeoTransform( geoTransform ), mValid( false ), mWritingEnabled( true ), mDrawPixelRect( false ), mCurrentImage( 0 ), mCurrentGDALData( 0 )
05671 {
05672
05673 }
05674
05675 QgsRasterImageBuffer::~QgsRasterImageBuffer()
05676 {
05677 delete mCurrentImage;
05678 CPLFree( mCurrentGDALData );
05679 }
05680
05681 void QgsRasterImageBuffer::reset( int maxPixelsInVirtualMemory )
05682 {
05683 if ( !mRasterBand || !mPainter || !mViewPort )
05684 {
05685 mValid = false;
05686 return;
05687 }
05688
05689 mValid = true;
05690
05691
05692
05693 int pixels = mViewPort->drawableAreaXDim * mViewPort->drawableAreaYDim;
05694 int mNumPartImages = pixels / maxPixelsInVirtualMemory + 1.0;
05695 mNumRasterRowsPerPart = ( double )mViewPort->clippedHeight / ( double )mNumPartImages + 0.5;
05696
05697 mCurrentPartRasterMin = -1;
05698 mCurrentPartRasterMax = -1;
05699 mCurrentPartImageRow = 0;
05700 mNumCurrentImageRows = 0;
05701
05702 createNextPartImage();
05703
05704 if ( 2 >= mViewPort->clippedWidth && 2 >= mViewPort->clippedHeight )
05705 {
05706
05707 mDrawPixelRect = true;
05708 }
05709 }
05710
05711 bool QgsRasterImageBuffer::nextScanLine( QRgb** imageScanLine, void** rasterScanLine )
05712 {
05713 if ( !mValid )
05714 return false;
05715
05716 if ( !mCurrentImage && !mCurrentGDALData )
05717 {
05718 return false;
05719 }
05720
05721 if ( mCurrentPartImageRow >= mNumCurrentImageRows )
05722 {
05723 if ( !createNextPartImage() )
05724 {
05725 return false;
05726 }
05727 }
05728
05729 if ( mWritingEnabled )
05730 {
05731 *imageScanLine = ( QRgb* ) mCurrentImage->scanLine( mCurrentPartImageRow );
05732 }
05733 else
05734 {
05735 *imageScanLine = 0;
05736 }
05737 GDALDataType type = GDALGetRasterDataType( mRasterBand );
05738 int size = GDALGetDataTypeSize( type ) / 8;
05739 *rasterScanLine = ( unsigned char * )mCurrentGDALData + mCurrentPartImageRow * mViewPort->drawableAreaXDim * size;
05740
05741 ++mCurrentPartImageRow;
05742 ++mCurrentRow;
05743 return !mWritingEnabled || *imageScanLine;
05744 }
05745
05746 bool QgsRasterImageBuffer::createNextPartImage()
05747 {
05748
05749 if ( mCurrentImage )
05750 {
05751 if ( mWritingEnabled )
05752 {
05753 if ( 2 >= mViewPort->clippedWidth && 2 >= mViewPort->clippedHeight )
05754 {
05755 drawPixelRectangle();
05756 }
05757 else
05758 {
05759 int paintXoffset = 0;
05760 int paintYoffset = 0;
05761 int imageX = 0;
05762 int imageY = 0;
05763
05764 if ( mMapToPixel )
05765 {
05766 paintXoffset = static_cast<int>(
05767 ( mViewPort->rectXOffsetFloat -
05768 mViewPort->rectXOffset )
05769 / mMapToPixel->mapUnitsPerPixel()
05770 * fabs( mGeoTransform[1] )
05771 );
05772
05773 paintYoffset = static_cast<int>(
05774 ( mViewPort->rectYOffsetFloat -
05775 mViewPort->rectYOffset )
05776 / mMapToPixel->mapUnitsPerPixel()
05777 * fabs( mGeoTransform[5] )
05778 );
05779
05780 imageX = static_cast<int>( mViewPort->topLeftPoint.x() + 0.5 );
05781 imageY = static_cast<int>( mViewPort->topLeftPoint.y() + 0.5 + fabs( mGeoTransform[5] ) * mCurrentPartRasterMin / mMapToPixel->mapUnitsPerPixel() );
05782 }
05783
05784 mPainter->drawImage( imageX,
05785 imageY,
05786 *mCurrentImage,
05787 paintXoffset,
05788 paintYoffset );
05789 }
05790 }
05791 }
05792
05793 delete mCurrentImage; mCurrentImage = 0;
05794 CPLFree( mCurrentGDALData ); mCurrentGDALData = 0;
05795
05796 if ( mCurrentPartRasterMax >= mViewPort->clippedHeight )
05797 {
05798 return false;
05799 }
05800
05801 mCurrentPartRasterMin = mCurrentPartRasterMax + 1;
05802 mCurrentPartRasterMax = mCurrentPartRasterMin + mNumRasterRowsPerPart;
05803 if ( mCurrentPartRasterMax > mViewPort->clippedHeight )
05804 {
05805 mCurrentPartRasterMax = mViewPort->clippedHeight;
05806 }
05807 mCurrentRow = mCurrentPartRasterMin;
05808 mCurrentPartImageRow = 0;
05809
05810
05811 GDALDataType type = GDALGetRasterDataType( mRasterBand );
05812 int size = GDALGetDataTypeSize( type ) / 8;
05813 int xSize = mViewPort->drawableAreaXDim;
05814 int ySize = mViewPort->drawableAreaYDim;
05815
05816
05817 int overlapRows = 0;
05818 if ( mMapToPixel )
05819 {
05820 overlapRows = mMapToPixel->mapUnitsPerPixel() / fabs( mGeoTransform[5] ) + 2;
05821 }
05822 if ( mCurrentPartRasterMax + overlapRows >= mViewPort->clippedHeight )
05823 {
05824 overlapRows = 0;
05825 }
05826 int rasterYSize = mCurrentPartRasterMax - mCurrentPartRasterMin + overlapRows;
05827
05828 if ( 2 >= mViewPort->clippedWidth && 2 >= mViewPort->clippedHeight )
05829 {
05830 rasterYSize = mViewPort->clippedHeight;
05831 ySize = mViewPort->drawableAreaYDim;
05832 }
05833 else
05834 {
05835 if ( mMapToPixel )
05836 {
05837 ySize = fabs((( rasterYSize ) / mMapToPixel->mapUnitsPerPixel() * mGeoTransform[5] ) ) + 0.5;
05838 }
05839 }
05840 if ( ySize < 1 || xSize < 1 )
05841 {
05842 return false;
05843 }
05844 mNumCurrentImageRows = ySize;
05845 mCurrentGDALData = VSIMalloc( size * xSize * ySize );
05846 CPLErr myErr = GDALRasterIO( mRasterBand, GF_Read, mViewPort->rectXOffset,
05847 mViewPort->rectYOffset + mCurrentRow, mViewPort->clippedWidth, rasterYSize,
05848 mCurrentGDALData, xSize, ySize, type, 0, 0 );
05849
05850 if ( myErr != CPLE_None )
05851 {
05852 CPLFree( mCurrentGDALData );
05853 mCurrentGDALData = 0;
05854 return false;
05855 }
05856
05857
05858 if ( mWritingEnabled )
05859 {
05860 mCurrentImage = new QImage( xSize, ySize, QImage::Format_ARGB32 );
05861 mCurrentImage->fill( qRgba( 255, 255, 255, 0 ) );
05862 }
05863 else
05864 {
05865 mCurrentImage = 0;
05866 }
05867 return true;
05868 }
05869
05870 void QgsRasterImageBuffer::drawPixelRectangle()
05871 {
05872
05873
05874 int paintXoffset = 0;
05875 int paintYoffset = 0;
05876
05877 if ( mMapToPixel )
05878 {
05879 paintXoffset = static_cast<int>(
05880 ( mViewPort->rectXOffsetFloat -
05881 mViewPort->rectXOffset )
05882 / mMapToPixel->mapUnitsPerPixel()
05883 * fabs( mGeoTransform[1] )
05884 );
05885
05886 paintYoffset = static_cast<int>(
05887 ( mViewPort->rectYOffsetFloat -
05888 mViewPort->rectYOffset )
05889 / mMapToPixel->mapUnitsPerPixel()
05890 * fabs( mGeoTransform[5] )
05891 );
05892 }
05893
05894
05895
05896
05897 if ( 1 == mViewPort->clippedWidth && 1 == mViewPort->clippedHeight )
05898 {
05899 QColor myColor( mCurrentImage->pixel( 0, 0 ) );
05900 myColor.setAlpha( qAlpha( mCurrentImage->pixel( 0, 0 ) ) );
05901 mPainter->fillRect( static_cast<int>( mViewPort->topLeftPoint.x() + 0.5 ),
05902 static_cast<int>( mViewPort->topLeftPoint.y() + 0.5 ),
05903 static_cast<int>( mViewPort->bottomRightPoint.x() ),
05904 static_cast<int>( mViewPort->bottomRightPoint.y() ),
05905 QBrush( myColor ) );
05906 }
05907
05908 else if ( 2 >= mViewPort->clippedWidth && 2 >= mViewPort->clippedHeight )
05909 {
05910 int myPixelBoundaryX = 0;
05911 int myPixelBoundaryY = 0;
05912 if ( mMapToPixel )
05913 {
05914 myPixelBoundaryX = static_cast<int>( mViewPort->topLeftPoint.x() + 0.5 ) + static_cast<int>( fabs( mGeoTransform[1] / mMapToPixel->mapUnitsPerPixel() ) ) - paintXoffset;
05915 myPixelBoundaryY = static_cast<int>( mViewPort->topLeftPoint.y() + 0.5 ) + static_cast<int>( fabs( mGeoTransform[5] / mMapToPixel->mapUnitsPerPixel() ) ) - paintYoffset;
05916 }
05917
05918
05919 if ( 1 == mViewPort->clippedWidth )
05920 {
05921 QColor myColor( mCurrentImage->pixel( 0, 0 ) );
05922 myColor.setAlpha( qAlpha( mCurrentImage->pixel( 0, 0 ) ) );
05923 mPainter->fillRect( static_cast<int>( mViewPort->topLeftPoint.x() + 0.5 ),
05924 static_cast<int>( mViewPort->topLeftPoint.y() + 0.5 ),
05925 static_cast<int>( mViewPort->bottomRightPoint.x() ),
05926 static_cast<int>( myPixelBoundaryY ),
05927 QBrush( myColor ) );
05928 myColor = QColor( mCurrentImage->pixel( 0, 1 ) );
05929 myColor.setAlpha( qAlpha( mCurrentImage->pixel( 0, 1 ) ) );
05930 mPainter->fillRect( static_cast<int>( mViewPort->topLeftPoint.x() + 0.5 ),
05931 static_cast<int>( myPixelBoundaryY ),
05932 static_cast<int>( mViewPort->bottomRightPoint.x() ),
05933 static_cast<int>( mViewPort->bottomRightPoint.y() ),
05934 QBrush( myColor ) );
05935 }
05936 else
05937 {
05938
05939 if ( 1 == mViewPort->clippedHeight )
05940 {
05941 QColor myColor( mCurrentImage->pixel( 0, 0 ) );
05942 myColor.setAlpha( qAlpha( mCurrentImage->pixel( 0, 0 ) ) );
05943 mPainter->fillRect( static_cast<int>( mViewPort->topLeftPoint.x() + 0.5 ),
05944 static_cast<int>( mViewPort->topLeftPoint.y() + 0.5 ),
05945 static_cast<int>( myPixelBoundaryX ),
05946 static_cast<int>( mViewPort->bottomRightPoint.y() ),
05947 QBrush( myColor ) );
05948 myColor = QColor( mCurrentImage->pixel( 1, 0 ) );
05949 myColor.setAlpha( qAlpha( mCurrentImage->pixel( 1, 0 ) ) );
05950 mPainter->fillRect( static_cast<int>( myPixelBoundaryX ),
05951 static_cast<int>( mViewPort->topLeftPoint.y() + 0.5 ),
05952 static_cast<int>( mViewPort->bottomRightPoint.x() ),
05953 static_cast<int>( mViewPort->bottomRightPoint.y() ),
05954 QBrush( myColor ) );
05955 }
05956
05957 else
05958 {
05959 QColor myColor( mCurrentImage->pixel( 0, 0 ) );
05960 myColor.setAlpha( qAlpha( mCurrentImage->pixel( 0, 0 ) ) );
05961 mPainter->fillRect( static_cast<int>( mViewPort->topLeftPoint.x() + 0.5 ),
05962 static_cast<int>( mViewPort->topLeftPoint.y() + 0.5 ),
05963 static_cast<int>( myPixelBoundaryX ),
05964 static_cast<int>( myPixelBoundaryY ),
05965 QBrush( myColor ) );
05966 myColor = QColor( mCurrentImage->pixel( 1, 0 ) );
05967 myColor.setAlpha( qAlpha( mCurrentImage->pixel( 1, 0 ) ) );
05968 mPainter->fillRect( static_cast<int>( myPixelBoundaryX ),
05969 static_cast<int>( mViewPort->topLeftPoint.y() + 0.5 ),
05970 static_cast<int>( mViewPort->bottomRightPoint.x() ),
05971 static_cast<int>( myPixelBoundaryY ),
05972 QBrush( myColor ) );
05973 myColor = QColor( mCurrentImage->pixel( 0, 1 ) );
05974 myColor.setAlpha( qAlpha( mCurrentImage->pixel( 0, 1 ) ) );
05975 mPainter->fillRect( static_cast<int>( mViewPort->topLeftPoint.x() + 0.5 ),
05976 static_cast<int>( myPixelBoundaryY ),
05977 static_cast<int>( myPixelBoundaryX ),
05978 static_cast<int>( mViewPort->bottomRightPoint.y() ),
05979 QBrush( myColor ) );
05980 myColor = QColor( mCurrentImage->pixel( 1, 1 ) );
05981 myColor.setAlpha( qAlpha( mCurrentImage->pixel( 1, 1 ) ) );
05982 mPainter->fillRect( static_cast<int>( myPixelBoundaryX ),
05983 static_cast<int>( myPixelBoundaryY ),
05984 static_cast<int>( mViewPort->bottomRightPoint.x() ),
05985 static_cast<int>( mViewPort->bottomRightPoint.y() ),
05986 QBrush( myColor ) );
05987 }
05988 }
05989 }
05990 }