void ECWThread::run() { try{ GDALDataset *poSrcDS = (GDALDataset *)GDALOpen(TO8F(inputPath),GA_ReadOnly); if (poSrcDS==NULL) throw tr("Open input file failed!"); if (poSrcDS->GetRasterBand(1)->GetRasterDataType()!=GDT_Byte) throw tr("Data type of input file is not byte!"); GDALDriver *poDriver = GetGDALDriverManager()->GetDriverByName("JP2ECW"); if (poDriver == NULL) throw tr("Data driver of ECW not found!"); char **papszOptions = NULL; papszOptions = CSLSetNameValue( papszOptions, "LARGE_OK", "YES" ); // papszOptions = CSLSetNameValue( papszOptions, "TARGET", "0" ); GDALDataset *poDstDS = poDriver->CreateCopy(TO8F(outputPath),poSrcDS,NULL,papszOptions,progress,this); if (poDstDS==NULL) throw tr("Generate ecw file failed!"); GDALClose(poSrcDS); GDALClose(poDstDS); updateProgressBar(100); } catch (const QString &msg) { qDebug()<<msg; } }
bool QgsOgrLayerItem::setCrs( QgsCoordinateReferenceSystem crs ) { QgsDebugMsg( "mPath = " + mPath ); OGRRegisterAll(); OGRSFDriverH hDriver; OGRDataSourceH hDataSource = OGROpen( TO8F( mPath ), true, &hDriver ); if ( !hDataSource ) return false; QString driverName = OGR_Dr_GetName( hDriver ); OGR_DS_Destroy( hDataSource ); // we are able to assign CRS only to shapefiles :-( if ( driverName == "ESRI Shapefile" ) { QString layerName = mPath.left( mPath.indexOf( ".shp", Qt::CaseInsensitive ) ); QString wkt = crs.toWkt(); // save ordinary .prj file OGRSpatialReferenceH hSRS = OSRNewSpatialReference( wkt.toLocal8Bit().data() ); OSRMorphToESRI( hSRS ); // this is the important stuff for shapefile .prj char* pszOutWkt = NULL; OSRExportToWkt( hSRS, &pszOutWkt ); QFile prjFile( layerName + ".prj" ); if ( prjFile.open( QIODevice::WriteOnly ) ) { QTextStream prjStream( &prjFile ); prjStream << pszOutWkt << endl; prjFile.close(); } else { QgsMessageLog::logMessage( tr( "Couldn't open file %1.prj" ).arg( layerName ), tr( "OGR" ) ); return false; } OSRDestroySpatialReference( hSRS ); CPLFree( pszOutWkt ); // save qgis-specific .qpj file (maybe because of better wkt compatibility?) QFile qpjFile( layerName + ".qpj" ); if ( qpjFile.open( QIODevice::WriteOnly ) ) { QTextStream qpjStream( &qpjFile ); qpjStream << wkt.toLocal8Bit().data() << endl; qpjFile.close(); } else { QgsMessageLog::logMessage( tr( "Couldn't open file %1.qpj" ).arg( layerName ), tr( "OGR" ) ); return false; } return true; } // It it is impossible to assign a crs to an existing layer // No OGR_L_SetSpatialRef : http://trac.osgeo.org/gdal/ticket/4032 return false; }
QgsShapeFile::QgsShapeFile( QString name, QString encoding ) { fileName = name; features = 0; QgsApplication::registerOgrDrivers(); QSettings settings; CPLSetConfigOption( "SHAPE_ENCODING", settings.value( "/qgis/ignoreShapeEncoding", true ).toBool() ? "" : 0 ); ogrDataSource = OGROpen( TO8F( fileName ), false, NULL ); if ( ogrDataSource != NULL ) { valid = true; ogrLayer = OGR_DS_GetLayer( ogrDataSource, 0 ); features = OGR_L_GetFeatureCount( ogrLayer, true ); } else valid = false; setDefaultTable(); // init the geometry types geometries << "NULL" << "POINT" << "LINESTRING" << "POLYGON" << "MULTIPOINT" << "MULTILINESTRING" << "MULTIPOLYGON" << "GEOMETRYCOLLECTION"; codec = QTextCodec::codecForName( encoding.toLocal8Bit().constData() ); if ( !codec ) codec = QTextCodec::codecForLocale(); Q_ASSERT( codec ); }
bool QgsImageWarper::openSrcDSAndGetWarpOpt( const QString &input, const ResamplingMethod &resampling, const GDALTransformerFunc &pfnTransform, GDALDatasetH &hSrcDS, GDALWarpOptions *&psWarpOptions ) { // Open input file GDALAllRegister(); hSrcDS = GDALOpen( TO8F( input ), GA_ReadOnly ); if ( !hSrcDS ) return false; // Setup warp options. psWarpOptions = GDALCreateWarpOptions(); psWarpOptions->hSrcDS = hSrcDS; psWarpOptions->nBandCount = GDALGetRasterCount( hSrcDS ); psWarpOptions->panSrcBands = ( int * ) CPLMalloc( sizeof( int ) * psWarpOptions->nBandCount ); psWarpOptions->panDstBands = ( int * ) CPLMalloc( sizeof( int ) * psWarpOptions->nBandCount ); for ( int i = 0; i < psWarpOptions->nBandCount; ++i ) { psWarpOptions->panSrcBands[i] = i + 1; psWarpOptions->panDstBands[i] = i + 1; } psWarpOptions->pfnProgress = GDALTermProgress; psWarpOptions->pfnTransformer = pfnTransform; psWarpOptions->eResampleAlg = GDALResampleAlg( resampling ); return true; }
QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrFeatureSource* source, bool ownSource, const QgsFeatureRequest& request ) : QgsAbstractFeatureIteratorFromSource<QgsOgrFeatureSource>( source, ownSource, request ) , ogrDataSource( 0 ) , ogrLayer( 0 ) , mSubsetStringSet( false ) , mGeometrySimplifier( NULL ) { mFeatureFetched = false; ogrDataSource = OGROpen( TO8F( mSource->mFilePath ), false, NULL ); if ( mSource->mLayerName.isNull() ) { ogrLayer = OGR_DS_GetLayer( ogrDataSource, mSource->mLayerIndex ); } else { ogrLayer = OGR_DS_GetLayerByName( ogrDataSource, TO8( mSource->mLayerName ) ); } if ( !mSource->mSubsetString.isEmpty() ) { ogrLayer = QgsOgrUtils::setSubsetString( ogrLayer, ogrDataSource, mSource->mEncoding, mSource->mSubsetString ); mSubsetStringSet = true; } mFetchGeometry = ( mRequest.filterType() == QgsFeatureRequest::FilterRect ) || !( mRequest.flags() & QgsFeatureRequest::NoGeometry ); QgsAttributeList attrs = ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) ? mRequest.subsetOfAttributes() : mSource->mFields.allAttributesList(); // make sure we fetch just relevant fields // unless it's a VRT data source filtered by geometry as we don't know which // attributes make up the geometry and OGR won't fetch them to evaluate the // filter if we choose to ignore them (fixes #11223) if (( mSource->mDriverName != "VRT" && mSource->mDriverName != "OGR_VRT" ) || mRequest.filterType() != QgsFeatureRequest::FilterRect ) { QgsOgrUtils::setRelevantFields( ogrLayer, mSource->mFields.count(), mFetchGeometry, attrs ); } // spatial query to select features if ( mRequest.filterType() == QgsFeatureRequest::FilterRect ) { OGRGeometryH filter = 0; QString wktExtent = QString( "POLYGON((%1))" ).arg( mRequest.filterRect().asPolygon() ); QByteArray ba = wktExtent.toAscii(); const char *wktText = ba; OGR_G_CreateFromWkt(( char ** )&wktText, NULL, &filter ); QgsDebugMsg( "Setting spatial filter using " + wktExtent ); OGR_L_SetSpatialFilter( ogrLayer, filter ); OGR_G_DestroyGeometry( filter ); } else { OGR_L_SetSpatialFilter( ogrLayer, 0 ); } //start with first feature rewind(); }
QgsLayerItem::Capability QgsGdalLayerItem::capabilities() { // Check if data source can be opened for update QgsDebugMsg( "mPath = " + mPath ); GDALAllRegister(); GDALDatasetH hDS = GDALOpen( TO8F( mPath ), GA_Update ); if ( !hDS ) return NoCapabilities; return SetCrs; }
QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrProvider* p, const QgsFeatureRequest& request ) : QgsAbstractFeatureIterator( request ) , P( p ) , ogrDataSource( 0 ) , ogrLayer( 0 ) , mSubsetStringSet( false ) , mGeometrySimplifier( NULL ) { mFeatureFetched = false; ogrDataSource = OGROpen( TO8F( P->filePath() ), false, NULL ); if ( P->layerName().isNull() ) { ogrLayer = OGR_DS_GetLayer( ogrDataSource, P->layerIndex() ); } else { ogrLayer = OGR_DS_GetLayerByName( ogrDataSource, TO8( p->layerName() ) ); } if ( !P->subsetString().isEmpty() ) { ogrLayer = P->setSubsetString( ogrLayer, ogrDataSource ); mSubsetStringSet = true; } ensureRelevantFields(); // spatial query to select features if ( mRequest.filterType() == QgsFeatureRequest::FilterRect ) { OGRGeometryH filter = 0; QString wktExtent = QString( "POLYGON((%1))" ).arg( mRequest.filterRect().asPolygon() ); QByteArray ba = wktExtent.toAscii(); const char *wktText = ba; OGR_G_CreateFromWkt(( char ** )&wktText, NULL, &filter ); QgsDebugMsg( "Setting spatial filter using " + wktExtent ); OGR_L_SetSpatialFilter( ogrLayer, filter ); OGR_G_DestroyGeometry( filter ); } else { OGR_L_SetSpatialFilter( ogrLayer, 0 ); } //start with first feature rewind(); }
GDALDatasetH QgsRelief::openOutputFile( GDALDatasetH inputDataset, GDALDriverH outputDriver ) { if ( inputDataset == NULL ) { return NULL; } int xSize = GDALGetRasterXSize( inputDataset ); int ySize = GDALGetRasterYSize( inputDataset );; //open output file char **papszOptions = NULL; //use PACKBITS compression for tiffs by default papszOptions = CSLSetNameValue( papszOptions, "COMPRESS", "PACKBITS" ); //create three band raster (reg, green, blue) GDALDatasetH outputDataset = GDALCreate( outputDriver, TO8F( mOutputFile ), xSize, ySize, 3, GDT_Byte, papszOptions ); if ( outputDataset == NULL ) { return outputDataset; } //get geotransform from inputDataset double geotransform[6]; if ( GDALGetGeoTransform( inputDataset, geotransform ) != CE_None ) { GDALClose( outputDataset ); return NULL; } GDALSetGeoTransform( outputDataset, geotransform ); //make sure mCellSizeX and mCellSizeY are always > 0 mCellSizeX = geotransform[1]; if ( mCellSizeX < 0 ) { mCellSizeX = -mCellSizeX; } mCellSizeY = geotransform[5]; if ( mCellSizeY < 0 ) { mCellSizeY = -mCellSizeY; } const char* projection = GDALGetProjectionRef( inputDataset ); GDALSetProjection( outputDataset, projection ); return outputDataset; }
//duplicated from QgsNineCellFilter. Todo: make common base class GDALDatasetH QgsRelief::openInputFile( int& nCellsX, int& nCellsY ) { GDALDatasetH inputDataset = GDALOpen( TO8F( mInputFile ), GA_ReadOnly ); if ( inputDataset != NULL ) { nCellsX = GDALGetRasterXSize( inputDataset ); nCellsY = GDALGetRasterYSize( inputDataset ); //we need at least one band if ( GDALGetRasterCount( inputDataset ) < 1 ) { GDALClose( inputDataset ); return NULL; } } return inputDataset; }
GDALDatasetH QgsRasterCalculator::openOutputFile( GDALDriverH outputDriver ) { //open output file char **papszOptions = nullptr; GDALDatasetH outputDataset = GDALCreate( outputDriver, TO8F( mOutputFile ), mNumOutputColumns, mNumOutputRows, 1, GDT_Float32, papszOptions ); if ( !outputDataset ) { return outputDataset; } //assign georef information double geotransform[6]; outputGeoTransform( geotransform ); GDALSetGeoTransform( outputDataset, geotransform ); return outputDataset; }
QgsLayerItem::Capability QgsOgrLayerItem::capabilities() { QgsDebugMsg( "mPath = " + mPath ); OGRRegisterAll(); OGRSFDriverH hDriver; OGRDataSourceH hDataSource = OGROpen( TO8F( mPath ), true, &hDriver ); if ( !hDataSource ) return NoCapabilities; QString driverName = OGR_Dr_GetName( hDriver ); OGR_DS_Destroy( hDataSource ); if ( driverName == "ESRI Shapefile" ) return SetCrs; return NoCapabilities; }
bool QgsGdalLayerItem::setCrs( QgsCoordinateReferenceSystem crs ) { QgsDebugMsg( "mPath = " + mPath ); GDALAllRegister(); GDALDatasetH hDS = GDALOpen( TO8F( mPath ), GA_Update ); if ( !hDS ) return false; QString wkt = crs.toWkt(); if ( GDALSetProjection( hDS, wkt.toLocal8Bit().data() ) != CE_None ) { QgsDebugMsg( "Could not set CRS" ); return false; } GDALClose( hDS ); return true; }
GDALDatasetH QgsNineCellFilter::openOutputFile( GDALDatasetH inputDataset, GDALDriverH outputDriver ) { if ( inputDataset == NULL ) { return NULL; } int xSize = GDALGetRasterXSize( inputDataset ); int ySize = GDALGetRasterYSize( inputDataset );; //open output file char **papszOptions = NULL; GDALDatasetH outputDataset = GDALCreate( outputDriver, TO8F( mOutputFile ), xSize, ySize, 1, GDT_Float32, papszOptions ); if ( outputDataset == NULL ) { return outputDataset; } //get geotransform from inputDataset double geotransform[6]; if ( GDALGetGeoTransform( inputDataset, geotransform ) != CE_None ) { GDALClose( outputDataset ); return NULL; } GDALSetGeoTransform( outputDataset, geotransform ); //make sure mCellSizeX and mCellSizeY are always > 0 mCellSizeX = geotransform[1]; if ( mCellSizeX < 0 ) { mCellSizeX = -mCellSizeX; } mCellSizeY = geotransform[5]; if ( mCellSizeY < 0 ) { mCellSizeY = -mCellSizeY; } const char* projection = GDALGetProjectionRef( inputDataset ); GDALSetProjection( outputDataset, projection ); return outputDataset; }
QVector<QgsDataItem*> QgsOgrDataCollectionItem::createChildren() { QVector<QgsDataItem*> children; OGRSFDriverH hDriver; OGRDataSourceH hDataSource = OGROpen( TO8F( mPath ), false, &hDriver ); if ( !hDataSource ) return children; int numLayers = OGR_DS_GetLayerCount( hDataSource ); for ( int i = 0; i < numLayers; i++ ) { QgsOgrLayerItem* item = dataItemForLayer( this, QString(), mPath, hDataSource, i ); children.append( item ); } OGR_DS_Destroy( hDataSource ); return children; }
void QgsNewOgrConnection::testConnection() { QString uri; uri = createDatabaseURI( cmbDatabaseTypes->currentText(), txtHost->text(), txtDatabase->text(), txtPort->text(), txtUsername->text(), txtPassword->text() ); QgsDebugMsg( "Connecting using uri = " + uri ); OGRRegisterAll(); OGRDataSourceH poDS; OGRSFDriverH pahDriver; CPLErrorReset(); poDS = OGROpen( TO8F( uri ), false, &pahDriver ); if ( poDS == NULL ) { QMessageBox::information( this, tr( "Test connection" ), tr( "Connection failed - Check settings and try again.\n\nExtended error information:\n%1" ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) ) ); } else { QMessageBox::information( this, tr( "Test connection" ), tr( "Connection to %1 was successful" ).arg( uri ) ); OGRReleaseDataSource( poDS ); } }
QgsOgrLayerItem::QgsOgrLayerItem( QgsDataItem* parent, const QString& name, const QString& path, const QString& uri, LayerType layerType ) : QgsLayerItem( parent, name, path, uri, layerType, "ogr" ) { mToolTip = uri; setState( Populated ); // children are not expected OGRRegisterAll(); OGRSFDriverH hDriver; OGRDataSourceH hDataSource = OGROpen( TO8F( mPath ), true, &hDriver ); if ( hDataSource ) { QString driverName = OGR_Dr_GetName( hDriver ); OGR_DS_Destroy( hDataSource ); if ( driverName == "ESRI Shapefile" ) mCapabilities |= SetCrs; // It it is impossible to assign a crs to an existing layer // No OGR_L_SetSpatialRef : http://trac.osgeo.org/gdal/ticket/4032 } }
void QgsOracleSelectGeoraster::showSelection( const QString & line ) { QString identification = line; GDALDatasetH hDS = NULL; GDALAccess eAccess = GA_ReadOnly; /* * Set access mode */ if ( checkBox->checkState() == Qt::Checked ) { eAccess = GA_Update; } /* * Try to open georaster dataset */ hDS = GDALOpenShared( TO8F( identification ), eAccess ); buttonBox->button( QDialogButtonBox::Ok )->setEnabled( false ); if ( hDS == NULL ) { QMessageBox::information( this, tr( "Open failed" ), tr( "The connection to %1 failed. Please verify your connection parameters. Make sure you have the GDAL GeoRaster plugin installed." ) .arg( identification ) ); return; } buttonBox->button( QDialogButtonBox::Ok )->setEnabled( true ); /* * Get subdataset list */ char **papszMetadata = NULL; papszMetadata = GDALGetMetadata( hDS, "SUBDATASETS" ); int nSubDatasets = CSLCount( papszMetadata ); /* * Add GeoRaster Layer */ if ( ! nSubDatasets ) { mIface->addRasterLayer( identification ); GDALClose( hDS ); return; } /* * Save subdataset */ QSettings settings; settings.setValue( "/Oracle/connections/" + cmbConnections->currentText() + "/subdtset", identification ); /* * List subdatasets */ QStringList fields = identification.split( ',' ); QString count = QString::number( nSubDatasets / 2 ); QString plural = "s"; if ( count == "1" ) { plural = ""; } if ( fields.size() < 4 ) { labelStatus->setText( QString( "%1 GeoRaster table%2" ) .arg( count ).arg( plural ) ); checkBox->setEnabled( false ); } else if ( fields.size() == 4 ) { labelStatus->setText( QString( "%1 GeoRaster column%2 on table %3" ) .arg( count ).arg( plural ).arg( fields[3] ) ); checkBox->setEnabled( false ); } else if ( fields.size() == 5 ) { labelStatus->setText( QString( "%1 GeoRaster object%2 on table %3 column %4" ) .arg( count ).arg( plural ).arg( fields[3] ).arg( fields[4] ) ); checkBox->setEnabled( true ); } else { labelStatus->setText( QString( "%1 GeoRaster object%2 on table %3 column %4 where %5" ) .arg( count ).arg( plural ).arg( fields[3] ).arg( fields[4] ).arg( fields[5] ) ); checkBox->setEnabled( true ); } /* * Populate selection list based on subdataset names */ listWidget->clear(); QListWidgetItem *textItem; for ( int i = 0; i < nSubDatasets; i += 2 ) { QString metadata = papszMetadata[i]; QStringList subdataset = metadata.split( '=' ); textItem = new QListWidgetItem( subdataset[1] ); listWidget->addItem( textItem ); } GDALClose( hDS ); }
int QgsRelief::processRaster( QProgressDialog* p ) { //open input file int xSize, ySize; GDALDatasetH inputDataset = openInputFile( xSize, ySize ); if ( inputDataset == NULL ) { return 1; //opening of input file failed } //output driver GDALDriverH outputDriver = openOutputDriver(); if ( outputDriver == 0 ) { return 2; } GDALDatasetH outputDataset = openOutputFile( inputDataset, outputDriver ); if ( outputDataset == NULL ) { return 3; //create operation on output file failed } //initialize dependency filters with cell sizes mHillshadeFilter285->setCellSizeX( mCellSizeX ); mHillshadeFilter285->setCellSizeY( mCellSizeY ); mHillshadeFilter285->setZFactor( mZFactor ); mHillshadeFilter300->setCellSizeX( mCellSizeX ); mHillshadeFilter300->setCellSizeY( mCellSizeY ); mHillshadeFilter300->setZFactor( mZFactor ); mHillshadeFilter315->setCellSizeX( mCellSizeX ); mHillshadeFilter315->setCellSizeY( mCellSizeY ); mHillshadeFilter315->setZFactor( mZFactor ); mSlopeFilter->setCellSizeX( mCellSizeX ); mSlopeFilter->setCellSizeY( mCellSizeY ); mSlopeFilter->setZFactor( mZFactor ); mAspectFilter->setCellSizeX( mCellSizeX ); mAspectFilter->setCellSizeY( mCellSizeY ); mAspectFilter->setZFactor( mZFactor ); //open first raster band for reading (operation is only for single band raster) GDALRasterBandH rasterBand = GDALGetRasterBand( inputDataset, 1 ); if ( rasterBand == NULL ) { GDALClose( inputDataset ); GDALClose( outputDataset ); return 4; } mInputNodataValue = GDALGetRasterNoDataValue( rasterBand, NULL ); mSlopeFilter->setInputNodataValue( mInputNodataValue ); mAspectFilter->setInputNodataValue( mInputNodataValue ); mHillshadeFilter285->setInputNodataValue( mInputNodataValue ); mHillshadeFilter300->setInputNodataValue( mInputNodataValue ); mHillshadeFilter315->setInputNodataValue( mInputNodataValue ); GDALRasterBandH outputRedBand = GDALGetRasterBand( outputDataset, 1 ); GDALRasterBandH outputGreenBand = GDALGetRasterBand( outputDataset, 2 ); GDALRasterBandH outputBlueBand = GDALGetRasterBand( outputDataset, 3 ); if ( outputRedBand == NULL || outputGreenBand == NULL || outputBlueBand == NULL ) { GDALClose( inputDataset ); GDALClose( outputDataset ); return 5; } //try to set -9999 as nodata value GDALSetRasterNoDataValue( outputRedBand, -9999 ); GDALSetRasterNoDataValue( outputGreenBand, -9999 ); GDALSetRasterNoDataValue( outputBlueBand, -9999 ); mOutputNodataValue = GDALGetRasterNoDataValue( outputRedBand, NULL ); mSlopeFilter->setOutputNodataValue( mOutputNodataValue ); mAspectFilter->setOutputNodataValue( mOutputNodataValue ); mHillshadeFilter285->setOutputNodataValue( mOutputNodataValue ); mHillshadeFilter300->setOutputNodataValue( mOutputNodataValue ); mHillshadeFilter315->setOutputNodataValue( mOutputNodataValue ); if ( ySize < 3 ) //we require at least three rows (should be true for most datasets) { GDALClose( inputDataset ); GDALClose( outputDataset ); return 6; } //keep only three scanlines in memory at a time float* scanLine1 = ( float * ) CPLMalloc( sizeof( float ) * xSize ); float* scanLine2 = ( float * ) CPLMalloc( sizeof( float ) * xSize ); float* scanLine3 = ( float * ) CPLMalloc( sizeof( float ) * xSize ); unsigned char* resultRedLine = ( unsigned char * ) CPLMalloc( sizeof( unsigned char ) * xSize ); unsigned char* resultGreenLine = ( unsigned char * ) CPLMalloc( sizeof( unsigned char ) * xSize ); unsigned char* resultBlueLine = ( unsigned char * ) CPLMalloc( sizeof( unsigned char ) * xSize ); if ( p ) { p->setMaximum( ySize ); } bool resultOk; //values outside the layer extent (if the 3x3 window is on the border) are sent to the processing method as (input) nodata values for ( int i = 0; i < ySize; ++i ) { if ( p ) { p->setValue( i ); } if ( p && p->wasCanceled() ) { break; } if ( i == 0 ) { //fill scanline 1 with (input) nodata for the values above the first row and feed scanline2 with the first row for ( int a = 0; a < xSize; ++a ) { scanLine1[a] = mInputNodataValue; } GDALRasterIO( rasterBand, GF_Read, 0, 0, xSize, 1, scanLine2, xSize, 1, GDT_Float32, 0, 0 ); } else { //normally fetch only scanLine3 and release scanline 1 if we move forward one row CPLFree( scanLine1 ); scanLine1 = scanLine2; scanLine2 = scanLine3; scanLine3 = ( float * ) CPLMalloc( sizeof( float ) * xSize ); } if ( i == ySize - 1 ) //fill the row below the bottom with nodata values { for ( int a = 0; a < xSize; ++a ) { scanLine3[a] = mInputNodataValue; } } else { GDALRasterIO( rasterBand, GF_Read, 0, i + 1, xSize, 1, scanLine3, xSize, 1, GDT_Float32, 0, 0 ); } for ( int j = 0; j < xSize; ++j ) { if ( j == 0 ) { resultOk = processNineCellWindow( &mInputNodataValue, &scanLine1[j], &scanLine1[j+1], &mInputNodataValue, &scanLine2[j], \ &scanLine2[j+1], &mInputNodataValue, &scanLine3[j], &scanLine3[j+1], \ &resultRedLine[j], &resultGreenLine[j], &resultBlueLine[j] ); } else if ( j == xSize - 1 ) { resultOk = processNineCellWindow( &scanLine1[j-1], &scanLine1[j], &mInputNodataValue, &scanLine2[j-1], &scanLine2[j], \ &mInputNodataValue, &scanLine3[j-1], &scanLine3[j], &mInputNodataValue, \ &resultRedLine[j], &resultGreenLine[j], &resultBlueLine[j] ); } else { resultOk = processNineCellWindow( &scanLine1[j-1], &scanLine1[j], &scanLine1[j+1], &scanLine2[j-1], &scanLine2[j], \ &scanLine2[j+1], &scanLine3[j-1], &scanLine3[j], &scanLine3[j+1], \ &resultRedLine[j], &resultGreenLine[j], &resultBlueLine[j] ); } if ( !resultOk ) { resultRedLine[j] = mOutputNodataValue; resultGreenLine[j] = mOutputNodataValue; resultBlueLine[j] = mOutputNodataValue; } } GDALRasterIO( outputRedBand, GF_Write, 0, i, xSize, 1, resultRedLine, xSize, 1, GDT_Byte, 0, 0 ); GDALRasterIO( outputGreenBand, GF_Write, 0, i, xSize, 1, resultGreenLine, xSize, 1, GDT_Byte, 0, 0 ); GDALRasterIO( outputBlueBand, GF_Write, 0, i, xSize, 1, resultBlueLine, xSize, 1, GDT_Byte, 0, 0 ); } if ( p ) { p->setValue( ySize ); } CPLFree( resultRedLine ); CPLFree( resultBlueLine ); CPLFree( resultGreenLine ); CPLFree( scanLine1 ); CPLFree( scanLine2 ); CPLFree( scanLine3 ); GDALClose( inputDataset ); if ( p && p->wasCanceled() ) { //delete the dataset without closing (because it is faster) GDALDeleteDataset( outputDriver, TO8F( mOutputFile ) ); return 7; } GDALClose( outputDataset ); return 0; }
// Slot called when the menu item is triggered // If you created more menu items / toolbar buttons in initiGui, you should // create a separate handler for each action - this single run() method will // not be enough void Heatmap::run() { HeatmapGui d( mQGisIface->mainWindow(), QgisGui::ModalDialogFlags, &mSessionSettings ); //check that dialog found a suitable vector layer if ( !d.inputVectorLayer() ) { mQGisIface->messageBar()->pushMessage( tr( "Layer not found" ), tr( "The heatmap plugin requires at least one point vector layer" ), QgsMessageBar::INFO, mQGisIface->messageTimeout() ); return; } if ( d.exec() != QDialog::Accepted ) { return; } QgsVectorLayer* inputLayer = d.inputVectorLayer(); // Get the required data from the dialog QgsRectangle myBBox = d.bbox(); int columns = d.columns(); int rows = d.rows(); double cellsize = d.cellSizeX(); // or d.cellSizeY(); both have the same value mDecay = d.decayRatio(); KernelShape kernelShape = d.kernelShape(); OutputValues valueType = d.outputValues(); //is input layer multipoint? bool isMultiPoint = inputLayer->wkbType() == QGis::WKBMultiPoint || inputLayer->wkbType() == QGis::WKBMultiPoint25D; // Getting the rasterdataset in place GDALAllRegister(); GDALDataset *emptyDataset; GDALDriver *myDriver; myDriver = GetGDALDriverManager()->GetDriverByName( d.outputFormat().toUtf8() ); if ( myDriver == NULL ) { mQGisIface->messageBar()->pushMessage( tr( "GDAL driver error" ), tr( "Cannot open the driver for the specified format" ), QgsMessageBar::WARNING, mQGisIface->messageTimeout() ); return; } double geoTransform[6] = { myBBox.xMinimum(), cellsize, 0, myBBox.yMinimum(), 0, cellsize }; emptyDataset = myDriver->Create( d.outputFilename().toUtf8(), columns, rows, 1, GDT_Float32, NULL ); emptyDataset->SetGeoTransform( geoTransform ); // Set the projection on the raster destination to match the input layer emptyDataset->SetProjection( inputLayer->crs().toWkt().toLocal8Bit().data() ); GDALRasterBand *poBand; poBand = emptyDataset->GetRasterBand( 1 ); poBand->SetNoDataValue( NO_DATA ); float* line = ( float * ) CPLMalloc( sizeof( float ) * columns ); for ( int i = 0; i < columns ; i++ ) { line[i] = NO_DATA; } // Write the empty raster for ( int i = 0; i < rows ; i++ ) { poBand->RasterIO( GF_Write, 0, i, columns, 1, line, columns, 1, GDT_Float32, 0, 0 ); } CPLFree( line ); //close the dataset GDALClose(( GDALDatasetH ) emptyDataset ); // open the raster in GA_Update mode GDALDataset *heatmapDS; heatmapDS = ( GDALDataset * ) GDALOpen( TO8F( d.outputFilename() ), GA_Update ); if ( !heatmapDS ) { mQGisIface->messageBar()->pushMessage( tr( "Raster update error" ), tr( "Could not open the created raster for updating. The heatmap was not generated." ), QgsMessageBar::WARNING ); return; } poBand = heatmapDS->GetRasterBand( 1 ); QgsAttributeList myAttrList; int rField = 0; int wField = 0; // Handle different radius options double radius; double radiusToMapUnits = 1; int myBuffer = 0; if ( d.variableRadius() ) { rField = d.radiusField(); myAttrList.append( rField ); QgsDebugMsg( QString( "Radius Field index received: %1" ).arg( rField ) ); // If not using map units, then calculate a conversion factor to convert the radii to map units if ( d.radiusUnit() == HeatmapGui::Meters ) { radiusToMapUnits = mapUnitsOf( 1, inputLayer->crs() ); } } else { radius = d.radius(); // radius returned by d.radius() is already in map units myBuffer = bufferSize( radius, cellsize ); } if ( d.weighted() ) { wField = d.weightField(); myAttrList.append( wField ); } // This might have attributes or mightnot have attibutes at all // based on the variableRadius() and weighted() QgsFeatureIterator fit = inputLayer->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( myAttrList ) ); int totalFeatures = inputLayer->featureCount(); int counter = 0; QProgressDialog p( tr( "Creating heatmap" ), tr( "Abort" ), 0, totalFeatures, mQGisIface->mainWindow() ); p.setWindowModality( Qt::ApplicationModal ); p.show(); QgsFeature myFeature; while ( fit.nextFeature( myFeature ) ) { counter++; p.setValue( counter ); QApplication::processEvents(); if ( p.wasCanceled() ) { mQGisIface->messageBar()->pushMessage( tr( "Heatmap generation aborted" ), tr( "QGIS will now load the partially-computed raster" ), QgsMessageBar::INFO, mQGisIface->messageTimeout() ); break; } QgsGeometry* featureGeometry = myFeature.geometry(); if ( !featureGeometry ) { continue; } // convert the geometry to multipoint QgsMultiPoint multiPoints; if ( !isMultiPoint ) { QgsPoint myPoint = featureGeometry->asPoint(); // avoiding any empty points or out of extent points if (( myPoint.x() < myBBox.xMinimum() ) || ( myPoint.y() < myBBox.yMinimum() ) || ( myPoint.x() > myBBox.xMaximum() ) || ( myPoint.y() > myBBox.yMaximum() ) ) { continue; } multiPoints << myPoint; } else { multiPoints = featureGeometry->asMultiPoint(); } // If radius is variable then fetch it and calculate new pixel buffer size if ( d.variableRadius() ) { radius = myFeature.attribute( rField ).toDouble() * radiusToMapUnits; myBuffer = bufferSize( radius, cellsize ); } int blockSize = 2 * myBuffer + 1; //Block SIDE would be more appropriate double weight = 1.0; if ( d.weighted() ) { weight = myFeature.attribute( wField ).toDouble(); } //loop through all points in multipoint for ( QgsMultiPoint::const_iterator pointIt = multiPoints.constBegin(); pointIt != multiPoints.constEnd(); ++pointIt ) { // avoiding any empty points or out of extent points if ((( *pointIt ).x() < myBBox.xMinimum() ) || (( *pointIt ).y() < myBBox.yMinimum() ) || (( *pointIt ).x() > myBBox.xMaximum() ) || (( *pointIt ).y() > myBBox.yMaximum() ) ) { continue; } // calculate the pixel position unsigned int xPosition, yPosition; xPosition = ((( *pointIt ).x() - myBBox.xMinimum() ) / cellsize ) - myBuffer; yPosition = ((( *pointIt ).y() - myBBox.yMinimum() ) / cellsize ) - myBuffer; // get the data float *dataBuffer = ( float * ) CPLMalloc( sizeof( float ) * blockSize * blockSize ); poBand->RasterIO( GF_Read, xPosition, yPosition, blockSize, blockSize, dataBuffer, blockSize, blockSize, GDT_Float32, 0, 0 ); for ( int xp = 0; xp <= myBuffer; xp++ ) { for ( int yp = 0; yp <= myBuffer; yp++ ) { double distance = sqrt( pow( xp, 2.0 ) + pow( yp, 2.0 ) ); // is pixel outside search bandwidth of feature? if ( distance > myBuffer ) { continue; } double pixelValue = weight * calculateKernelValue( distance, myBuffer, kernelShape, valueType ); // clearing anamolies along the axes if ( xp == 0 && yp == 0 ) { pixelValue /= 4; } else if ( xp == 0 || yp == 0 ) { pixelValue /= 2; } int pos[4]; pos[0] = ( myBuffer + xp ) * blockSize + ( myBuffer + yp ); pos[1] = ( myBuffer + xp ) * blockSize + ( myBuffer - yp ); pos[2] = ( myBuffer - xp ) * blockSize + ( myBuffer + yp ); pos[3] = ( myBuffer - xp ) * blockSize + ( myBuffer - yp ); for ( int p = 0; p < 4; p++ ) { if ( dataBuffer[ pos[p] ] == NO_DATA ) { dataBuffer[ pos[p] ] = 0; } dataBuffer[ pos[p] ] += pixelValue; } } } poBand->RasterIO( GF_Write, xPosition, yPosition, blockSize, blockSize, dataBuffer, blockSize, blockSize, GDT_Float32, 0, 0 ); CPLFree( dataBuffer ); } } // Finally close the dataset GDALClose(( GDALDatasetH ) heatmapDS ); // Open the file in QGIS window if requested if ( d.addToCanvas() ) { mQGisIface->addRasterLayer( d.outputFilename(), QFileInfo( d.outputFilename() ).baseName() ); } }
bool matches = false; foreach( QString wildcard, wildcards ) { QRegExp rx( wildcard, Qt::CaseInsensitive, QRegExp::Wildcard ); if ( rx.exactMatch( info.fileName() ) ) { matches = true; break; } } if ( !matches ) return 0; } GDALAllRegister(); GDALDatasetH hDS = GDALOpen( TO8F( thePath ), GA_ReadOnly ); if ( !hDS ) return 0; QStringList sublayers = QgsGdalProvider::subLayers( hDS ); GDALClose( hDS ); QgsDebugMsg( "GdalDataset opened " + thePath ); QString name = info.completeBaseName(); QString uri = thePath; QgsLayerItem * item = new QgsGdalLayerItem( parentItem, name, thePath, uri );
int QgsZonalStatistics::calculateStatistics( QProgressDialog* p ) { if ( !mPolygonLayer || mPolygonLayer->geometryType() != QGis::Polygon ) { return 1; } QgsVectorDataProvider* vectorProvider = mPolygonLayer->dataProvider(); if ( !vectorProvider ) { return 2; } //open the raster layer and the raster band GDALAllRegister(); GDALDatasetH inputDataset = GDALOpen( TO8F( mRasterFilePath ), GA_ReadOnly ); if ( !inputDataset ) { return 3; } if ( GDALGetRasterCount( inputDataset ) < ( mRasterBand - 1 ) ) { GDALClose( inputDataset ); return 4; } GDALRasterBandH rasterBand = GDALGetRasterBand( inputDataset, mRasterBand ); if ( !rasterBand ) { GDALClose( inputDataset ); return 5; } mInputNodataValue = GDALGetRasterNoDataValue( rasterBand, nullptr ); //get geometry info about raster layer int nCellsXGDAL = GDALGetRasterXSize( inputDataset ); int nCellsYGDAL = GDALGetRasterYSize( inputDataset ); double geoTransform[6]; if ( GDALGetGeoTransform( inputDataset, geoTransform ) != CE_None ) { GDALClose( inputDataset ); return 6; } double cellsizeX = geoTransform[1]; if ( cellsizeX < 0 ) { cellsizeX = -cellsizeX; } double cellsizeY = geoTransform[5]; if ( cellsizeY < 0 ) { cellsizeY = -cellsizeY; } QgsRectangle rasterBBox( geoTransform[0], geoTransform[3] - ( nCellsYGDAL * cellsizeY ), geoTransform[0] + ( nCellsXGDAL * cellsizeX ), geoTransform[3] ); //add the new fields to the provider QList<QgsField> newFieldList; QString countFieldName; if ( mStatistics & QgsZonalStatistics::Count ) { countFieldName = getUniqueFieldName( mAttributePrefix + "count" ); QgsField countField( countFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( countField ); } QString sumFieldName; if ( mStatistics & QgsZonalStatistics::Sum ) { sumFieldName = getUniqueFieldName( mAttributePrefix + "sum" ); QgsField sumField( sumFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( sumField ); } QString meanFieldName; if ( mStatistics & QgsZonalStatistics::Mean ) { meanFieldName = getUniqueFieldName( mAttributePrefix + "mean" ); QgsField meanField( meanFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( meanField ); } QString medianFieldName; if ( mStatistics & QgsZonalStatistics::Median ) { medianFieldName = getUniqueFieldName( mAttributePrefix + "median" ); QgsField medianField( medianFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( medianField ); } QString stdevFieldName; if ( mStatistics & QgsZonalStatistics::StDev ) { stdevFieldName = getUniqueFieldName( mAttributePrefix + "stdev" ); QgsField stdField( stdevFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( stdField ); } QString minFieldName; if ( mStatistics & QgsZonalStatistics::Min ) { minFieldName = getUniqueFieldName( mAttributePrefix + "min" ); QgsField minField( minFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( minField ); } QString maxFieldName; if ( mStatistics & QgsZonalStatistics::Max ) { maxFieldName = getUniqueFieldName( mAttributePrefix + "max" ); QgsField maxField( maxFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( maxField ); } QString rangeFieldName; if ( mStatistics & QgsZonalStatistics::Range ) { rangeFieldName = getUniqueFieldName( mAttributePrefix + "range" ); QgsField rangeField( rangeFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( rangeField ); } QString minorityFieldName; if ( mStatistics & QgsZonalStatistics::Minority ) { minorityFieldName = getUniqueFieldName( mAttributePrefix + "minority" ); QgsField minorityField( minorityFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( minorityField ); } QString majorityFieldName; if ( mStatistics & QgsZonalStatistics::Majority ) { majorityFieldName = getUniqueFieldName( mAttributePrefix + "majority" ); QgsField majField( majorityFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( majField ); } QString varietyFieldName; if ( mStatistics & QgsZonalStatistics::Variety ) { varietyFieldName = getUniqueFieldName( mAttributePrefix + "variety" ); QgsField varietyField( varietyFieldName, QVariant::Int, "int" ); newFieldList.push_back( varietyField ); } vectorProvider->addAttributes( newFieldList ); //index of the new fields int countIndex = mStatistics & QgsZonalStatistics::Count ? vectorProvider->fieldNameIndex( countFieldName ) : -1; int sumIndex = mStatistics & QgsZonalStatistics::Sum ? vectorProvider->fieldNameIndex( sumFieldName ) : -1; int meanIndex = mStatistics & QgsZonalStatistics::Mean ? vectorProvider->fieldNameIndex( meanFieldName ) : -1; int medianIndex = mStatistics & QgsZonalStatistics::Median ? vectorProvider->fieldNameIndex( medianFieldName ) : -1; int stdevIndex = mStatistics & QgsZonalStatistics::StDev ? vectorProvider->fieldNameIndex( stdevFieldName ) : -1; int minIndex = mStatistics & QgsZonalStatistics::Min ? vectorProvider->fieldNameIndex( minFieldName ) : -1; int maxIndex = mStatistics & QgsZonalStatistics::Max ? vectorProvider->fieldNameIndex( maxFieldName ) : -1; int rangeIndex = mStatistics & QgsZonalStatistics::Range ? vectorProvider->fieldNameIndex( rangeFieldName ) : -1; int minorityIndex = mStatistics & QgsZonalStatistics::Minority ? vectorProvider->fieldNameIndex( minorityFieldName ) : -1; int majorityIndex = mStatistics & QgsZonalStatistics::Majority ? vectorProvider->fieldNameIndex( majorityFieldName ) : -1; int varietyIndex = mStatistics & QgsZonalStatistics::Variety ? vectorProvider->fieldNameIndex( varietyFieldName ) : -1; if (( mStatistics & QgsZonalStatistics::Count && countIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Sum && sumIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Mean && meanIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Median && medianIndex == -1 ) || ( mStatistics & QgsZonalStatistics::StDev && stdevIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Min && minIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Max && maxIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Range && rangeIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Minority && minorityIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Majority && majorityIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Variety && varietyIndex == -1 ) ) { //failed to create a required field return 8; } //progress dialog long featureCount = vectorProvider->featureCount(); if ( p ) { p->setMaximum( featureCount ); } //iterate over each polygon QgsFeatureRequest request; request.setSubsetOfAttributes( QgsAttributeList() ); QgsFeatureIterator fi = vectorProvider->getFeatures( request ); QgsFeature f; bool statsStoreValues = ( mStatistics & QgsZonalStatistics::Median ) || ( mStatistics & QgsZonalStatistics::StDev ); bool statsStoreValueCount = ( mStatistics & QgsZonalStatistics::Minority ) || ( mStatistics & QgsZonalStatistics::Majority ); FeatureStats featureStats( statsStoreValues, statsStoreValueCount ); int featureCounter = 0; QgsChangedAttributesMap changeMap; while ( fi.nextFeature( f ) ) { if ( p ) { p->setValue( featureCounter ); } if ( p && p->wasCanceled() ) { break; } if ( !f.constGeometry() ) { ++featureCounter; continue; } const QgsGeometry* featureGeometry = f.constGeometry(); QgsRectangle featureRect = featureGeometry->boundingBox().intersect( &rasterBBox ); if ( featureRect.isEmpty() ) { ++featureCounter; continue; } int offsetX, offsetY, nCellsX, nCellsY; if ( cellInfoForBBox( rasterBBox, featureRect, cellsizeX, cellsizeY, offsetX, offsetY, nCellsX, nCellsY ) != 0 ) { ++featureCounter; continue; } //avoid access to cells outside of the raster (may occur because of rounding) if (( offsetX + nCellsX ) > nCellsXGDAL ) { nCellsX = nCellsXGDAL - offsetX; } if (( offsetY + nCellsY ) > nCellsYGDAL ) { nCellsY = nCellsYGDAL - offsetY; } statisticsFromMiddlePointTest( rasterBand, featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY, rasterBBox, featureStats ); if ( featureStats.count <= 1 ) { //the cell resolution is probably larger than the polygon area. We switch to precise pixel - polygon intersection in this case statisticsFromPreciseIntersection( rasterBand, featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY, rasterBBox, featureStats ); } //write the statistics value to the vector data provider QgsAttributeMap changeAttributeMap; if ( mStatistics & QgsZonalStatistics::Count ) changeAttributeMap.insert( countIndex, QVariant( featureStats.count ) ); if ( mStatistics & QgsZonalStatistics::Sum ) changeAttributeMap.insert( sumIndex, QVariant( featureStats.sum ) ); if ( featureStats.count > 0 ) { double mean = featureStats.sum / featureStats.count; if ( mStatistics & QgsZonalStatistics::Mean ) changeAttributeMap.insert( meanIndex, QVariant( mean ) ); if ( mStatistics & QgsZonalStatistics::Median ) { qSort( featureStats.values.begin(), featureStats.values.end() ); int size = featureStats.values.count(); bool even = ( size % 2 ) < 1; double medianValue; if ( even ) { medianValue = ( featureStats.values.at( size / 2 - 1 ) + featureStats.values.at( size / 2 ) ) / 2; } else //odd { medianValue = featureStats.values.at(( size + 1 ) / 2 - 1 ); } changeAttributeMap.insert( medianIndex, QVariant( medianValue ) ); } if ( mStatistics & QgsZonalStatistics::StDev ) { double sumSquared = 0; for ( int i = 0; i < featureStats.values.count(); ++i ) { double diff = featureStats.values.at( i ) - mean; sumSquared += diff * diff; } double stdev = qPow( sumSquared / featureStats.values.count(), 0.5 ); changeAttributeMap.insert( stdevIndex, QVariant( stdev ) ); } if ( mStatistics & QgsZonalStatistics::Min ) changeAttributeMap.insert( minIndex, QVariant( featureStats.min ) ); if ( mStatistics & QgsZonalStatistics::Max ) changeAttributeMap.insert( maxIndex, QVariant( featureStats.max ) ); if ( mStatistics & QgsZonalStatistics::Range ) changeAttributeMap.insert( rangeIndex, QVariant( featureStats.max - featureStats.min ) ); if ( mStatistics & QgsZonalStatistics::Minority || mStatistics & QgsZonalStatistics::Majority ) { QList<int> vals = featureStats.valueCount.values(); qSort( vals.begin(), vals.end() ); if ( mStatistics & QgsZonalStatistics::Minority ) { float minorityKey = featureStats.valueCount.key( vals.first() ); changeAttributeMap.insert( minorityIndex, QVariant( minorityKey ) ); } if ( mStatistics & QgsZonalStatistics::Majority ) { float majKey = featureStats.valueCount.key( vals.last() ); changeAttributeMap.insert( majorityIndex, QVariant( majKey ) ); } } if ( mStatistics & QgsZonalStatistics::Variety ) changeAttributeMap.insert( varietyIndex, QVariant( featureStats.valueCount.count() ) ); } changeMap.insert( f.id(), changeAttributeMap ); ++featureCounter; } vectorProvider->changeAttributeValues( changeMap ); if ( p ) { p->setValue( featureCount ); } GDALClose( inputDataset ); mPolygonLayer->updateFields(); if ( p && p->wasCanceled() ) { return 9; } return 0; }
int QgsRasterCalculator::processCalculation( QProgressDialog* p ) { //prepare search string / tree QString errorString; QgsRasterCalcNode* calcNode = QgsRasterCalcNode::parseRasterCalcString( mFormulaString, errorString ); if ( !calcNode ) { //error return static_cast<int>( ParserError ); } QMap< QString, QgsRasterBlock* > inputBlocks; QVector<QgsRasterCalculatorEntry>::const_iterator it = mRasterEntries.constBegin(); for ( ; it != mRasterEntries.constEnd(); ++it ) { if ( !it->raster ) // no raster layer in entry { delete calcNode; qDeleteAll( inputBlocks ); return static_cast< int >( InputLayerError ); } QgsRasterBlock* block = nullptr; // if crs transform needed if ( it->raster->crs() != mOutputCrs ) { QgsRasterProjector proj; proj.setCRS( it->raster->crs(), mOutputCrs ); proj.setInput( it->raster->dataProvider() ); proj.setPrecision( QgsRasterProjector::Exact ); block = proj.block( it->bandNumber, mOutputRectangle, mNumOutputColumns, mNumOutputRows ); } else { block = it->raster->dataProvider()->block( it->bandNumber, mOutputRectangle, mNumOutputColumns, mNumOutputRows ); } if ( block->isEmpty() ) { delete block; delete calcNode; qDeleteAll( inputBlocks ); return static_cast<int>( MemoryError ); } inputBlocks.insert( it->ref, block ); } //open output dataset for writing GDALDriverH outputDriver = openOutputDriver(); if ( !outputDriver ) { return static_cast< int >( CreateOutputError ); } GDALDatasetH outputDataset = openOutputFile( outputDriver ); GDALSetProjection( outputDataset, mOutputCrs.toWkt().toLocal8Bit().data() ); GDALRasterBandH outputRasterBand = GDALGetRasterBand( outputDataset, 1 ); float outputNodataValue = -FLT_MAX; GDALSetRasterNoDataValue( outputRasterBand, outputNodataValue ); if ( p ) { p->setMaximum( mNumOutputRows ); } QgsRasterMatrix resultMatrix; resultMatrix.setNodataValue( outputNodataValue ); //read / write line by line for ( int i = 0; i < mNumOutputRows; ++i ) { if ( p ) { p->setValue( i ); } if ( p && p->wasCanceled() ) { break; } if ( calcNode->calculate( inputBlocks, resultMatrix, i ) ) { bool resultIsNumber = resultMatrix.isNumber(); float* calcData = new float[mNumOutputColumns]; for ( int j = 0; j < mNumOutputColumns; ++j ) { calcData[j] = ( float )( resultIsNumber ? resultMatrix.number() : resultMatrix.data()[j] ); } //write scanline to the dataset if ( GDALRasterIO( outputRasterBand, GF_Write, 0, i, mNumOutputColumns, 1, calcData, mNumOutputColumns, 1, GDT_Float32, 0, 0 ) != CE_None ) { qWarning( "RasterIO error!" ); } delete[] calcData; } } if ( p ) { p->setValue( mNumOutputRows ); } //close datasets and release memory delete calcNode; qDeleteAll( inputBlocks ); inputBlocks.clear(); if ( p && p->wasCanceled() ) { //delete the dataset without closing (because it is faster) GDALDeleteDataset( outputDriver, TO8F( mOutputFile ) ); return static_cast< int >( Cancelled ); } GDALClose( outputDataset ); return static_cast< int >( Success ); }
int QgsZonalStatistics::calculateStatistics( QProgressDialog* p ) { if ( !mPolygonLayer || mPolygonLayer->geometryType() != QGis::Polygon ) { return 1; } QgsVectorDataProvider* vectorProvider = mPolygonLayer->dataProvider(); if ( !vectorProvider ) { return 2; } //open the raster layer and the raster band GDALAllRegister(); GDALDatasetH inputDataset = GDALOpen( TO8F( mRasterFilePath ), GA_ReadOnly ); if ( inputDataset == NULL ) { return 3; } if ( GDALGetRasterCount( inputDataset ) < ( mRasterBand - 1 ) ) { GDALClose( inputDataset ); return 4; } GDALRasterBandH rasterBand = GDALGetRasterBand( inputDataset, mRasterBand ); if ( rasterBand == NULL ) { GDALClose( inputDataset ); return 5; } mInputNodataValue = GDALGetRasterNoDataValue( rasterBand, NULL ); //get geometry info about raster layer int nCellsXGDAL = GDALGetRasterXSize( inputDataset ); int nCellsYGDAL = GDALGetRasterYSize( inputDataset ); double geoTransform[6]; if ( GDALGetGeoTransform( inputDataset, geoTransform ) != CE_None ) { GDALClose( inputDataset ); return 6; } double cellsizeX = geoTransform[1]; if ( cellsizeX < 0 ) { cellsizeX = -cellsizeX; } double cellsizeY = geoTransform[5]; if ( cellsizeY < 0 ) { cellsizeY = -cellsizeY; } QgsRectangle rasterBBox( geoTransform[0], geoTransform[3] - ( nCellsYGDAL * cellsizeY ), geoTransform[0] + ( nCellsXGDAL * cellsizeX ), geoTransform[3] ); //add the new count, sum, mean fields to the provider QList<QgsField> newFieldList; QString countFieldName = getUniqueFieldName( mAttributePrefix + "count" ); QString sumFieldName = getUniqueFieldName( mAttributePrefix + "sum" ); QString meanFieldName = getUniqueFieldName( mAttributePrefix + "mean" ); QgsField countField( countFieldName, QVariant::Double, "double precision" ); QgsField sumField( sumFieldName, QVariant::Double, "double precision" ); QgsField meanField( meanFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( countField ); newFieldList.push_back( sumField ); newFieldList.push_back( meanField ); vectorProvider->addAttributes( newFieldList ); //index of the new fields int countIndex = vectorProvider->fieldNameIndex( countFieldName ); int sumIndex = vectorProvider->fieldNameIndex( sumFieldName ); int meanIndex = vectorProvider->fieldNameIndex( meanFieldName ); if ( countIndex == -1 || sumIndex == -1 || meanIndex == -1 ) { return 8; } //progress dialog long featureCount = vectorProvider->featureCount(); if ( p ) { p->setMaximum( featureCount ); } //iterate over each polygon QgsFeatureRequest request; request.setSubsetOfAttributes( QgsAttributeList() ); QgsFeatureIterator fi = vectorProvider->getFeatures( request ); QgsFeature f; double count = 0; double sum = 0; double mean = 0; int featureCounter = 0; while ( fi.nextFeature( f ) ) { if ( p ) { p->setValue( featureCounter ); } if ( p && p->wasCanceled() ) { break; } QgsGeometry* featureGeometry = f.geometry(); if ( !featureGeometry ) { ++featureCounter; continue; } QgsRectangle featureRect = featureGeometry->boundingBox().intersect( &rasterBBox ); if ( featureRect.isEmpty() ) { ++featureCounter; continue; } int offsetX, offsetY, nCellsX, nCellsY; if ( cellInfoForBBox( rasterBBox, featureRect, cellsizeX, cellsizeY, offsetX, offsetY, nCellsX, nCellsY ) != 0 ) { ++featureCounter; continue; } //avoid access to cells outside of the raster (may occur because of rounding) if (( offsetX + nCellsX ) > nCellsXGDAL ) { nCellsX = nCellsXGDAL - offsetX; } if (( offsetY + nCellsY ) > nCellsYGDAL ) { nCellsY = nCellsYGDAL - offsetY; } statisticsFromMiddlePointTest( rasterBand, featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY, rasterBBox, sum, count ); if ( count <= 1 ) { //the cell resolution is probably larger than the polygon area. We switch to precise pixel - polygon intersection in this case statisticsFromPreciseIntersection( rasterBand, featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY, rasterBBox, sum, count ); } if ( count == 0 ) { mean = 0; } else { mean = sum / count; } //write the statistics value to the vector data provider QgsChangedAttributesMap changeMap; QgsAttributeMap changeAttributeMap; changeAttributeMap.insert( countIndex, QVariant( count ) ); changeAttributeMap.insert( sumIndex, QVariant( sum ) ); changeAttributeMap.insert( meanIndex, QVariant( mean ) ); changeMap.insert( f.id(), changeAttributeMap ); vectorProvider->changeAttributeValues( changeMap ); ++featureCounter; } if ( p ) { p->setValue( featureCount ); } GDALClose( inputDataset ); mPolygonLayer->updateFields(); if ( p && p->wasCanceled() ) { return 9; } return 0; }