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();
}
Beispiel #2
0
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();
}
Beispiel #5
0
//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;
}
Beispiel #10
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;
}