QgsGeometry QgsMapToolDeleteRing::ringUnderPoint( const QgsPoint &p, QgsFeatureId &fid, int &partNum, int &ringNum ) { //There is no clean way to find if we are inside the ring of a feature, //so we iterate over all the features visible in the canvas //If several rings are found at this position, the smallest one is chosen, //in order to be able to delete a ring inside another ring QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFilterRect( toLayerCoordinates( vlayer, mCanvas->extent() ) ) ); QgsFeature f; QgsGeometry g; QgsGeometry ringGeom; QgsMultiPolygon pol; QgsPolygon tempPol; QgsGeometry tempGeom; double area = std::numeric_limits<double>::max(); while ( fit.nextFeature( f ) ) { g = f.geometry(); if ( g.isNull() ) continue; if ( g.wkbType() == QgsWkbTypes::Polygon || g.wkbType() == QgsWkbTypes::Polygon25D ) { pol = QgsMultiPolygon() << g.asPolygon(); } else { pol = g.asMultiPolygon(); } for ( int i = 0; i < pol.size() ; ++i ) { //for each part if ( pol[i].size() > 1 ) { for ( int j = 1; j < pol[i].size(); ++j ) { tempPol = QgsPolygon() << pol[i][j]; tempGeom = QgsGeometry::fromPolygon( tempPol ); if ( tempGeom.area() < area && tempGeom.contains( &p ) ) { fid = f.id(); partNum = i; ringNum = j; area = tempGeom.area(); ringGeom = tempGeom; } } } } } return ringGeom; }
void QgsZonalStatistics::statisticsFromPreciseIntersection( const QgsGeometry &poly, int pixelOffsetX, int pixelOffsetY, int nCellsX, int nCellsY, double cellSizeX, double cellSizeY, const QgsRectangle &rasterBBox, FeatureStats &stats ) { stats.reset(); double currentY = rasterBBox.yMaximum() - pixelOffsetY * cellSizeY - cellSizeY / 2; QgsGeometry pixelRectGeometry; double hCellSizeX = cellSizeX / 2.0; double hCellSizeY = cellSizeY / 2.0; double pixelArea = cellSizeX * cellSizeY; double weight = 0; QgsRectangle featureBBox = poly.boundingBox().intersect( &rasterBBox ); QgsRectangle intersectBBox = rasterBBox.intersect( &featureBBox ); QgsRasterBlock *block = mRasterProvider->block( mRasterBand, intersectBBox, nCellsX, nCellsY ); for ( int i = 0; i < nCellsY; ++i ) { double currentX = rasterBBox.xMinimum() + cellSizeX / 2.0 + pixelOffsetX * cellSizeX; for ( int j = 0; j < nCellsX; ++j ) { if ( !validPixel( block->value( i, j ) ) ) { continue; } pixelRectGeometry = QgsGeometry::fromRect( QgsRectangle( currentX - hCellSizeX, currentY - hCellSizeY, currentX + hCellSizeX, currentY + hCellSizeY ) ); if ( !pixelRectGeometry.isNull() ) { //intersection QgsGeometry intersectGeometry = pixelRectGeometry.intersection( poly ); if ( !intersectGeometry.isNull() ) { double intersectionArea = intersectGeometry.area(); if ( intersectionArea >= 0.0 ) { weight = intersectionArea / pixelArea; stats.addValue( block->value( i, j ), weight ); } } pixelRectGeometry = QgsGeometry(); } currentX += cellSizeX; } currentY -= cellSizeY; } delete block; }
void QgsZonalStatistics::statisticsFromPreciseIntersection( void* band, const QgsGeometry* poly, int pixelOffsetX, int pixelOffsetY, int nCellsX, int nCellsY, double cellSizeX, double cellSizeY, const QgsRectangle& rasterBBox, FeatureStats &stats ) { stats.reset(); double currentY = rasterBBox.yMaximum() - pixelOffsetY * cellSizeY - cellSizeY / 2; float* pixelData = ( float * ) CPLMalloc( sizeof( float ) ); QgsGeometry* pixelRectGeometry = nullptr; double hCellSizeX = cellSizeX / 2.0; double hCellSizeY = cellSizeY / 2.0; double pixelArea = cellSizeX * cellSizeY; double weight = 0; for ( int row = 0; row < nCellsY; ++row ) { double currentX = rasterBBox.xMinimum() + cellSizeX / 2.0 + pixelOffsetX * cellSizeX; for ( int col = 0; col < nCellsX; ++col ) { if ( GDALRasterIO( band, GF_Read, pixelOffsetX + col, pixelOffsetY + row, nCellsX, 1, pixelData, 1, 1, GDT_Float32, 0, 0 ) != CE_None ) QgsDebugMsg( "Raster IO Error" ); if ( !validPixel( *pixelData ) ) continue; pixelRectGeometry = QgsGeometry::fromRect( QgsRectangle( currentX - hCellSizeX, currentY - hCellSizeY, currentX + hCellSizeX, currentY + hCellSizeY ) ); if ( pixelRectGeometry ) { //intersection QgsGeometry *intersectGeometry = pixelRectGeometry->intersection( poly ); if ( intersectGeometry ) { double intersectionArea = intersectGeometry->area(); if ( intersectionArea >= 0.0 ) { weight = intersectionArea / pixelArea; stats.addValue( *pixelData, weight ); } delete intersectGeometry; } delete pixelRectGeometry; pixelRectGeometry = nullptr; } currentX += cellSizeX; } currentY -= cellSizeY; } CPLFree( pixelData ); }
void QgsZonalStatistics::statisticsFromPreciseIntersection( void* band, QgsGeometry* poly, int pixelOffsetX, int pixelOffsetY, int nCellsX, int nCellsY, double cellSizeX, double cellSizeY, const QgsRectangle& rasterBBox, double& sum, double& count ) { sum = 0; count = 0; double currentY = rasterBBox.yMaximum() - pixelOffsetY * cellSizeY - cellSizeY / 2; float* pixelData = ( float * ) CPLMalloc( sizeof( float ) ); QgsGeometry* pixelRectGeometry = 0; double hCellSizeX = cellSizeX / 2.0; double hCellSizeY = cellSizeY / 2.0; double pixelArea = cellSizeX * cellSizeY; double weight = 0; for ( int row = 0; row < nCellsY; ++row ) { double currentX = rasterBBox.xMinimum() + cellSizeX / 2.0 + pixelOffsetX * cellSizeX; for ( int col = 0; col < nCellsX; ++col ) { GDALRasterIO( band, GF_Read, pixelOffsetX + col, pixelOffsetY + row, nCellsX, 1, pixelData, 1, 1, GDT_Float32, 0, 0 ); pixelRectGeometry = QgsGeometry::fromRect( QgsRectangle( currentX - hCellSizeX, currentY - hCellSizeY, currentX + hCellSizeX, currentY + hCellSizeY ) ); if ( pixelRectGeometry ) { //intersection QgsGeometry *intersectGeometry = pixelRectGeometry->intersection( poly ); if ( intersectGeometry ) { double intersectionArea = intersectGeometry->area(); if ( intersectionArea >= 0.0 ) { weight = intersectionArea / pixelArea; count += weight; sum += *pixelData * weight; } delete intersectGeometry; } delete pixelRectGeometry; pixelRectGeometry = 0; } currentX += cellSizeX; } currentY -= cellSizeY; } CPLFree( pixelData ); }