23 #include "cpl_string.h"
24 #include <QProgressDialog>
27 #if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1800
28 #define TO8F(x) (x).toUtf8().constData()
30 #define TO8F(x) QFile::encodeName( x ).constData()
34 : mRasterFilePath( rasterFile )
35 , mRasterBand( rasterBand )
36 , mPolygonLayer( polygonLayer )
37 , mAttributePrefix( attributePrefix )
38 , mInputNodataValue( -1 )
63 if ( !vectorProvider )
71 if ( inputDataset == NULL )
76 if ( GDALGetRasterCount( inputDataset ) < (
mRasterBand - 1 ) )
78 GDALClose( inputDataset );
82 GDALRasterBandH rasterBand = GDALGetRasterBand( inputDataset,
mRasterBand );
83 if ( rasterBand == NULL )
85 GDALClose( inputDataset );
91 int nCellsXGDAL = GDALGetRasterXSize( inputDataset );
92 int nCellsYGDAL = GDALGetRasterYSize( inputDataset );
93 double geoTransform[6];
94 if ( GDALGetGeoTransform( inputDataset, geoTransform ) != CE_None )
96 GDALClose( inputDataset );
99 double cellsizeX = geoTransform[1];
102 cellsizeX = -cellsizeX;
104 double cellsizeY = geoTransform[5];
107 cellsizeY = -cellsizeY;
109 QgsRectangle rasterBBox( geoTransform[0], geoTransform[3] - ( nCellsYGDAL * cellsizeY ),
110 geoTransform[0] + ( nCellsXGDAL * cellsizeX ), geoTransform[3] );
113 QList<QgsField> newFieldList;
117 QgsField countField( countFieldName, QVariant::Double,
"double precision" );
118 QgsField sumField( sumFieldName, QVariant::Double,
"double precision" );
119 QgsField meanField( meanFieldName, QVariant::Double,
"double precision" );
120 newFieldList.push_back( countField );
121 newFieldList.push_back( sumField );
122 newFieldList.push_back( meanField );
126 int countIndex = vectorProvider->
fieldNameIndex( countFieldName );
130 if ( countIndex == -1 || sumIndex == -1 || meanIndex == -1 )
139 p->setMaximum( featureCount );
151 int featureCounter = 0;
157 p->setValue( featureCounter );
160 if ( p && p->wasCanceled() )
166 if ( !featureGeometry )
179 int offsetX, offsetY, nCellsX, nCellsY;
180 if (
cellInfoForBBox( rasterBBox, featureRect, cellsizeX, cellsizeY, offsetX, offsetY, nCellsX, nCellsY ) != 0 )
187 if (( offsetX + nCellsX ) > nCellsXGDAL )
189 nCellsX = nCellsXGDAL - offsetX;
191 if (( offsetY + nCellsY ) > nCellsYGDAL )
193 nCellsY = nCellsYGDAL - offsetY;
197 rasterBBox, sum, count );
203 rasterBBox, sum, count );
219 changeAttributeMap.insert( countIndex, QVariant( count ) );
220 changeAttributeMap.insert( sumIndex, QVariant( sum ) );
221 changeAttributeMap.insert( meanIndex, QVariant( mean ) );
222 changeMap.insert( f.
id(), changeAttributeMap );
230 p->setValue( featureCount );
233 GDALClose( inputDataset );
236 if ( p && p->wasCanceled() )
245 int& offsetX,
int& offsetY,
int& nCellsX,
int& nCellsY )
const
251 nCellsX = 0; nCellsY = 0; offsetX = 0; offsetY = 0;
256 offsetX = ( int )(( intersectBox.
xMinimum() - rasterBBox.
xMinimum() ) / cellSizeX );
257 offsetY = ( int )(( rasterBBox.
yMaximum() - intersectBox.
yMaximum() ) / cellSizeY );
259 int maxColumn = ( int )(( intersectBox.
xMaximum() - rasterBBox.
xMinimum() ) / cellSizeX ) + 1;
260 int maxRow = ( int )(( rasterBBox.
yMaximum() - intersectBox.
yMinimum() ) / cellSizeY ) + 1;
262 nCellsX = maxColumn - offsetX;
263 nCellsY = maxRow - offsetY;
269 int pixelOffsetY,
int nCellsX,
int nCellsY,
double cellSizeX,
double cellSizeY,
const QgsRectangle& rasterBBox,
double& sum,
double& count )
271 double cellCenterX, cellCenterY;
273 float* scanLine = (
float * ) CPLMalloc(
sizeof(
float ) * nCellsX );
274 cellCenterY = rasterBBox.
yMaximum() - pixelOffsetY * cellSizeY - cellSizeY / 2;
278 const GEOSGeometry* polyGeos = poly->
asGeos();
284 const GEOSPreparedGeometry* polyGeosPrepared = GEOSPrepare( poly->
asGeos() );
285 if ( !polyGeosPrepared )
290 GEOSCoordSequence* cellCenterCoords = 0;
291 GEOSGeometry* currentCellCenter = 0;
293 for (
int i = 0; i < nCellsY; ++i )
295 if ( GDALRasterIO( band, GF_Read, pixelOffsetX, pixelOffsetY + i, nCellsX, 1, scanLine, nCellsX, 1, GDT_Float32, 0, 0 )
300 cellCenterX = rasterBBox.
xMinimum() + pixelOffsetX * cellSizeX + cellSizeX / 2;
301 for (
int j = 0; j < nCellsX; ++j )
303 GEOSGeom_destroy( currentCellCenter );
304 cellCenterCoords = GEOSCoordSeq_create( 1, 2 );
305 GEOSCoordSeq_setX( cellCenterCoords, 0, cellCenterX );
306 GEOSCoordSeq_setY( cellCenterCoords, 0, cellCenterY );
307 currentCellCenter = GEOSGeom_createPoint( cellCenterCoords );
311 if ( GEOSPreparedContains( polyGeosPrepared, currentCellCenter ) )
313 if ( !qIsNaN( scanLine[j] ) )
320 cellCenterX += cellSizeX;
322 cellCenterY -= cellSizeY;
325 GEOSPreparedGeom_destroy( polyGeosPrepared );
329 int pixelOffsetY,
int nCellsX,
int nCellsY,
double cellSizeX,
double cellSizeY,
const QgsRectangle& rasterBBox,
double& sum,
double& count )
333 double currentY = rasterBBox.
yMaximum() - pixelOffsetY * cellSizeY - cellSizeY / 2;
334 float* pixelData = (
float * ) CPLMalloc(
sizeof(
float ) );
337 double hCellSizeX = cellSizeX / 2.0;
338 double hCellSizeY = cellSizeY / 2.0;
339 double pixelArea = cellSizeX * cellSizeY;
342 for (
int row = 0; row < nCellsY; ++row )
344 double currentX = rasterBBox.
xMinimum() + cellSizeX / 2.0 + pixelOffsetX * cellSizeX;
345 for (
int col = 0; col < nCellsX; ++col )
347 GDALRasterIO( band, GF_Read, pixelOffsetX + col, pixelOffsetY + row, nCellsX, 1, pixelData, 1, 1, GDT_Float32, 0, 0 );
349 if ( pixelRectGeometry )
353 if ( intersectGeometry )
355 double intersectionArea = intersectGeometry->
area();
356 if ( intersectionArea >= 0.0 )
358 weight = intersectionArea / pixelArea;
360 sum += *pixelData * weight;
362 delete intersectGeometry;
365 currentX += cellSizeX;
367 currentY -= cellSizeY;
369 CPLFree( pixelData );
376 if ( !dp->
storageType().contains(
"ESRI Shapefile" ) )
382 QString shortName = fieldName.mid( 0, 10 );
385 for (
int idx = 0; idx < providerFields.
count(); ++idx )
387 if ( shortName == providerFields[idx].name() )
400 shortName = QString(
"%1_%2" ).arg( fieldName.mid( 0, 8 ) ).arg( n );
405 for (
int idx = 0; idx < providerFields.
count(); ++idx )
407 if ( shortName == providerFields[idx].name() )
412 shortName = QString(
"%1_%2" ).arg( fieldName.mid( 0, 8 ) ).arg( n );
416 shortName = QString(
"%1_%2" ).arg( fieldName.mid( 0, 7 ) ).arg( n );