[QGIS Commit] r15218 - in branches/raster-providers/src: core providers/gdal

svn_qgis at osgeo.org svn_qgis at osgeo.org
Sun Feb 20 10:11:59 EST 2011


Author: rblazek
Date: 2011-02-20 07:11:59 -0800 (Sun, 20 Feb 2011)
New Revision: 15218

Modified:
   branches/raster-providers/src/core/qgsrasterdataprovider.h
   branches/raster-providers/src/providers/gdal/qgsgdalprovider.cpp
   branches/raster-providers/src/providers/gdal/qgsgdalprovider.h
Log:
better no data support

Modified: branches/raster-providers/src/core/qgsrasterdataprovider.h
===================================================================
--- branches/raster-providers/src/core/qgsrasterdataprovider.h	2011-02-20 14:55:35 UTC (rev 15217)
+++ branches/raster-providers/src/core/qgsrasterdataprovider.h	2011-02-20 15:11:59 UTC (rev 15218)
@@ -171,6 +171,14 @@
       return QgsRasterDataProvider::UnknownDataType;
     }
 
+    /** Returns source data type for the band specified by number,
+     *  source data type may be shorter than dataType  
+     */
+    virtual int srcDataType ( int bandNo ) const
+    {
+      return QgsRasterDataProvider::UnknownDataType;
+    }
+
     int typeSize ( int dataType ) const
     {
       // modified copy from GDAL
@@ -455,7 +463,7 @@
     int mDpi;
 
     /** \brief Cell value representing no data. e.g. -9999  */
-    double mNoDataValue;
+    QList<double> mNoDataValue;
 
     /** \brief Flag indicating if the nodatavalue is valid*/
     bool mValidNoDataValue;

Modified: branches/raster-providers/src/providers/gdal/qgsgdalprovider.cpp
===================================================================
--- branches/raster-providers/src/providers/gdal/qgsgdalprovider.cpp	2011-02-20 14:55:35 UTC (rev 15217)
+++ branches/raster-providers/src/providers/gdal/qgsgdalprovider.cpp	2011-02-20 15:11:59 UTC (rev 15218)
@@ -253,46 +253,61 @@
 
   GDALGetBlockSize( GDALGetRasterBand( mGdalDataset, 1 ), &mXBlockSize, &mYBlockSize );
   //
-  // Determine the nodata value
+  // Determine the nodata value and data type
   //
-  mNoDataValue = -9999.0; //Standard default?
-  mValidNoDataValue = false;
-  int isValid = false;
-  double myNoDataValue = GDALGetRasterNoDataValue( GDALGetRasterBand( mGdalDataset, 1 ), &isValid );
-  if ( isValid )
+  mValidNoDataValue = true;
+  for ( int i = 0; i < GDALGetRasterCount( mGdalBaseDataset ); i++ )
   {
-    QgsDebugMsg( QString("GDALGetRasterNoDataValue = %1").arg( myNoDataValue ) ) ;
-    mNoDataValue = myNoDataValue;
-    mValidNoDataValue = true;
-  } 
-  else 
-  {
-    // But we need a null value in case of reprojection and BTW also for 
-    // aligned margines
+    GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, i );
+    GDALDataType myGdalDataType = GDALGetRasterDataType( myGdalBand );
+    int isValid = false;
+    double myNoDataValue = GDALGetRasterNoDataValue( GDALGetRasterBand( mGdalDataset, i ), &isValid );
+    if ( isValid )
+    {
+      QgsDebugMsg( QString("GDALGetRasterNoDataValue = %1").arg( myNoDataValue ) ) ;
+      mGdalDataType.append( myGdalDataType );
+       
+    } 
+    else 
+    {
+      // But we need a null value in case of reprojection and BTW also for 
+      // aligned margines
 
-    switch ( dataType( 1 ) ) {
-      case QgsRasterDataProvider::Byte:
-        mNoDataValue = 255.0;
-        break;
-      case QgsRasterDataProvider::Int16:
-        mNoDataValue = -32768.0;
-        break;
-      case QgsRasterDataProvider::UInt16:
-        mNoDataValue = 65535.0;
-        break;
-      case QgsRasterDataProvider::Int32:
-        mNoDataValue = -2147483648.0;
-        break;
-      case QgsRasterDataProvider::UInt32:
-        mNoDataValue = 4294967295.0;
-        break;
-      default:
-        mNoDataValue = std::numeric_limits<int>::max();
+      switch ( srcDataType( i ) ) {
+        case QgsRasterDataProvider::Byte:
+          // Use longer data type to avoid conflict with real data
+          //myNoDataValue = 255.0;
+          myNoDataValue = -32768.0;
+          mGdalDataType.append( GDT_UInt16 );
+          break;
+        case QgsRasterDataProvider::Int16:
+          //myNoDataValue = -32768.0;
+          myNoDataValue = -2147483648.0;
+          mGdalDataType.append( GDT_UInt32 );
+          break;
+        case QgsRasterDataProvider::UInt16:
+          //myNoDataValue = 65535.0;
+          myNoDataValue = -2147483648.0;
+          mGdalDataType.append( GDT_UInt32 );
+          break;
+        case QgsRasterDataProvider::Int32:
+          myNoDataValue = -2147483648.0;
+          mGdalDataType.append( myGdalDataType );
+          break;
+        case QgsRasterDataProvider::UInt32:
+          myNoDataValue = 4294967295.0;
+          mGdalDataType.append( myGdalDataType );
+          break;
+        default:
+          myNoDataValue = std::numeric_limits<int>::max();
+          // Would NaN work well? 
+          //myNoDataValue = std::numeric_limits<double>::quiet_NaN(); 
+          mGdalDataType.append( myGdalDataType );
+      }
     }
-    QgsDebugMsg( QString("GDALGetRasterNoDataValue not set, using = %1").arg( mNoDataValue ) );
-    mValidNoDataValue = true;
+    mNoDataValue.append( myNoDataValue );
+    QgsDebugMsg( QString("mNoDataValue[%1] = %1").arg(i).arg ( mNoDataValue[i] ) ); 
   }
-  QgsDebugMsg( QString("mNoDataValue = %1").arg ( mNoDataValue ) ); 
 
   // This block of code was in old version in QgsRasterLayer::bandStatistics 
   //ifdefs below to remove compiler warning about unused vars
@@ -550,7 +565,8 @@
 
  
   // TODO: more bands support
-  myMemDsn.sprintf ( "MEM:::DATAPOINTER=%lu,PIXELS=%d,LINES=%d,BANDS=1,DATATYPE=%s,PIXELOFFSET=0,LINEOFFSET=0,BANDOFFSET=0", (long)theBlock, thePixelWidth, thePixelHeight,  GDALGetDataTypeName( myGdalDataType ) );
+  //myMemDsn.sprintf ( "MEM:::DATAPOINTER=%lu,PIXELS=%d,LINES=%d,BANDS=1,DATATYPE=%s,PIXELOFFSET=0,LINEOFFSET=0,BANDOFFSET=0", (long)theBlock, thePixelWidth, thePixelHeight,  GDALGetDataTypeName( myGdalDataType ) );
+  myMemDsn.sprintf ( "MEM:::DATAPOINTER=%lu,PIXELS=%d,LINES=%d,BANDS=1,DATATYPE=%s,PIXELOFFSET=0,LINEOFFSET=0,BANDOFFSET=0", (long)theBlock, thePixelWidth, thePixelHeight,  GDALGetDataTypeName( (GDALDataType)mGdalDataType[theBandNo] ) );
 
   QgsDebugMsg( "Open GDAL MEM : " + myMemDsn );
 
@@ -646,7 +662,7 @@
 
   }
   */
-  myWarpOptions->padfDstNoDataReal[0] = mNoDataValue;
+  myWarpOptions->padfDstNoDataReal[0] = mNoDataValue[theBandNo];
   myWarpOptions->padfDstNoDataImag[0] = 0.0;
 
   GDALSetRasterNoDataValue( GDALGetRasterBand( myGdalMemDataset, 
@@ -687,7 +703,10 @@
 }
 
 double  QgsGdalProvider::noDataValue() const {
-  return mNoDataValue;
+  if ( mNoDataValue.size () > 0 ) {
+    return mNoDataValue[0];
+  }
+  return std::numeric_limits<int>::max(); // should not happen or be used
 }
 
 void QgsGdalProvider::computeMinMax ( int theBandNo ) 
@@ -878,7 +897,7 @@
 #endif
       QString v;
 
-      if ( mValidNoDataValue && ( fabs( value - mNoDataValue ) <= TINY_VALUE || value != value ) )
+      if ( mValidNoDataValue && ( fabs( value - mNoDataValue[i] ) <= TINY_VALUE || value != value ) )
       {
         v = tr( "null (no data)" );
       }
@@ -904,12 +923,9 @@
   return capability;
 }
 
-int QgsGdalProvider::dataType( int bandNo ) const
+int QgsGdalProvider::dataTypeFormGdal( int theGdalDataType ) const
 {
-  GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, bandNo ); 
-  GDALDataType myGdalDataType = GDALGetRasterDataType( myGdalBand );
-
-  switch ( myGdalDataType ) {
+  switch ( theGdalDataType ) {
     case GDT_Unknown:
       return QgsRasterDataProvider::UnknownDataType;
       break;
@@ -953,6 +969,18 @@
   return QgsRasterDataProvider::UnknownDataType;
 }
 
+int QgsGdalProvider::srcDataType( int bandNo ) const
+{
+  GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, bandNo ); 
+  GDALDataType myGdalDataType = GDALGetRasterDataType( myGdalBand );
+  return dataTypeFormGdal ( myGdalDataType );
+}
+
+int QgsGdalProvider::dataType( int bandNo ) const
+{
+  return dataTypeFormGdal ( mGdalDataType[bandNo] );
+}
+
 int QgsGdalProvider::bandCount() const
 {
   return GDALGetRasterCount( mGdalDataset);

Modified: branches/raster-providers/src/providers/gdal/qgsgdalprovider.h
===================================================================
--- branches/raster-providers/src/providers/gdal/qgsgdalprovider.h	2011-02-20 14:55:35 UTC (rev 15217)
+++ branches/raster-providers/src/providers/gdal/qgsgdalprovider.h	2011-02-20 15:11:59 UTC (rev 15218)
@@ -187,7 +187,10 @@
     int capabilities() const;
 
     int dataType ( int bandNo ) const;
+    int srcDataType ( int bandNo ) const;
 
+    int dataTypeFormGdal ( int theGdalDataType ) const;
+
     int bandCount() const;
 
     int colorInterpretation ( int bandNo ) const;
@@ -264,10 +267,9 @@
     /** \brief Whether this raster has overviews / pyramids or not */
     bool mHasPyramids;
 
-    QString mGisdbase;      // map gisdabase
-    QString mLocation;      // map location name (not path!)
-    QString mMapset;        // map mapset
-    QString mMapName;       // map name
+    /** \brief Gdal data types used to represent data in in QGIS, 
+               may be longer than source data type to keep nulls */
+    QList<int>mGdalDataType;
 
     QgsRectangle mExtent;
     int mWidth;



More information about the QGIS-commit mailing list