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(); }
QgsFeatureList QgsOgrUtils::stringToFeatureList( const QString& string, const QgsFields& fields, QTextCodec* encoding ) { QgsFeatureList features; if ( string.isEmpty() ) return features; QString randomFileName = QString( "/vsimem/%1" ).arg( QUuid::createUuid().toString() ); // create memory file system object from string buffer QByteArray ba = string.toUtf8(); VSIFCloseL( VSIFileFromMemBuffer( TO8( randomFileName ), reinterpret_cast< GByte* >( ba.data() ), static_cast< vsi_l_offset >( ba.size() ), FALSE ) ); OGRDataSourceH hDS = OGROpen( TO8( randomFileName ), false, nullptr ); if ( !hDS ) { VSIUnlink( TO8( randomFileName ) ); return features; } OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS, 0 ); if ( !ogrLayer ) { OGR_DS_Destroy( hDS ); VSIUnlink( TO8( randomFileName ) ); return features; } OGRFeatureH oFeat; while (( oFeat = OGR_L_GetNextFeature( ogrLayer ) ) ) { QgsFeature feat = readOgrFeature( oFeat, fields, encoding ); if ( feat.isValid() ) features << feat; OGR_F_Destroy( oFeat ); } OGR_DS_Destroy( hDS ); VSIUnlink( TO8( randomFileName ) ); return features; }
QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrFeatureSource* source, bool ownSource, const QgsFeatureRequest& request ) : QgsAbstractFeatureIteratorFromSource<QgsOgrFeatureSource>( source, ownSource, request ) , mFeatureFetched( false ) , mConn( nullptr ) , ogrLayer( nullptr ) , mSubsetStringSet( false ) , mFetchGeometry( false ) , mExpressionCompiled( false ) , mFilterFids( mRequest.filterFids() ) , mFilterFidsIt( mFilterFids.constBegin() ) { mConn = QgsOgrConnPool::instance()->acquireConnection( mSource->mProvider->dataSourceUri() ); if ( !mConn->ds ) { return; } if ( mSource->mLayerName.isNull() ) { ogrLayer = OGR_DS_GetLayer( mConn->ds, mSource->mLayerIndex ); } else { ogrLayer = OGR_DS_GetLayerByName( mConn->ds, TO8( mSource->mLayerName ) ); } if ( !ogrLayer ) { return; } if ( !mSource->mSubsetString.isEmpty() ) { ogrLayer = QgsOgrProviderUtils::setSubsetString( ogrLayer, mConn->ds, mSource->mEncoding, mSource->mSubsetString ); if ( !ogrLayer ) { return; } mSubsetStringSet = true; } mFetchGeometry = ( !mRequest.filterRect().isNull() ) || !( mRequest.flags() & QgsFeatureRequest::NoGeometry ); QgsAttributeList attrs = ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) ? mRequest.subsetOfAttributes() : mSource->mFields.allAttributesList(); // ensure that all attributes required for expression filter are being fetched if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes && request.filterType() == QgsFeatureRequest::FilterExpression ) { Q_FOREACH ( const QString& field, request.filterExpression()->referencedColumns() ) { int attrIdx = mSource->mFields.fieldNameIndex( field ); if ( !attrs.contains( attrIdx ) ) attrs << attrIdx; } mRequest.setSubsetOfAttributes( attrs ); }
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(); }
//duplicated from QgsNineCellFilter. Todo: make common base class GDALDatasetH QgsRelief::openInputFile( int& nCellsX, int& nCellsY ) { GDALDatasetH inputDataset = GDALOpen( TO8( 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; }
QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrFeatureSource* source, bool ownSource, const QgsFeatureRequest& request ) : QgsAbstractFeatureIteratorFromSource<QgsOgrFeatureSource>( source, ownSource, request ) , mFeatureFetched( false ) , mConn( nullptr ) , ogrLayer( nullptr ) , mSubsetStringSet( false ) , mFetchGeometry( false ) , mExpressionCompiled( false ) , mFilterFids( mRequest.filterFids() ) , mFilterFidsIt( mFilterFids.constBegin() ) { mConn = QgsOgrConnPool::instance()->acquireConnection( mSource->mProvider->dataSourceUri() ); if ( !mConn->ds ) { return; } if ( mSource->mLayerName.isNull() ) { ogrLayer = OGR_DS_GetLayer( mConn->ds, mSource->mLayerIndex ); } else { ogrLayer = OGR_DS_GetLayerByName( mConn->ds, TO8( mSource->mLayerName ) ); } if ( !ogrLayer ) { return; } if ( !mSource->mSubsetString.isEmpty() ) { ogrLayer = QgsOgrProviderUtils::setSubsetString( ogrLayer, mConn->ds, mSource->mEncoding, mSource->mSubsetString ); if ( !ogrLayer ) { return; } mSubsetStringSet = true; } mFetchGeometry = ( !mRequest.filterRect().isNull() ) || !( mRequest.flags() & QgsFeatureRequest::NoGeometry ); QgsAttributeList attrs = ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) ? mRequest.subsetOfAttributes() : mSource->mFields.allAttributesList(); // ensure that all attributes required for expression filter are being fetched if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes && request.filterType() == QgsFeatureRequest::FilterExpression ) { //ensure that all fields required for filter expressions are prepared QSet<int> attributeIndexes = request.filterExpression()->referencedAttributeIndexes( mSource->mFields ); attributeIndexes += attrs.toSet(); attrs = attributeIndexes.toList(); mRequest.setSubsetOfAttributes( attrs ); } if ( request.filterType() == QgsFeatureRequest::FilterExpression && request.filterExpression()->needsGeometry() ) { mFetchGeometry = true; } // 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.filterRect().isNull() ) { QgsOgrProviderUtils::setRelevantFields( ogrLayer, mSource->mFields.count(), mFetchGeometry, attrs, mSource->mFirstFieldIsFid ); } // spatial query to select features if ( !mRequest.filterRect().isNull() ) { const QgsRectangle& rect = mRequest.filterRect(); OGR_L_SetSpatialFilterRect( ogrLayer, rect.xMinimum(), rect.yMinimum(), rect.xMaximum(), rect.yMaximum() ); } else { OGR_L_SetSpatialFilter( ogrLayer, nullptr ); } if ( request.filterType() == QgsFeatureRequest::FilterExpression && QSettings().value( "/qgis/compileExpressions", true ).toBool() ) { QgsSqlExpressionCompiler* compiler; if ( source->mDriverName == "SQLite" || source->mDriverName == "GPKG" ) { compiler = new QgsSQLiteExpressionCompiler( source->mFields ); } else { compiler = new QgsOgrExpressionCompiler( source ); } QgsSqlExpressionCompiler::Result result = compiler->compile( request.filterExpression() ); if ( result == QgsSqlExpressionCompiler::Complete || result == QgsSqlExpressionCompiler::Partial ) { QString whereClause = compiler->result(); if ( OGR_L_SetAttributeFilter( ogrLayer, mSource->mEncoding->fromUnicode( whereClause ).constData() ) == OGRERR_NONE ) { //if only partial success when compiling expression, we need to double-check results using QGIS' expressions mExpressionCompiled = ( result == QgsSqlExpressionCompiler::Complete ); mCompileStatus = ( mExpressionCompiled ? Compiled : PartiallyCompiled ); } } else { OGR_L_SetAttributeFilter( ogrLayer, nullptr ); } delete compiler; } else { OGR_L_SetAttributeFilter( ogrLayer, nullptr ); } //start with first feature rewind(); }
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( TO8( 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 nCellsX = GDALGetRasterXSize( inputDataset ); int nCellsY = 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] - ( nCellsY * cellsizeY ), geoTransform[0] + ( nCellsX * cellsizeX ), geoTransform[3] ); //add the new count, sum, mean fields to the provider QList<QgsField> newFieldList; QgsField countField( mAttributePrefix + "count", QVariant::Double ); QgsField sumField( mAttributePrefix + "sum", QVariant::Double ); QgsField meanField( mAttributePrefix + "mean", QVariant::Double ); newFieldList.push_back( countField ); newFieldList.push_back( sumField ); newFieldList.push_back( meanField ); vectorProvider->addAttributes( newFieldList ); //index of the new fields int countIndex = vectorProvider->fieldNameIndex( mAttributePrefix + "count" ); int sumIndex = vectorProvider->fieldNameIndex( mAttributePrefix + "sum" ); int meanIndex = vectorProvider->fieldNameIndex( mAttributePrefix + "mean" ); if ( countIndex == -1 || sumIndex == -1 || meanIndex == -1 ) { return 8; } //progress dialog long featureCount = vectorProvider->featureCount(); if ( p ) { p->setMaximum( featureCount ); } //iterate over each polygon vectorProvider->select( QgsAttributeList(), QgsRectangle(), true, false ); QgsFeature f; double count = 0; double sum = 0; double mean = 0; int featureCounter = 0; while ( vectorProvider->nextFeature( f ) ) { qWarning( "%d", featureCounter ); if ( p ) { p->setValue( featureCounter ); } if ( p && p->wasCanceled() ) { break; } QgsGeometry* featureGeometry = f.geometry(); if ( !featureGeometry ) { ++featureCounter; continue; } int offsetX, offsetY, nCellsX, nCellsY; if ( cellInfoForBBox( rasterBBox, featureGeometry->boundingBox(), cellsizeX, cellsizeY, offsetX, offsetY, nCellsX, nCellsY ) != 0 ) { ++featureCounter; continue; } statisticsFromMiddlePointTest_improved( 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->updateFieldMap(); if ( p && p->wasCanceled() ) { return 9; } return 0; }
QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrFeatureSource* source, bool ownSource, const QgsFeatureRequest& request ) : QgsAbstractFeatureIteratorFromSource<QgsOgrFeatureSource>( source, ownSource, request ) , ogrLayer( 0 ) , mSubsetStringSet( false ) , mGeometrySimplifier( NULL ) , mExpressionCompiled( false ) { mFeatureFetched = false; mConn = QgsOgrConnPool::instance()->acquireConnection( mSource->mFilePath ); if ( mSource->mLayerName.isNull() ) { ogrLayer = OGR_DS_GetLayer( mConn->ds, mSource->mLayerIndex ); } else { ogrLayer = OGR_DS_GetLayerByName( mConn->ds, TO8( mSource->mLayerName ) ); } if ( !mSource->mSubsetString.isEmpty() ) { ogrLayer = QgsOgrUtils::setSubsetString( ogrLayer, mConn->ds, mSource->mEncoding, mSource->mSubsetString ); mSubsetStringSet = true; } mFetchGeometry = ( !mRequest.filterRect().isNull() ) || !( 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.filterRect().isNull() ) { QgsOgrUtils::setRelevantFields( ogrLayer, mSource->mFields.count(), mFetchGeometry, attrs ); } // spatial query to select features if ( !mRequest.filterRect().isNull() ) { const QgsRectangle& rect = mRequest.filterRect(); OGR_L_SetSpatialFilterRect( ogrLayer, rect.xMinimum(), rect.yMinimum(), rect.xMaximum(), rect.yMaximum() ); } else { OGR_L_SetSpatialFilter( ogrLayer, 0 ); } if ( request.filterType() == QgsFeatureRequest::FilterExpression && QSettings().value( "/qgis/compileExpressions", true ).toBool() ) { QgsOgrExpressionCompiler compiler = QgsOgrExpressionCompiler( source ); QgsSqlExpressionCompiler::Result result = compiler.compile( request.filterExpression() ); if ( result == QgsSqlExpressionCompiler::Complete || result == QgsSqlExpressionCompiler::Partial ) { QString whereClause = compiler.result(); if ( OGR_L_SetAttributeFilter( ogrLayer, whereClause.toLocal8Bit().data() ) == OGRERR_NONE ) { //if only partial success when compiling expression, we need to double-check results using QGIS' expressions mExpressionCompiled = ( result == QgsSqlExpressionCompiler::Complete ); } } else { OGR_L_SetAttributeFilter( ogrLayer, 0 ); } } else { OGR_L_SetAttributeFilter( ogrLayer, 0 ); } //start with first feature rewind(); }
int QgsRasterCalculator::processCalculation( QProgressDialog* p ) { //prepare search string / tree QString errorString; QgsRasterCalcNode* calcNode = QgsRasterCalcNode::parseRasterCalcString( mFormulaString, errorString ); if ( !calcNode ) { //error } double targetGeoTransform[6]; outputGeoTransform( targetGeoTransform ); //open all input rasters for reading QMap< QString, GDALRasterBandH > mInputRasterBands; //raster references and corresponding scanline data QMap< QString, QgsRasterMatrix* > inputScanLineData; //stores raster references and corresponding scanline data QVector< GDALDatasetH > mInputDatasets; //raster references and corresponding dataset QVector<QgsRasterCalculatorEntry>::const_iterator it = mRasterEntries.constBegin(); for ( ; it != mRasterEntries.constEnd(); ++it ) { if ( !it->raster ) // no raster layer in entry { return 2; } GDALDatasetH inputDataset = GDALOpen( TO8( it->raster->source() ), GA_ReadOnly ); if ( inputDataset == NULL ) { return 2; } //check if the input dataset is south up or rotated. If yes, use GDALAutoCreateWarpedVRT to create a north up raster double inputGeoTransform[6]; if ( GDALGetGeoTransform( inputDataset, inputGeoTransform ) == CE_None && ( inputGeoTransform[1] < 0.0 || inputGeoTransform[2] != 0.0 || inputGeoTransform[4] != 0.0 || inputGeoTransform[5] > 0.0 ) ) { GDALDatasetH vDataset = GDALAutoCreateWarpedVRT( inputDataset, NULL, NULL, GRA_NearestNeighbour, 0.2, NULL ); mInputDatasets.push_back( vDataset ); mInputDatasets.push_back( inputDataset ); inputDataset = vDataset; } else { mInputDatasets.push_back( inputDataset ); } GDALRasterBandH inputRasterBand = GDALGetRasterBand( inputDataset, it->bandNumber ); if ( inputRasterBand == NULL ) { return 2; } int nodataSuccess; double nodataValue = GDALGetRasterNoDataValue( inputRasterBand, &nodataSuccess ); mInputRasterBands.insert( it->ref, inputRasterBand ); inputScanLineData.insert( it->ref, new QgsRasterMatrix( mNumOutputColumns, 1, new float[mNumOutputColumns], nodataValue ) ); } //open output dataset for writing GDALDriverH outputDriver = openOutputDriver(); if ( outputDriver == NULL ) { return 1; } GDALDatasetH outputDataset = openOutputFile( outputDriver ); //copy the projection info from the first input raster if ( mRasterEntries.size() > 0 ) { QgsRasterLayer* rl = mRasterEntries.at( 0 ).raster; if ( rl ) { char* crsWKT = 0; OGRSpatialReferenceH ogrSRS = OSRNewSpatialReference( NULL ); if ( OSRSetFromUserInput( ogrSRS, rl->crs().authid().toUtf8().constData() ) == OGRERR_NONE ) { OSRExportToWkt( ogrSRS, &crsWKT ); GDALSetProjection( outputDataset, crsWKT ); } else { GDALSetProjection( outputDataset, TO8( rl->crs().toWkt() ) ); } OSRDestroySpatialReference( ogrSRS ); CPLFree( crsWKT ); } } GDALRasterBandH outputRasterBand = GDALGetRasterBand( outputDataset, 1 ); float outputNodataValue = -FLT_MAX; GDALSetRasterNoDataValue( outputRasterBand, outputNodataValue ); float* resultScanLine = ( float * ) CPLMalloc( sizeof( float ) * mNumOutputColumns ); if ( p ) { p->setMaximum( mNumOutputRows ); } QgsRasterMatrix resultMatrix; //read / write line by line for ( int i = 0; i < mNumOutputRows; ++i ) { if ( p ) { p->setValue( i ); } if ( p && p->wasCanceled() ) { break; } //fill buffers QMap< QString, QgsRasterMatrix* >::iterator bufferIt = inputScanLineData.begin(); for ( ; bufferIt != inputScanLineData.end(); ++bufferIt ) { double sourceTransformation[6]; GDALRasterBandH sourceRasterBand = mInputRasterBands[bufferIt.key()]; GDALGetGeoTransform( GDALGetBandDataset( sourceRasterBand ), sourceTransformation ); //the function readRasterPart calls GDALRasterIO (and ev. does some conversion if raster transformations are not the same) readRasterPart( targetGeoTransform, 0, i, mNumOutputColumns, 1, sourceTransformation, sourceRasterBand, bufferIt.value()->data() ); } if ( calcNode->calculate( inputScanLineData, resultMatrix ) ) { bool resultIsNumber = resultMatrix.isNumber(); float* calcData; if ( resultIsNumber ) //scalar result. Insert number for every pixel { calcData = new float[mNumOutputColumns]; for ( int j = 0; j < mNumOutputColumns; ++j ) { calcData[j] = resultMatrix.number(); } } else //result is real matrix { calcData = resultMatrix.data(); } //replace all matrix nodata values with output nodatas for ( int j = 0; j < mNumOutputColumns; ++j ) { if ( calcData[j] == resultMatrix.nodataValue() ) { calcData[j] = outputNodataValue; } } //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!" ); } if ( resultIsNumber ) { delete[] calcData; } } } if ( p ) { p->setValue( mNumOutputRows ); } //close datasets and release memory delete calcNode; QMap< QString, QgsRasterMatrix* >::iterator bufferIt = inputScanLineData.begin(); for ( ; bufferIt != inputScanLineData.end(); ++bufferIt ) { delete bufferIt.value(); } inputScanLineData.clear(); QVector< GDALDatasetH >::iterator datasetIt = mInputDatasets.begin(); for ( ; datasetIt != mInputDatasets.end(); ++ datasetIt ) { GDALClose( *datasetIt ); } if ( p && p->wasCanceled() ) { //delete the dataset without closing (because it is faster) GDALDeleteDataset( outputDriver, mOutputFile.toLocal8Bit().data() ); return 3; } GDALClose( outputDataset ); CPLFree( resultScanLine ); return 0; }
QgsVectorLayer* QgsSLDConfigParser::contourLayerFromRaster( const QDomElement& userStyleElem, QgsRasterLayer* rasterLayer ) const { QgsDebugMsg( "Entering." ); if ( !rasterLayer ) { return nullptr; } //get <ContourSymbolizer> element QDomNodeList contourNodeList = userStyleElem.elementsByTagName( "ContourSymbolizer" ); if ( contourNodeList.size() < 1 ) { return nullptr; } QDomElement contourSymbolizerElem = contourNodeList.item( 0 ).toElement(); if ( contourSymbolizerElem.isNull() ) { return nullptr; } double equidistance, minValue, maxValue, offset; QString propertyName; equidistance = contourSymbolizerElem.attribute( "equidistance" ).toDouble(); minValue = contourSymbolizerElem.attribute( "minValue" ).toDouble(); maxValue = contourSymbolizerElem.attribute( "maxValue" ).toDouble(); offset = contourSymbolizerElem.attribute( "offset" ).toDouble(); propertyName = contourSymbolizerElem.attribute( "propertyName" ); if ( equidistance <= 0.0 ) { return nullptr; } QTemporaryFile* tmpFile1 = new QTemporaryFile(); tmpFile1->open(); mFilesToRemove.push_back( tmpFile1 ); QString tmpBaseName = tmpFile1->fileName(); QString tmpFileName = tmpBaseName + ".shp"; //hack: use gdal_contour first to write into a temporary file /* todo: use GDALContourGenerate( hBand, dfInterval, dfOffset, nFixedLevelCount, adfFixedLevels, bNoDataSet, dfNoData, hLayer, 0, nElevField, GDALTermProgress, nullptr );*/ //do the stuff that is also done in the main method of gdal_contour... /* -------------------------------------------------------------------- */ /* Open source raster file. */ /* -------------------------------------------------------------------- */ GDALRasterBandH hBand; GDALDatasetH hSrcDS; int numberOfLevels = 0; double currentLevel = 0.0; if ( maxValue > minValue ) { //find first level currentLevel = ( int )(( minValue - offset ) / equidistance + 0.5 ) * equidistance + offset; while ( currentLevel <= maxValue ) { ++numberOfLevels; currentLevel += equidistance; } } double *adfFixedLevels = new double[numberOfLevels]; int nFixedLevelCount = numberOfLevels; currentLevel = ( int )(( minValue - offset ) / equidistance + 0.5 ) * equidistance + offset; for ( int i = 0; i < numberOfLevels; ++i ) { adfFixedLevels[i] = currentLevel; currentLevel += equidistance; } int nBandIn = 1; double dfInterval = equidistance, dfNoData = 0.0, dfOffset = offset; int /* b3D = FALSE, */ bNoDataSet = FALSE, bIgnoreNoData = FALSE; hSrcDS = GDALOpen( TO8( rasterLayer->source() ), GA_ReadOnly ); if ( !hSrcDS ) { delete [] adfFixedLevels; throw QgsMapServiceException( "LayerNotDefined", "Operation request is for a file not available on the server." ); } hBand = GDALGetRasterBand( hSrcDS, nBandIn ); if ( !hBand ) { CPLError( CE_Failure, CPLE_AppDefined, "Band %d does not exist on dataset.", nBandIn ); } if ( !bNoDataSet && !bIgnoreNoData ) dfNoData = GDALGetRasterNoDataValue( hBand, &bNoDataSet ); /* -------------------------------------------------------------------- */ /* Try to get a coordinate system from the raster. */ /* -------------------------------------------------------------------- */ OGRSpatialReferenceH hSRS = nullptr; const char *pszWKT = GDALGetProjectionRef( hBand ); if ( pszWKT && strlen( pszWKT ) != 0 ) hSRS = OSRNewSpatialReference( pszWKT ); /* -------------------------------------------------------------------- */ /* Create the outputfile. */ /* -------------------------------------------------------------------- */ OGRDataSourceH hDS; OGRSFDriverH hDriver = OGRGetDriverByName( "ESRI Shapefile" ); OGRFieldDefnH hFld; OGRLayerH hLayer; int nElevField = -1; if ( !hDriver ) { //fprintf( FCGI_stderr, "Unable to find format driver named 'ESRI Shapefile'.\n" ); delete [] adfFixedLevels; throw QgsMapServiceException( "LayerNotDefined", "Operation request is for a file not available on the server." ); } hDS = OGR_Dr_CreateDataSource( hDriver, TO8( tmpFileName ), nullptr ); if ( !hDS ) { delete [] adfFixedLevels; throw QgsMapServiceException( "LayerNotDefined", "Operation request cannot create data source." ); } hLayer = OGR_DS_CreateLayer( hDS, "contour", hSRS, /* b3D ? wkbLineString25D : */ wkbLineString, nullptr ); if ( !hLayer ) { delete [] adfFixedLevels; throw QgsMapServiceException( "LayerNotDefined", "Operation request could not create contour file." ); } hFld = OGR_Fld_Create( "ID", OFTInteger ); OGR_Fld_SetWidth( hFld, 8 ); OGR_L_CreateField( hLayer, hFld, FALSE ); OGR_Fld_Destroy( hFld ); if ( !propertyName.isEmpty() ) { hFld = OGR_Fld_Create( TO8( propertyName ), OFTReal ); OGR_Fld_SetWidth( hFld, 12 ); OGR_Fld_SetPrecision( hFld, 3 ); OGR_L_CreateField( hLayer, hFld, FALSE ); OGR_Fld_Destroy( hFld ); nElevField = 1; } /* -------------------------------------------------------------------- */ /* Invoke. */ /* -------------------------------------------------------------------- */ GDALContourGenerate( hBand, dfInterval, dfOffset, nFixedLevelCount, adfFixedLevels, bNoDataSet, dfNoData, hLayer, 0, nElevField, GDALTermProgress, nullptr ); delete [] adfFixedLevels; OGR_DS_Destroy( hDS ); GDALClose( hSrcDS ); //todo: store those three files elsewhere... //mark shp, dbf and shx to delete after the request mFilePathsToRemove.push_back( tmpBaseName + ".shp" ); mFilePathsToRemove.push_back( tmpBaseName + ".dbf" ); mFilePathsToRemove.push_back( tmpBaseName + ".shx" ); QgsVectorLayer* contourLayer = new QgsVectorLayer( tmpFileName, "layer", "ogr" ); //create renderer QgsFeatureRenderer* theRenderer = rendererFromUserStyle( userStyleElem, contourLayer ); contourLayer->setRenderer( theRenderer ); //add labelling if requested labelSettingsFromUserStyle( userStyleElem, contourLayer ); QgsDebugMsg( "Returning the contour layer" ); return contourLayer; }