@@ -1089,7 +1089,19 @@ QgsRasterIdentifyResult QgsGdalProvider::identify( const QgsPointXY &point, QgsR
1089
1089
return QgsRasterIdentifyResult ( QgsRaster::IdentifyFormatValue, results );
1090
1090
}
1091
1091
1092
- QVariant QgsGdalProvider::sample ( const QgsPointXY &point, int band, const QgsRectangle &boundingBox, int width, int height, int )
1092
+ bool QgsGdalProvider::worldToPixel ( double x, double y, int &col, int &row ) const
1093
+ {
1094
+ double div = ( mGeoTransform [2 ] * mGeoTransform [4 ] - mGeoTransform [1 ] * mGeoTransform [5 ] );
1095
+ if ( div < 2 * std::numeric_limits<double >::epsilon () )
1096
+ return false ;
1097
+ double doubleCol = -( mGeoTransform [2 ] * ( mGeoTransform [3 ] - y ) + mGeoTransform [5 ] * x - mGeoTransform [0 ] * mGeoTransform [5 ] ) / div;
1098
+ double doubleRow = ( mGeoTransform [1 ] * ( mGeoTransform [3 ] - y ) + mGeoTransform [4 ] * x - mGeoTransform [0 ] * mGeoTransform [4 ] ) / div;
1099
+ col = static_cast < int >( doubleCol );
1100
+ row = static_cast < int >( doubleRow );
1101
+ return true ;
1102
+ };
1103
+
1104
+ QVariant QgsGdalProvider::sample ( const QgsPointXY &point, int band, const QgsRectangle &, int , int , int )
1093
1105
{
1094
1106
QMutexLocker locker ( mpMutex );
1095
1107
if ( !initIfNeeded () )
@@ -1101,60 +1113,22 @@ QVariant QgsGdalProvider::sample( const QgsPointXY &point, int band, const QgsRe
1101
1113
return QVariant ();
1102
1114
}
1103
1115
1104
- QgsRectangle finalExtent = boundingBox;
1105
- if ( finalExtent.isEmpty () )
1106
- finalExtent = extent ();
1107
-
1108
- if ( width == 0 )
1109
- width = xSize ();
1110
- if ( height == 0 )
1111
- height = ySize ();
1112
-
1113
- // Calculate the row / column where the point falls
1114
- double xres = ( finalExtent.width () ) / width;
1115
- double yres = ( finalExtent.height () ) / height;
1116
-
1117
- // Offset, not the cell index -> std::floor
1118
- int col = static_cast < int >( std::floor ( ( point.x () - finalExtent.xMinimum () ) / xres ) );
1119
- int row = static_cast < int >( std::floor ( ( finalExtent.yMaximum () - point.y () ) / yres ) );
1120
-
1121
- int r = 0 ;
1122
- int c = 0 ;
1123
- int w = 1 ;
1124
- int h = 1 ;
1125
-
1126
- double xMin = finalExtent.xMinimum () + col * xres;
1127
- double xMax = xMin + xres * w;
1128
- double yMax = finalExtent.yMaximum () - row * yres;
1129
- double yMin = yMax - yres * h;
1130
- QgsRectangle pixelExtent ( xMin, yMin, xMax, yMax );
1131
-
1132
- std::unique_ptr< QgsRasterBlock > bandBlock ( block ( band, pixelExtent, w, h ) );
1116
+ GDALRasterBandH hBand = GDALGetRasterBand ( mGdalDataset , band );
1117
+ if ( !hBand )
1118
+ return QVariant ();
1133
1119
1134
- if ( !bandBlock )
1135
- {
1136
- return tr ( " Cannot read data " );
1137
- }
1120
+ int row;
1121
+ int col;
1122
+ if ( ! worldToPixel ( point. x (), point. y (), col, row ) )
1123
+ return QVariant ();
1138
1124
1139
- double value = bandBlock->value ( r, c );
1125
+ float value = 0 ;
1126
+ CPLErr err = GDALRasterIO ( hBand, GF_Read, col, row, 1 , 1 ,
1127
+ &value, 1 , 1 , GDT_Float32, 0 , 0 );
1128
+ if ( err != CE_None )
1129
+ return QVariant ();
1140
1130
1141
- if ( ( sourceHasNoDataValue ( band ) && useSourceNoDataValue ( band ) &&
1142
- ( std::isnan ( value ) || qgsDoubleNear ( value, sourceNoDataValue ( band ) ) ) ) ||
1143
- ( QgsRasterRange::contains ( value, userNoDataValues ( band ) ) ) )
1144
- {
1145
- return QVariant (); // null QVariant represents no data
1146
- }
1147
- else
1148
- {
1149
- if ( sourceDataType ( band ) == Qgis::Float32 )
1150
- {
1151
- // Insert a float QVariant so that QgsMapToolIdentify::identifyRasterLayer()
1152
- // can print a string without an excessive precision
1153
- return static_cast <float >( value );
1154
- }
1155
- else
1156
- return value;
1157
- }
1131
+ return static_cast < double >( value ) * bandScale ( band ) + bandOffset ( band );
1158
1132
}
1159
1133
1160
1134
int QgsGdalProvider::capabilities () const
0 commit comments