Beispiel #1
0
int
makeGeotiff (struct deminfo *d0, char *outpath,int nodata)
{

  GDALAllRegister ();

  GDALDataType band_type = GDT_Float32;
  int bands = 1;
  int dsn_xsize = (d0->highx - d0->lowx + 1);
  int dsn_ysize = (d0->highy - d0->lowy + 1);
  char **papszCreateOptions = NULL;
  papszCreateOptions = CSLSetNameValue (papszCreateOptions, "PROFILE", "GeoTIFF");
  //papszCreateOptions = CSLSetNameValue( papszCreateOptions, "TFW", "YES" );
  //papszCreateOptions = CSLSetNameValue (papszCreateOptions, "INTERLEAVE", "PIXEL");
  //papszCreateOptions = CSLSetNameValue (papszCreateOptions, "TILED", "YES");
  //papszCreateOptions = CSLSetNameValue (papszCreateOptions, "COMPRESS", "LZW");


  GDALDriverH hDriver = GDALGetDriverByName ("GTiff");
  GDALDatasetH hDsnDS = GDALCreate (hDriver, outpath, dsn_xsize, dsn_ysize, bands, band_type, papszCreateOptions);

  double dsnGeoTransform[6];
  dsnGeoTransform[0] = d0->W;
  dsnGeoTransform[1] = (d0->E - d0->W) / dsn_xsize;
  dsnGeoTransform[2] = 0;
  dsnGeoTransform[3] = d0->N;
  dsnGeoTransform[4] = 0;
  dsnGeoTransform[5] = -1.0 * (d0->N - d0->S) / dsn_ysize;
  GDALSetGeoTransform (hDsnDS, dsnGeoTransform);

  char pszSRS_WKT[1024] = "GEOGCS[\"JGD2000\", DATUM[\"Japanese Geodetic Datum 2000\", SPHEROID[\"GRS 1980\", 6378137.0, 298.257222101, AUTHORITY[\"EPSG\",\"7019\"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],AUTHORITY[\"EPSG\",\"6612\"]], PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], UNIT[\"degree\", 0.017453292519943295], AXIS[\"Geodetic longitude\", EAST], AXIS[\"Geodetic latitude\", NORTH], AUTHORITY[\"EPSG\",\"4612\"]]";
  GDALSetProjection (hDsnDS, pszSRS_WKT);
  GDALRasterBandH t_band = GDALGetRasterBand (hDsnDS, 1);
  if(nodata==1){
   GDALSetRasterNoDataValue (t_band, -9999);
  }
  GDALRasterIO (t_band, GF_Write, 0, 0, dsn_xsize, dsn_ysize, d0->alti, dsn_xsize, dsn_ysize, band_type, 0, 0);
  CSLDestroy (papszCreateOptions);
  GDALClose (hDsnDS);



  return 0;
}
Beispiel #2
0
void writeGeoTiffF(char * fileName, float * result, int nRow, int nCol, double xMin, double yMax, double cellSize)
{
	
	GDALAllRegister();
	OGRRegisterAll();

	GDALDatasetH hDstDS;
	GDALDriverH hDriver;
	GDALRasterBandH hBand;
	double adfGeoTransform[6];

	char *papszOptions[] = {"COMPRESS=LZW",NULL};
	const char *pszFormat="GTiff";

	if(NULL == (hDriver = GDALGetDriverByName(pszFormat)))
	{
		printf("ERROR: hDriver is null cannot output using GDAL\n");
		exit(1);
	}
	
	hDstDS = GDALCreate(hDriver, fileName, nCol, nRow, 1, GDT_Float32, papszOptions);

	adfGeoTransform[0] = xMin;
	adfGeoTransform[1] = cellSize;
	adfGeoTransform[2] = 0;
	adfGeoTransform[3] = yMax;
	adfGeoTransform[4] = 0;
	adfGeoTransform[5] = -cellSize;

	GDALSetGeoTransform(hDstDS,adfGeoTransform);

	hBand=GDALGetRasterBand(hDstDS,1);
	GDALSetRasterNoDataValue(hBand,-1);
	GDALRasterIO(hBand, GF_Write, 0, 0, nCol, nRow, result, nCol, nRow, GDT_Float32, 0, 0 );
	
	GDALClose(hDstDS);

	return;
}
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 );
}
Beispiel #4
0
QgsRasterCalculator::Result QgsRasterCalculator::processCalculation( QgsFeedback *feedback )
{
  mLastError.clear();

  //prepare search string / tree
  std::unique_ptr< QgsRasterCalcNode > calcNode( QgsRasterCalcNode::parseRasterCalcString( mFormulaString, mLastError ) );
  if ( !calcNode )
  {
    //error
    return ParserError;
  }

  // Check input layers and bands
  for ( const auto &entry : qgis::as_const( mRasterEntries ) )
  {
    if ( !entry.raster ) // no raster layer in entry
    {
      mLastError = QObject::tr( "No raster layer for entry %1" ).arg( entry.ref );
      return InputLayerError;
    }
    if ( entry.bandNumber <= 0 || entry.bandNumber > entry.raster->bandCount() )
    {
      mLastError = QObject::tr( "Band number %1 is not valid for entry %2" ).arg( entry.bandNumber ).arg( entry.ref );
      return BandError;
    }
  }

#ifdef HAVE_OPENCL
  // Check for matrix nodes, GPU implementation does not support them
  QList<const QgsRasterCalcNode *> nodeList;
  if ( QgsOpenClUtils::enabled() && QgsOpenClUtils::available() && calcNode->findNodes( QgsRasterCalcNode::Type::tMatrix ).isEmpty() )
    return processCalculationGPU( std::move( calcNode ), feedback );
#endif

  //open output dataset for writing
  GDALDriverH outputDriver = openOutputDriver();
  if ( !outputDriver )
  {
    mLastError = QObject::tr( "Could not obtain driver for %1" ).arg( mOutputFormat );
    return CreateOutputError;
  }

  gdal::dataset_unique_ptr outputDataset( openOutputFile( outputDriver ) );
  if ( !outputDataset )
  {
    mLastError = QObject::tr( "Could not create output %1" ).arg( mOutputFile );
    return CreateOutputError;
  }

  GDALSetProjection( outputDataset.get(), mOutputCrs.toWkt().toLocal8Bit().data() );
  GDALRasterBandH outputRasterBand = GDALGetRasterBand( outputDataset.get(), 1 );

  float outputNodataValue = -FLT_MAX;
  GDALSetRasterNoDataValue( outputRasterBand, outputNodataValue );

  // Check if we need to read the raster as a whole (which is memory inefficient
  // and not interruptable by the user) by checking if any raster matrix nodes are
  // in the expression
  bool requiresMatrix = ! calcNode->findNodes( QgsRasterCalcNode::Type::tMatrix ).isEmpty();

  // Take the fast route (process one line at a time) if we can
  if ( ! requiresMatrix )
  {
    // Map of raster names -> blocks
    std::map<QString, std::unique_ptr<QgsRasterBlock>> inputBlocks;
    std::map<QString, QgsRasterCalculatorEntry> uniqueRasterEntries;
    for ( const auto &r : calcNode->findNodes( QgsRasterCalcNode::Type::tRasterRef ) )
    {
      QString layerRef( r->toString().remove( 0, 1 ) );
      layerRef.chop( 1 );
      if ( ! inputBlocks.count( layerRef ) )
      {
        for ( const auto &ref : mRasterEntries )
        {
          if ( ref.ref == layerRef )
          {
            uniqueRasterEntries[layerRef] = ref;
            inputBlocks[layerRef ] = qgis::make_unique<QgsRasterBlock>();
          }
        }
      }
    }

    //read / write line by line
    QMap<QString, QgsRasterBlock * > _rasterData;
    // Cast to float
    std::vector<float> castedResult;
    castedResult.reserve( static_cast<size_t>( mNumOutputColumns ) );
    auto rowHeight = mOutputRectangle.height() / mNumOutputRows;
    for ( size_t row = 0; row < static_cast<size_t>( mNumOutputRows ); ++row )
    {
      if ( feedback )
      {
        feedback->setProgress( 100.0 * static_cast< double >( row ) / mNumOutputRows );
      }

      if ( feedback && feedback->isCanceled() )
      {
        break;
      }

      // Calculates the rect for a single row read
      QgsRectangle rect( mOutputRectangle );
      rect.setYMaximum( rect.yMaximum() - rowHeight * row );
      rect.setYMinimum( rect.yMaximum() - rowHeight );

      // Read rows into input blocks
      for ( auto &layerRef : inputBlocks )
      {
        QgsRasterCalculatorEntry ref = uniqueRasterEntries[layerRef.first];
        if ( uniqueRasterEntries[layerRef.first].raster->crs() != mOutputCrs )
        {
          QgsRasterProjector proj;
          proj.setCrs( ref.raster->crs(), mOutputCrs );
          proj.setInput( ref.raster->dataProvider() );
          proj.setPrecision( QgsRasterProjector::Exact );
          layerRef.second.reset( proj.block( ref.bandNumber, rect, mNumOutputColumns, 1 ) );
        }
        else
        {
          inputBlocks[layerRef.first].reset( ref.raster->dataProvider()->block( ref.bandNumber, rect, mNumOutputColumns, 1 ) );
        }
      }

      QgsRasterMatrix resultMatrix;
      resultMatrix.setNodataValue( outputNodataValue );

      _rasterData.clear();
      for ( const auto &layerRef : inputBlocks )
      {
        _rasterData.insert( layerRef.first, inputBlocks[layerRef.first].get() );
      }

      if ( calcNode->calculate( _rasterData, resultMatrix, 0 ) )
      {
        // write scanline to the dataset
        for ( size_t i = 0; i < static_cast<size_t>( mNumOutputColumns ); i++ )
        {
          castedResult[i] = static_cast<float>( resultMatrix.data()[i] );
        }
        if ( GDALRasterIO( outputRasterBand, GF_Write, 0, row, mNumOutputColumns, 1, castedResult.data(), mNumOutputColumns, 1, GDT_Float32, 0, 0 ) != CE_None )
        {
          QgsDebugMsg( QStringLiteral( "RasterIO error!" ) );
        }
      }
    }

    if ( feedback )
    {
      feedback->setProgress( 100.0 );
    }
  }
  else  // Original code (memory inefficient route)
  {
    QMap< QString, QgsRasterBlock * > inputBlocks;
    QVector<QgsRasterCalculatorEntry>::const_iterator it = mRasterEntries.constBegin();
    for ( ; it != mRasterEntries.constEnd(); ++it )
    {

      std::unique_ptr< QgsRasterBlock > block;
      // 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 );

        QgsRasterBlockFeedback *rasterBlockFeedback = new QgsRasterBlockFeedback();
        QObject::connect( feedback, &QgsFeedback::canceled, rasterBlockFeedback, &QgsRasterBlockFeedback::cancel );
        block.reset( proj.block( it->bandNumber, mOutputRectangle, mNumOutputColumns, mNumOutputRows, rasterBlockFeedback ) );
        if ( rasterBlockFeedback->isCanceled() )
        {
          qDeleteAll( inputBlocks );
          return Canceled;
        }
      }
      else
      {
        block.reset( it->raster->dataProvider()->block( it->bandNumber, mOutputRectangle, mNumOutputColumns, mNumOutputRows ) );
      }
      if ( block->isEmpty() )
      {
        mLastError = QObject::tr( "Could not allocate required memory for %1" ).arg( it->ref );
        qDeleteAll( inputBlocks );
        return MemoryError;
      }
      inputBlocks.insert( it->ref, block.release() );
    }

    QgsRasterMatrix resultMatrix;
    resultMatrix.setNodataValue( outputNodataValue );

    //read / write line by line
    for ( int i = 0; i < mNumOutputRows; ++i )
    {
      if ( feedback )
      {
        feedback->setProgress( 100.0 * static_cast< double >( i ) / mNumOutputRows );
      }

      if ( feedback && feedback->isCanceled() )
      {
        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 )
        {
          QgsDebugMsg( QStringLiteral( "RasterIO error!" ) );
        }

        delete[] calcData;
      }

    }

    if ( feedback )
    {
      feedback->setProgress( 100.0 );
    }

    //close datasets and release memory
    calcNode.reset();
    qDeleteAll( inputBlocks );
    inputBlocks.clear();

  }

  if ( feedback && feedback->isCanceled() )
  {
    //delete the dataset without closing (because it is faster)
    gdal::fast_delete_and_close( outputDataset, outputDriver, mOutputFile );
    return Canceled;
  }
  return Success;
}
Beispiel #5
0
int QgsRelief::processRaster( QgsFeedback *feedback )
{
  //open input file
  int xSize, ySize;
  GDALDatasetH  inputDataset = openInputFile( xSize, ySize );
  if ( !inputDataset )
  {
    return 1; //opening of input file failed
  }

  //output driver
  GDALDriverH outputDriver = openOutputDriver();
  if ( !outputDriver )
  {
    return 2;
  }

  GDALDatasetH outputDataset = openOutputFile( inputDataset, outputDriver );
  if ( !outputDataset )
  {
    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 )
  {
    GDALClose( inputDataset );
    GDALClose( outputDataset );
    return 4;
  }
  mInputNodataValue = GDALGetRasterNoDataValue( rasterBand, nullptr );
  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 || !outputGreenBand || !outputBlueBand )
  {
    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, nullptr );
  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 );

  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 ( feedback )
    {
      feedback->setProgress( 100.0 * i / static_cast< double >( ySize ) );
    }

    if ( feedback && feedback->isCanceled() )
    {
      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;
      }
      if ( GDALRasterIO( rasterBand, GF_Read, 0, 0, xSize, 1, scanLine2, xSize, 1, GDT_Float32, 0, 0 )  != CE_None )
      {
        QgsDebugMsg( "Raster IO Error" );
      }
    }
    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
    {
      if ( GDALRasterIO( rasterBand, GF_Read, 0, i + 1, xSize, 1, scanLine3, xSize, 1, GDT_Float32, 0, 0 ) != CE_None )
      {
        QgsDebugMsg( "Raster IO Error" );
      }
    }

    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;
      }
    }

    if ( GDALRasterIO( outputRedBand, GF_Write, 0, i, xSize, 1, resultRedLine, xSize, 1, GDT_Byte, 0, 0 ) != CE_None )
    {
      QgsDebugMsg( "Raster IO Error" );
    }
    if ( GDALRasterIO( outputGreenBand, GF_Write, 0, i, xSize, 1, resultGreenLine, xSize, 1, GDT_Byte, 0, 0 ) != CE_None )
    {
      QgsDebugMsg( "Raster IO Error" );
    }
    if ( GDALRasterIO( outputBlueBand, GF_Write, 0, i, xSize, 1, resultBlueLine, xSize, 1, GDT_Byte, 0, 0 ) != CE_None )
    {
      QgsDebugMsg( "Raster IO Error" );
    }
  }

  if ( feedback )
  {
    feedback->setProgress( 100 );
  }

  CPLFree( resultRedLine );
  CPLFree( resultBlueLine );
  CPLFree( resultGreenLine );
  CPLFree( scanLine1 );
  CPLFree( scanLine2 );
  CPLFree( scanLine3 );

  GDALClose( inputDataset );

  if ( feedback && feedback->isCanceled() )
  {
    //delete the dataset without closing (because it is faster)
    GDALDeleteDataset( outputDriver, mOutputFile.toUtf8().constData() );
    return 7;
  }
  GDALClose( outputDataset );

  return 0;
}
Beispiel #6
0
/* actual raster band export
 * returns 0 on success
 * -1 on raster data read/write error
 * */
int export_band(GDALDatasetH hMEMDS, int band,
		const char *name, const char *mapset,
		struct Cell_head *cellhead, RASTER_MAP_TYPE maptype,
		double nodataval, int suppress_main_colortable)
{
    struct Colors sGrassColors;
    GDALColorTableH hCT;
    int iColor;
    int bHaveMinMax;
    double dfCellMin;
    double dfCellMax;
    struct FPRange sRange;
    int fd;
    int cols = cellhead->cols;
    int rows = cellhead->rows;
    int ret = 0;
    char value[200];

    /* Open GRASS raster */
    fd = Rast_open_old(name, mapset);

    /* Get raster band  */
    GDALRasterBandH hBand = GDALGetRasterBand(hMEMDS, band);

    if (hBand == NULL) {
	G_warning(_("Unable to get raster band"));
	return -1;
    }

    /* Get min/max values. */
    if (Rast_read_fp_range(name, mapset, &sRange) == -1) {
	bHaveMinMax = FALSE;
    }
    else {
	bHaveMinMax = TRUE;
	Rast_get_fp_range_min_max(&sRange, &dfCellMin, &dfCellMax);
    }

    sprintf(value, "GRASS GIS %s", GRASS_VERSION_NUMBER);
    GDALSetMetadataItem(hBand, "Generated_with", value, NULL);

    /* use default color rules if no color rules are given */
    if (Rast_read_colors(name, mapset, &sGrassColors) >= 0) {
	int maxcolor, i;
	CELL min, max;
	char key[200];
	int rcount;

	Rast_get_c_color_range(&min, &max, &sGrassColors);
	if (bHaveMinMax) {
	    if (max < dfCellMax) {
		maxcolor = max;
	    }
	    else {
		maxcolor = (int)ceil(dfCellMax);
	    }
	    if (maxcolor > GRASS_MAX_COLORS) {
		maxcolor = GRASS_MAX_COLORS;
		G_warning("Too many values, color table cut to %d entries",
			  maxcolor);
	    }
	}
	else {
	    if (max < GRASS_MAX_COLORS) {
		maxcolor = max;
	    }
	    else {
		maxcolor = GRASS_MAX_COLORS;
		G_warning("Too many values, color table set to %d entries",
			  maxcolor);
	    }
	}

	rcount = Rast_colors_count(&sGrassColors);

	G_debug(3, "dfCellMin: %f, dfCellMax: %f, maxcolor: %d", dfCellMin,
		dfCellMax, maxcolor);

	if (!suppress_main_colortable) {
	    hCT = GDALCreateColorTable(GPI_RGB);

	    for (iColor = 0; iColor <= maxcolor; iColor++) {
		int nRed, nGreen, nBlue;
		GDALColorEntry sColor;

		if (Rast_get_c_color(&iColor, &nRed, &nGreen, &nBlue,
				     &sGrassColors)) {
		    sColor.c1 = nRed;
		    sColor.c2 = nGreen;
		    sColor.c3 = nBlue;
		    sColor.c4 = 255;

		    G_debug(3,
			    "Rast_get_c_color: Y, rcount %d, nRed %d, nGreen %d, nBlue %d",
			    rcount, nRed, nGreen, nBlue);
		    GDALSetColorEntry(hCT, iColor, &sColor);
		}
		else {
		    sColor.c1 = 0;
		    sColor.c2 = 0;
		    sColor.c3 = 0;
		    sColor.c4 = 0;

		    G_debug(3,
			    "Rast_get_c_color: N, rcount %d, nRed %d, nGreen %d, nBlue %d",
			    rcount, nRed, nGreen, nBlue);
		    GDALSetColorEntry(hCT, iColor, &sColor);
		}
	    }

	    GDALSetRasterColorTable(hBand, hCT);
	}

	if (rcount > 0) {
	    /* Create metadata entries for color table rules */
	    sprintf(value, "%d", rcount);
	    GDALSetMetadataItem(hBand, "COLOR_TABLE_RULES_COUNT", value,
				NULL);
	}

	/* Add the rules in reverse order */
	/* This can cause a GDAL warning with many rules, something like
	 * Warning 1: Lost metadata writing to GeoTIFF ... too large to fit in tag. */
	for (i = rcount - 1; i >= 0; i--) {
	    DCELL val1, val2;
	    unsigned char r1, g1, b1, r2, g2, b2;

	    Rast_get_fp_color_rule(&val1, &r1, &g1, &b1, &val2, &r2, &g2, &b2,
			       &sGrassColors, i);


	    sprintf(key, "COLOR_TABLE_RULE_RGB_%d", rcount - i - 1);
	    sprintf(value, "%e %e %d %d %d %d %d %d", val1, val2, r1, g1, b1,
		    r2, g2, b2);
	    GDALSetMetadataItem(hBand, key, value, NULL);
	}
    }

    /* Create GRASS raster buffer */
    void *bufer = Rast_allocate_buf(maptype);

    if (bufer == NULL) {
	G_warning(_("Unable to allocate buffer for reading raster map"));
	return -1;
    }

    /* the following routine must be kept identical to exact_checks */

    /* Copy data form GRASS raster to GDAL raster */
    int row, col;
    int n_nulls = 0;

    /* Better use selected GDAL datatype instead of 
     * the best match with GRASS raster map types ? */

    if (maptype == FCELL_TYPE) {

	/* Source datatype understandable by GDAL */
	GDALDataType datatype = GDT_Float32;
	FCELL fnullval = (FCELL) nodataval;

	G_debug(1, "FCELL nodata val: %f", fnullval);

	for (row = 0; row < rows; row++) {

	    Rast_get_row(fd, bufer, row, maptype);
	    for (col = 0; col < cols; col++) {
		if (Rast_is_f_null_value(&((FCELL *) bufer)[col])) {
		    ((FCELL *) bufer)[col] = fnullval;
		    if (n_nulls == 0) {
			GDALSetRasterNoDataValue(hBand, nodataval);
		    }
		    n_nulls++;
		}
	    }

	    if (GDALRasterIO
		(hBand, GF_Write, 0, row, cols, 1, bufer, cols, 1, datatype,
		 0, 0) >= CE_Failure) {
		G_warning(_("Unable to write GDAL raster file"));
		return -1;
	    }
	    G_percent(row + 1, rows, 2);
	}
    }
    else if (maptype == DCELL_TYPE) {

	GDALDataType datatype = GDT_Float64;
	DCELL dnullval = (DCELL) nodataval;

	G_debug(1, "DCELL nodata val: %f", dnullval);

	for (row = 0; row < rows; row++) {

	    Rast_get_row(fd, bufer, row, maptype);
	    for (col = 0; col < cols; col++) {
		if (Rast_is_d_null_value(&((DCELL *) bufer)[col])) {
		    ((DCELL *) bufer)[col] = dnullval;
		    if (n_nulls == 0) {
			GDALSetRasterNoDataValue(hBand, nodataval);
		    }
		    n_nulls++;
		}
	    }

	    if (GDALRasterIO
		(hBand, GF_Write, 0, row, cols, 1, bufer, cols, 1, datatype,
		 0, 0) >= CE_Failure) {
		G_warning(_("Unable to write GDAL raster file"));
		return -1;
	    }
	    G_percent(row + 1, rows, 2);
	}
    }
    else {

	GDALDataType datatype = GDT_Int32;
	CELL inullval = (CELL) nodataval;

	G_debug(1, "CELL nodata val: %d", inullval);

	for (row = 0; row < rows; row++) {

	    Rast_get_row(fd, bufer, row, maptype);
	    for (col = 0; col < cols; col++) {
		if (Rast_is_c_null_value(&((CELL *) bufer)[col])) {
		    ((CELL *) bufer)[col] = inullval;
		    if (n_nulls == 0) {
			GDALSetRasterNoDataValue(hBand, nodataval);
		    }
		    n_nulls++;
		}
	    }

	    if (GDALRasterIO
		(hBand, GF_Write, 0, row, cols, 1, bufer, cols, 1, datatype,
		 0, 0) >= CE_Failure) {
		G_warning(_("Unable to write GDAL raster file"));
		return -1;
	    }
	    G_percent(row + 1, rows, 2);
	}
    }

    Rast_close(fd);

    G_free(bufer);

    return ret;
}
int
main (int argc, const char *argv[])
{
  GDALDriverH hDriver;
  double adfGeoTransform[6];
  GDALDatasetH in_Dataset;
  GDALDatasetH out_Dataset;
  double *data_scan_line;
  char *out_scan_line;
  int nBlockXSize, nBlockYSize;
  int bGotMin, bGotMax;
  int bands;
  int xsize;
  double lower_fiddle, upper_fiddle;
  double adfMinMax[2];
  /* These are hard coded for now - need to figure out a better way to handle this.. */
  double palette_in[256] =
    { 0.0, 1.00011, 1.9999649999999998, 3.000075, 3.9999299999999995, 5.00004,
    5.999895, 7.000005, 8.000115, 8.99997, 10.00008, 10.999935,
    12.000044999999998, 12.9999,
    14.00001, 15.00012, 15.999975, 17.000085000000002, 17.99994, 19.00005,
    19.999905000000002,
    21.000014999999998, 22.000125, 22.99998, 24.000089999999997, 24.999945,
    26.000055, 26.99991,
    28.00002, 28.999875000000003, 29.999985, 31.000094999999998, 31.99995,
    33.00006, 33.999915,
    35.000024999999994, 35.99988, 36.999990000000004, 38.0001, 38.999955,
    40.000065, 40.99992,
    42.000029999999995, 42.999885, 43.999995000000006, 45.000105, 45.99996,
    47.00007,
    47.999925000000005, 49.000035, 49.99989, 51.0, 52.00011, 52.999965,
    54.000075, 54.99993,
    56.00004, 56.999895, 58.000004999999994, 59.000115, 59.99997,
    61.000080000000004, 61.999935,
    63.000045, 63.9999, 65.00001, 66.00012, 66.999975, 68.000085, 68.99994,
    70.00004999999999,
    70.999905, 72.000015, 73.000125, 73.99998000000001, 75.00009, 75.999945,
    77.00005499999999,
    77.99991, 79.00002, 79.99987499999999, 80.99998500000001, 82.000095,
    82.99995,
    84.00005999999999, 84.999915, 86.00002500000001, 86.99987999999999,
    87.99999000000001, 89.0001,
    89.999955, 91.00006499999999, 91.99992, 93.00003, 93.99988499999999,
    94.999995, 96.000105,
    96.99996, 98.00007, 98.999925, 100.000035, 100.99989, 102.0, 103.00011,
    103.999965, 105.000075,
    105.99993, 107.00004, 107.999895, 109.000005, 110.00011500000001,
    110.99997, 112.00008,
    112.99993500000001, 114.000045, 114.9999, 116.00000999999999, 117.00012,
    117.999975,
    119.000085, 119.99994, 121.00005, 121.999905, 123.00001499999999,
    124.000125,
    124.99998000000001, 126.00009, 126.999945, 128.000055, 128.99991,
    130.00002, 130.999875,
    131.99998499999998, 133.000095, 133.99995, 135.00006, 135.999915,
    137.00002500000002,
    137.99988, 138.99999, 140.00009999999997, 140.999955, 142.000065,
    142.99991999999997,
    144.00003, 144.999885, 145.99999499999998, 147.000105, 147.99996000000002,
    149.00007,
    149.999925, 151.00003500000003, 151.99989, 153.0, 154.00010999999998,
    154.999965, 156.000075,
    156.99992999999998, 158.00004, 158.999895, 160.000005, 161.000115,
    161.99997000000002,
    163.00008, 163.999935, 165.000045, 165.9999, 167.00001,
    168.00011999999998, 168.999975,
    170.000085, 170.99993999999998, 172.00005000000002, 172.999905,
    174.000015, 175.000125,
    175.99998000000002, 177.00009, 177.999945, 179.00005499999997, 179.99991,
    181.00002,
    181.999875, 182.999985, 184.00009500000002, 184.99994999999998, 186.00006,
    186.99991500000002,
    188.000025, 188.99988, 189.99999, 191.0001, 191.999955,
    193.00006499999998, 193.99992,
    195.00003, 195.99988499999998, 196.999995, 198.00010500000002, 198.99996,
    200.00007,
    200.99992500000002, 202.000035, 202.99989, 204.0, 205.00011, 205.999965,
    207.00007499999998,
    207.99993, 209.00004, 209.99989499999998, 211.00000500000002, 212.000115,
    212.99997, 214.00008,
    214.999935, 216.000045, 216.9999, 218.00001, 219.00012, 219.999975,
    221.00008499999998,
    221.99994, 223.00005000000002, 223.99990499999998, 225.00001500000002,
    226.000125, 226.99998,
    228.00009, 228.999945, 230.000055, 230.99991, 232.00001999999998,
    232.999875, 233.999985,
    235.000095, 235.99995, 237.00006, 237.999915, 239.000025, 239.99988,
    240.99999, 242.0001,
    242.999955, 244.000065, 244.99992, 246.00002999999998, 246.999885,
    247.999995, 249.000105,
    249.99996000000002, 251.00007, 251.999925, 253.000035, 253.99989, 255.0
  };
  double palette_out[256] =
    { 0.0, 0.042075, 0.08415, 0.126225, 0.169065, 0.21216, 0.255765, 0.29988,
    0.345015, 0.390915, 0.437835, 0.48602999999999996, 0.5352450000000001,
    0.58599, 0.63801,
    0.69156, 0.7468950000000001, 0.804015, 0.8629199999999999,
    0.9238649999999999, 0.98685, 1.05213,
    1.119705, 1.18983, 1.26225, 1.337475, 1.415505, 1.49634, 1.580235,
    1.6674449999999998, 1.75746,
    1.851045, 1.9482, 2.04867, 2.152965, 2.2608300000000003,
    2.3727750000000003, 2.4885450000000002,
    2.6083950000000002, 2.73258, 2.8611000000000004, 2.993955,
    3.1313999999999997, 3.27369, 3.42057,
    3.572295, 3.72912, 3.891045, 4.05807, 4.23045, 4.408440000000001,
    4.591785, 4.780995, 4.975815,
    5.1765, 5.38305, 5.595975, 5.8150200000000005, 6.040185, 6.27198,
    6.510405, 6.755205, 7.007145,
    7.265715, 7.53117, 7.8040199999999995, 8.084010000000001, 8.37114,
    8.66592, 8.968095, 9.27792,
    9.59565, 9.92103, 10.25457, 10.596015, 10.945875, 11.30415, 11.670585,
    12.04569, 12.429465,
    12.82191, 13.223279999999999, 13.63383, 14.053305, 14.48196,
    14.919794999999999, 15.36732,
    15.82428, 16.29093, 16.767270000000003, 17.253555, 17.749785, 18.256215,
    18.925845,
    19.456245000000003, 19.99863, 20.552745, 21.11859, 21.696165, 22.285725,
    22.887014999999998,
    23.500035, 24.125295, 24.762285, 25.411260000000002, 26.071965, 26.74491,
    27.42984, 28.12701,
    28.835910000000002, 29.55705, 30.29043, 31.035795, 31.7934, 32.56299,
    33.345075, 34.139145,
    34.94571, 35.764514999999996, 36.595305, 37.438845, 38.294625, 39.162645,
    40.04316, 40.935915,
    41.84142, 42.759165, 43.68966, 44.632394999999995, 45.58788, 46.55586,
    47.536335,
    48.529560000000004, 49.535535, 50.554005000000004, 51.58497, 52.62894,
    53.68566, 54.75513,
    55.837095, 56.932064999999994, 58.040040000000005, 59.160765,
    60.294239999999995, 61.44072,
    62.59995000000001, 63.772439999999996, 64.95768000000001,
    66.15592500000001, 67.36743,
    68.591685, 69.82919999999999, 71.07972, 72.343245, 73.620285, 74.910075,
    76.21337999999999,
    77.52968999999999, 78.85926, 80.20209, 81.55843499999999, 82.927785,
    84.31065, 85.66419,
    87.10264500000001, 88.611225, 90.18712500000001, 91.82779500000001,
    93.52992, 95.291205,
    97.108845, 98.979525, 100.90095, 102.87006, 104.884305, 106.94037,
    109.03596, 111.16827,
    113.33424000000001, 115.531065, 117.756195, 120.00657, 122.27964,
    124.572345,
    126.88213499999999, 129.20595, 131.54124, 133.8852, 136.23477,
    138.58714500000002, 140.939775,
    143.289855, 145.63458, 147.97089, 150.296235, 152.60781, 154.902555,
    157.17817499999998,
    159.431355, 161.65929, 163.859685, 166.02948, 168.165615, 170.26554,
    172.32645, 174.34554,
    176.320005, 178.24704, 180.292905, 182.130945, 183.953685, 185.76138,
    187.554285, 189.33291,
    191.09751, 192.84834, 194.58591, 196.310475, 198.02229, 199.72161,
    201.4092, 203.084805,
    204.74944499999998, 206.402865, 208.04557499999999, 209.67808499999998,
    211.30065, 212.913525,
    214.516965, 216.11148, 217.69758000000002, 219.27501, 220.84479,
    222.406665, 223.9614,
    225.50924999999998, 227.05047000000002, 228.585315, 230.114295,
    231.63766500000003,
    233.15568000000002, 234.66885000000002, 236.17743, 237.681675, 239.18184,
    240.67869, 242.172225,
    243.66295499999998, 245.15088, 246.636765, 248.12061000000003, 249.602925,
    251.083965,
    252.56424, 254.04375, 255.0
  };


  GDALAllRegister ();


  /* ussage.. */
  if (argc != 3)
    ussage ();

  /* Set cache to something reasonable.. - 1/2 gig */
  CPLSetConfigOption ("GDAL_CACHEMAX", "512");

  /* open datasets.. */
  in_Dataset = GDAL_open_read (argv[1]);
  out_Dataset = make_me_a_sandwitch (&in_Dataset, argv[2]);

  /* Basic info on source dataset.. */
  GDALGetBlockSize (GDALGetRasterBand (in_Dataset, 1), &nBlockXSize,
		    &nBlockYSize);
  printf ("Block=%dx%d Type=%s, ColorInterp=%s\n", nBlockXSize, nBlockYSize,
	  GDALGetDataTypeName (GDALGetRasterDataType
			       (GDALGetRasterBand (in_Dataset, 1))),
	  GDALGetColorInterpretationName (GDALGetRasterColorInterpretation
					  (GDALGetRasterBand
					   (in_Dataset, 1))));

  /* Loop though bands, scaling the data.. */
  xsize = GDALGetRasterXSize (in_Dataset);
  data_scan_line = (double *) CPLMalloc (sizeof (double) * xsize);
  out_scan_line = (char *) CPLMalloc (sizeof (char) * xsize);

  for (bands = 1; bands <= GDALGetRasterCount (in_Dataset); bands++)
    {
      int x;
      double min = 9999999.0, max = 0.0;	/* probibly a better way to set these.. */
      double dmin, dmax, middle;
      GDALRasterBandH data_band, out_band;
      int y_index = 0;
      data_band = GDALGetRasterBand (in_Dataset, bands);
      out_band = GDALGetRasterBand (out_Dataset, bands);

      /* Set nodata for that band */
      GDALSetRasterNoDataValue (out_band, 0.0);

      /*Find Min,Max, required for scaling */
      for (y_index = 0; y_index < GDALGetRasterYSize (in_Dataset); y_index++)
	{
	  /* Read data.. */
	  GDALRasterIO (data_band, GF_Read, 0, y_index, xsize, 1,
			data_scan_line, xsize, 1, GDT_Float64, 0, 0);
	  for (x = 0; x < xsize; x++)
	    {
	      if (data_scan_line[x] < MAX_MODIS
		  && data_scan_line[x] > MIN_VALUE)
		{
		  if (data_scan_line[x] > max)
		    max = data_scan_line[x];
		  else if (data_scan_line[x] < min)
		    min = data_scan_line[x];
		}
	    }
	}

      dmax = (double) max;
      dmin = (double) min;

      printf ("Info: For Band %d -> Min=%g,Max=%g\n", bands, dmin, dmax);

      for (y_index = 0; y_index < GDALGetRasterYSize (in_Dataset); y_index++)
	{
	  double scaled;

	  /* Read data.. */
	  GDALRasterIO (data_band, GF_Read, 0, y_index, xsize, 1,
			data_scan_line, xsize, 1, GDT_Float64, 0, 0);

	  /* scale each .. */
	  for (x = 0; x < xsize; x++)
	    {
	      out_scan_line[x] =
		scale (palette_in, palette_out, data_scan_line[x], dmin,
		       dmax);
	    }

	  /* now write out band.. */
	  GDALRasterIO (out_band, GF_Write, 0, y_index, xsize, 1,
			out_scan_line, xsize, 1, GDT_Byte, 0, 0);
	}

    }


  /* close file, and we are done. */
  GDALClose (out_Dataset);

}
Beispiel #8
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();

  GDALDriverH myDriver = GDALGetDriverByName( d.outputFormat().toUtf8() );
  if ( !myDriver )
  {
    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 };
  GDALDatasetH emptyDataset = GDALCreate( myDriver, d.outputFilename().toUtf8(), columns, rows, 1, GDT_Float32, nullptr );
  GDALSetGeoTransform( emptyDataset, geoTransform );
  // Set the projection on the raster destination to match the input layer
  GDALSetProjection( emptyDataset, inputLayer->crs().toWkt().toLocal8Bit().data() );

  GDALRasterBandH poBand = GDALGetRasterBand( emptyDataset, 1 );
  GDALSetRasterNoDataValue( poBand, 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++ )
  {
    if ( GDALRasterIO( poBand, GF_Write, 0, i, columns, 1, line, columns, 1, GDT_Float32, 0, 0 ) != CE_None )
    {
      QgsDebugMsg( "Raster IO Error" );
    }
  }

  CPLFree( line );
  //close the dataset
  GDALClose( emptyDataset );

  // open the raster in GA_Update mode
  GDALDatasetH heatmapDS = 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 = GDALGetRasterBand( heatmapDS, 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::LayerUnits )
    {
      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( "Rendering heatmap..." ), tr( "Abort" ), 0, totalFeatures, mQGisIface->mainWindow() );
  p.setWindowTitle( tr( "QGIS" ) );
  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;
    }

    const QgsGeometry* featureGeometry = myFeature.constGeometry();
    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 );
      if ( GDALRasterIO( poBand, GF_Read, xPosition, yPosition, blockSize, blockSize,
                         dataBuffer, blockSize, blockSize, GDT_Float32, 0, 0 ) != CE_None )
      {
        QgsDebugMsg( "Raster IO Error" );
      }

      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;
          }
        }
      }
      if ( GDALRasterIO( poBand, GF_Write, xPosition, yPosition, blockSize, blockSize,
                         dataBuffer, blockSize, blockSize, GDT_Float32, 0, 0 ) != CE_None )
      {
        QgsDebugMsg( "Raster IO Error" );
      }
      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() );
  }

}
Beispiel #9
0
void CUtils::calculateByteGeoTIFFStatistics(GDALDatasetH hDataset, int userBandNumber, byte flNoDataValueAsBackground, byte NoDataValue)
{
	fputs("\nCalculate statistics...\n", stderr);

	GDALRasterBandH hBand =  GDALGetRasterBand(hDataset, 1);
	int cols  = GDALGetRasterBandXSize(hBand);
	int rows  = GDALGetRasterBandYSize(hBand);
	int bands = GDALGetRasterCount(hDataset);
	
	byte * pbuf = NULL;
	pbuf = (byte *)CPLMalloc(sizeof(byte)*cols);
	
	byte min = 0, max = 0, mean = 0;
	double stddev = 0;
    double summ = 0;
    int count = 0;
	
	for(int band=1; band<=bands; band++)
	{
		if(userBandNumber != -1) fprintf(stderr, "Band %d...\n", userBandNumber);
		else fprintf(stderr, "Band %d...\n", band);
		
		hBand =  GDALGetRasterBand(hDataset, band);		
		if(flNoDataValueAsBackground) NoDataValue = getFloatNoDataValueAsBackground(hBand);
		
		min = max = mean = stddev = summ = 0;
		count = 0;
		bool flFirst = true;
		
		int pr = CUtils::progress_ln_ex(stderr, 0, 0, START_PROGRESS);
		for(int i=0; i<rows; i++)
		{
			GDALRasterIO(hBand, GF_Read, 0, i, cols, 1, pbuf, cols, 1, GDT_Byte, 0, 0 );
			for(int j=0; j<cols; j++) if(pbuf[j]!=NoDataValue) 
			{
				if(flFirst)
				{
					mean = pbuf[j];
					min = max = mean;
					flFirst = false;
				}
				else
				{
					mean += pbuf[j];
					if( min > pbuf[j] ) min = pbuf[j];
					if( max < pbuf[j] ) max = pbuf[j];
				}
				count++;
			}
			pr = CUtils::progress_ln_ex(stderr, i, rows, pr);
		}
		CUtils::progress_ln_ex(stderr, 0, 0, END_PROGRESS);
		
		double dmean = 0;
		if(count > 0) dmean = mean / (double)count;
		
		pr = CUtils::progress_ln_ex(stderr, 0, 0, START_PROGRESS);
		for(int i=0; i<rows; i++)
		{
			GDALRasterIO(hBand, GF_Read, 0, i, cols, 1, pbuf, cols, 1, GDT_Byte, 0, 0 );
			for(int j=0; j<cols; j++) if(pbuf[j]!=NoDataValue) summ += ((double)pbuf[j]-dmean)*((double)pbuf[j]-dmean);
						
			pr = CUtils::progress_ln_ex(stderr, i, rows, pr);
		}
		CUtils::progress_ln_ex(stderr, 0, 0, END_PROGRESS);
		
		summ = 0; stddev = 0;
		if((count-1)>0)
		{
			summ /= (double)(count-1);
			if(summ!=0) stddev = sqrt(summ);
		}
			
		GDALSetRasterStatistics(hBand, min, max, mean, stddev);
		GDALSetRasterNoDataValue(hBand, NoDataValue);
	}
	
	CPLFree(pbuf);
}
Beispiel #10
0
int main( int argc, char ** argv )
{
    GDALDriverH     hDriver;
    const char      *pszSource=NULL, *pszDest=NULL, *pszFormat = "GTiff";
    int             bFormatExplicitlySet = FALSE;
    char            **papszLayers = NULL;
    const char      *pszBurnAttribute = NULL;
    double          dfIncreaseBurnValue = 0.0;
    double          dfMultiplyBurnValue = 1.0;
    const char      *pszWHERE = NULL, *pszSQL = NULL;
    GDALDataType    eOutputType = GDT_Float64;
    char            **papszCreateOptions = NULL;
    GUInt32         nXSize = 0, nYSize = 0;
    double          dfXMin = 0.0, dfXMax = 0.0, dfYMin = 0.0, dfYMax = 0.0;
    int             bIsXExtentSet = FALSE, bIsYExtentSet = FALSE;
    GDALGridAlgorithm eAlgorithm = GGA_InverseDistanceToAPower;
    void            *pOptions = NULL;
    char            *pszOutputSRS = NULL;
    int             bQuiet = FALSE;
    GDALProgressFunc pfnProgress = GDALTermProgress;
    int             i;
    OGRGeometry     *poSpatialFilter = NULL;
    int             bClipSrc = FALSE;
    OGRGeometry     *poClipSrc = NULL;
    const char      *pszClipSrcDS = NULL;
    const char      *pszClipSrcSQL = NULL;
    const char      *pszClipSrcLayer = NULL;
    const char      *pszClipSrcWhere = NULL;
    int              bNoDataSet = FALSE;
    double           dfNoDataValue = 0;

    /* Check strict compilation and runtime library version as we use C++ API */
    if (! GDAL_CHECK_VERSION(argv[0]))
        exit(1);

    GDALAllRegister();
    OGRRegisterAll();

    argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
    if( argc < 1 )
        exit( -argc );

/* -------------------------------------------------------------------- */
/*      Parse arguments.                                                */
/* -------------------------------------------------------------------- */
    for( i = 1; i < argc; i++ )
    {
        if( EQUAL(argv[i], "--utility_version") )
        {
            printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
                   argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
            return 0;
        }
        else if( EQUAL(argv[i],"--help") )
            Usage();
        else if( EQUAL(argv[i],"-of") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszFormat = argv[++i];
            bFormatExplicitlySet = TRUE;
        }

        else if( EQUAL(argv[i],"-q") || EQUAL(argv[i],"-quiet") )
        {
            bQuiet = TRUE;
            pfnProgress = GDALDummyProgress;
        }

        else if( EQUAL(argv[i],"-ot") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            int	iType;
            
            for( iType = 1; iType < GDT_TypeCount; iType++ )
            {
                if( GDALGetDataTypeName((GDALDataType)iType) != NULL
                    && EQUAL(GDALGetDataTypeName((GDALDataType)iType),
                             argv[i+1]) )
                {
                    eOutputType = (GDALDataType) iType;
                }
            }

            if( eOutputType == GDT_Unknown )
            {
                Usage(CPLSPrintf("Unknown output pixel type: %s.",
                                 argv[i + 1] ));
            }
            i++;
        }

        else if( EQUAL(argv[i],"-txe") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2);
            dfXMin = CPLAtof(argv[++i]);
            dfXMax = CPLAtof(argv[++i]);
            bIsXExtentSet = TRUE;
        }   

        else if( EQUAL(argv[i],"-tye") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2);
            dfYMin = CPLAtof(argv[++i]);
            dfYMax = CPLAtof(argv[++i]);
            bIsYExtentSet = TRUE;
        }   

        else if( EQUAL(argv[i],"-outsize") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2);
            nXSize = atoi(argv[++i]);
            nYSize = atoi(argv[++i]);
        }   

        else if( EQUAL(argv[i],"-co") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            papszCreateOptions = CSLAddString( papszCreateOptions, argv[++i] );
        }   

        else if( EQUAL(argv[i],"-zfield") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszBurnAttribute = argv[++i];
        }

        else if( EQUAL(argv[i],"-z_increase") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            dfIncreaseBurnValue = CPLAtof(argv[++i]);
        }

        else if( EQUAL(argv[i],"-z_multiply") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            dfMultiplyBurnValue = CPLAtof(argv[++i]);
        }

        else if( EQUAL(argv[i],"-where") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszWHERE = argv[++i];
        }

        else if( EQUAL(argv[i],"-l") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            papszLayers = CSLAddString( papszLayers, argv[++i] );
        }

        else if( EQUAL(argv[i],"-sql") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszSQL = argv[++i];
        }

        else if( EQUAL(argv[i],"-spat") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(4);
            OGRLinearRing  oRing;

            oRing.addPoint( CPLAtof(argv[i+1]), CPLAtof(argv[i+2]) );
            oRing.addPoint( CPLAtof(argv[i+1]), CPLAtof(argv[i+4]) );
            oRing.addPoint( CPLAtof(argv[i+3]), CPLAtof(argv[i+4]) );
            oRing.addPoint( CPLAtof(argv[i+3]), CPLAtof(argv[i+2]) );
            oRing.addPoint( CPLAtof(argv[i+1]), CPLAtof(argv[i+2]) );

            poSpatialFilter = new OGRPolygon();
            ((OGRPolygon *) poSpatialFilter)->addRing( &oRing );
            i += 4;
        }

        else if ( EQUAL(argv[i],"-clipsrc") )
        {
            if (i + 1 >= argc)
                Usage(CPLSPrintf("%s option requires 1 or 4 arguments", argv[i]));

            bClipSrc = TRUE;
            errno = 0;
            const double unused = strtod( argv[i + 1], NULL );    // XXX: is it a number or not?
            if ( errno != 0
                 && argv[i + 2] != NULL
                 && argv[i + 3] != NULL
                 && argv[i + 4] != NULL)
            {
                OGRLinearRing  oRing;

                oRing.addPoint( CPLAtof(argv[i + 1]), CPLAtof(argv[i + 2]) );
                oRing.addPoint( CPLAtof(argv[i + 1]), CPLAtof(argv[i + 4]) );
                oRing.addPoint( CPLAtof(argv[i + 3]), CPLAtof(argv[i + 4]) );
                oRing.addPoint( CPLAtof(argv[i + 3]), CPLAtof(argv[i + 2]) );
                oRing.addPoint( CPLAtof(argv[i + 1]), CPLAtof(argv[i + 2]) );

                poClipSrc = new OGRPolygon();
                ((OGRPolygon *) poClipSrc)->addRing( &oRing );
                i += 4;

                (void)unused;
            }
            else if (EQUALN(argv[i + 1], "POLYGON", 7)
                     || EQUALN(argv[i + 1], "MULTIPOLYGON", 12))
            {
                OGRGeometryFactory::createFromWkt(&argv[i + 1], NULL, &poClipSrc);
                if ( poClipSrc == NULL )
                {
                    Usage("Invalid geometry. "
                             "Must be a valid POLYGON or MULTIPOLYGON WKT.");
                }
                i++;
            }
            else if (EQUAL(argv[i + 1], "spat_extent") )
            {
                i++;
            }
            else
            {
                pszClipSrcDS = argv[i + 1];
                i++;
            }
        }

        else if ( EQUAL(argv[i], "-clipsrcsql") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszClipSrcSQL = argv[i + 1];
            i++;
        }

        else if ( EQUAL(argv[i], "-clipsrclayer") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszClipSrcLayer = argv[i + 1];
            i++;
        }

        else if ( EQUAL(argv[i], "-clipsrcwhere") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszClipSrcWhere = argv[i + 1];
            i++;
        }

        else if( EQUAL(argv[i],"-a_srs") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            OGRSpatialReference oOutputSRS;

            if( oOutputSRS.SetFromUserInput( argv[i+1] ) != OGRERR_NONE )
            {
                fprintf( stderr, "Failed to process SRS definition: %s\n", 
                         argv[i+1] );
                GDALDestroyDriverManager();
                exit( 1 );
            }

            oOutputSRS.exportToWkt( &pszOutputSRS );
            i++;
        }   

        else if( EQUAL(argv[i],"-a") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            const char* pszAlgorithm = argv[++i];
            if ( ParseAlgorithmAndOptions( pszAlgorithm, &eAlgorithm, &pOptions )
                 != CE_None )
            {
                fprintf( stderr,
                         "Failed to process algorithm name and parameters.\n" );
                exit( 1 );
            }
            
            char **papszParms = CSLTokenizeString2( pszAlgorithm, ":", FALSE );
            const char* pszNoDataValue = CSLFetchNameValue( papszParms, "nodata" );
            if( pszNoDataValue != NULL )
            {
                bNoDataSet = TRUE;
                dfNoDataValue = CPLAtofM(pszNoDataValue);
            }
            CSLDestroy(papszParms);
        }

        else if( argv[i][0] == '-' )
        {
            Usage(CPLSPrintf("Unknown option name '%s'", argv[i]));
        }

        else if( pszSource == NULL )
        {
            pszSource = argv[i];
        }

        else if( pszDest == NULL )
        {
            pszDest = argv[i];
        }

        else
        {
            Usage("Too many command options.");
        }
    }

    if( pszSource == NULL )
    {
        Usage("Source datasource is not specified.");
    }
    if( pszDest == NULL )
    {
        Usage("Target dataset is not specified.");
    }
    if( pszSQL == NULL && papszLayers == NULL )
    {
        Usage("Neither -sql nor -l are specified.");
    }
    
    if ( bClipSrc && pszClipSrcDS != NULL )
    {
        poClipSrc = LoadGeometry( pszClipSrcDS, pszClipSrcSQL,
                                  pszClipSrcLayer, pszClipSrcWhere );
        if ( poClipSrc == NULL )
        {
            Usage("Cannot load source clip geometry.");
        }
    }
    else if ( bClipSrc && poClipSrc == NULL && !poSpatialFilter )
    {
        Usage("-clipsrc must be used with -spat option or \n"
                 "a bounding box, WKT string or datasource must be "
                 "specified.");
    }

    if ( poSpatialFilter )
    {
        if ( poClipSrc )
        {
            OGRGeometry *poTemp = poSpatialFilter->Intersection( poClipSrc );

            if ( poTemp )
            {
                OGRGeometryFactory::destroyGeometry( poSpatialFilter );
                poSpatialFilter = poTemp;
            }

            OGRGeometryFactory::destroyGeometry( poClipSrc );
            poClipSrc = NULL;
        }
    }
    else
    {
        if ( poClipSrc )
        {
            poSpatialFilter = poClipSrc;
            poClipSrc = NULL;
        }
    }

/* -------------------------------------------------------------------- */
/*      Find the output driver.                                         */
/* -------------------------------------------------------------------- */
    hDriver = GDALGetDriverByName( pszFormat );
    if( hDriver == NULL )
    {
        int	iDr;
        
        fprintf( stderr,
                 "FAILURE: Output driver `%s' not recognised.\n", pszFormat );
        fprintf( stderr,
        "The following format drivers are configured and support output:\n" );
        for( iDr = 0; iDr < GDALGetDriverCount(); iDr++ )
        {
            GDALDriverH hDriver = GDALGetDriver(iDr);

            if( GDALGetMetadataItem( hDriver, GDAL_DCAP_RASTER, NULL) != NULL &&
                ( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) != NULL
                || GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATECOPY, NULL ) != NULL) )
            {
                fprintf( stderr, "  %s: %s\n",
                         GDALGetDriverShortName( hDriver  ),
                         GDALGetDriverLongName( hDriver ) );
            }
        }
        printf( "\n" );
        Usage();
    }

/* -------------------------------------------------------------------- */
/*      Open input datasource.                                          */
/* -------------------------------------------------------------------- */
    OGRDataSourceH hSrcDS;

    hSrcDS = OGROpen( pszSource, FALSE, NULL );
    if( hSrcDS == NULL )
    {
        fprintf( stderr, "Unable to open input datasource \"%s\".\n",
                 pszSource );
        fprintf( stderr, "%s\n", CPLGetLastErrorMsg() );
        exit( 3 );
    }

/* -------------------------------------------------------------------- */
/*      Create target raster file.                                      */
/* -------------------------------------------------------------------- */
    GDALDatasetH    hDstDS;
    int             nLayerCount = CSLCount(papszLayers);
    int             nBands = nLayerCount;

    if ( pszSQL )
        nBands++;

    // FIXME
    if ( nXSize == 0 )
        nXSize = 256;
    if ( nYSize == 0 )
        nYSize = 256;

    if (!bQuiet && !bFormatExplicitlySet)
        CheckExtensionConsistency(pszDest, pszFormat);

    hDstDS = GDALCreate( hDriver, pszDest, nXSize, nYSize, nBands,
                         eOutputType, papszCreateOptions );
    if ( hDstDS == NULL )
    {
        fprintf( stderr, "Unable to create target dataset \"%s\".\n",
                 pszDest );
        fprintf( stderr, "%s\n", CPLGetLastErrorMsg() );
        exit( 3 );
    }
    
    if( bNoDataSet )
    {
        for( i = 1; i <= nBands; i++ )
        {
            GDALRasterBandH hBand = GDALGetRasterBand( hDstDS, i );
            GDALSetRasterNoDataValue( hBand, dfNoDataValue );
        }
    }

/* -------------------------------------------------------------------- */
/*      If algorithm was not specified assigh default one.              */
/* -------------------------------------------------------------------- */
    if ( !pOptions )
        ParseAlgorithmAndOptions( szAlgNameInvDist, &eAlgorithm, &pOptions );

/* -------------------------------------------------------------------- */
/*      Process SQL request.                                            */
/* -------------------------------------------------------------------- */
    if( pszSQL != NULL )
    {
        OGRLayerH hLayer;

        hLayer = OGR_DS_ExecuteSQL( hSrcDS, pszSQL,
                                    (OGRGeometryH)poSpatialFilter, NULL ); 
        if( hLayer != NULL )
        {
            // Custom layer will be rasterized in the first band.
            ProcessLayer( hLayer, hDstDS, poSpatialFilter, nXSize, nYSize, 1,
                          bIsXExtentSet, bIsYExtentSet,
                          dfXMin, dfXMax, dfYMin, dfYMax, pszBurnAttribute,
                          dfIncreaseBurnValue, dfMultiplyBurnValue, eOutputType, eAlgorithm, pOptions,
                          bQuiet, pfnProgress );
        }
    }

/* -------------------------------------------------------------------- */
/*      Process each layer.                                             */
/* -------------------------------------------------------------------- */
    for( i = 0; i < nLayerCount; i++ )
    {
        OGRLayerH hLayer = OGR_DS_GetLayerByName( hSrcDS, papszLayers[i]);
        if( hLayer == NULL )
        {
            fprintf( stderr, "Unable to find layer \"%s\", skipping.\n", 
                     papszLayers[i] );
            continue;
        }

        if( pszWHERE )
        {
            if( OGR_L_SetAttributeFilter( hLayer, pszWHERE ) != OGRERR_NONE )
                break;
        }

        if ( poSpatialFilter != NULL )
            OGR_L_SetSpatialFilter( hLayer, (OGRGeometryH)poSpatialFilter );

        // Fetch the first meaningful SRS definition
        if ( !pszOutputSRS )
        {
            OGRSpatialReferenceH hSRS = OGR_L_GetSpatialRef( hLayer );
            if ( hSRS )
                OSRExportToWkt( hSRS, &pszOutputSRS );
        }

        ProcessLayer( hLayer, hDstDS, poSpatialFilter, nXSize, nYSize,
                      i + 1 + nBands - nLayerCount,
                      bIsXExtentSet, bIsYExtentSet,
                      dfXMin, dfXMax, dfYMin, dfYMax, pszBurnAttribute,
                      dfIncreaseBurnValue, dfMultiplyBurnValue, eOutputType, eAlgorithm, pOptions,
                      bQuiet, pfnProgress );
    }

/* -------------------------------------------------------------------- */
/*      Apply geotransformation matrix.                                 */
/* -------------------------------------------------------------------- */
    double  adfGeoTransform[6];
    adfGeoTransform[0] = dfXMin;
    adfGeoTransform[1] = (dfXMax - dfXMin) / nXSize;
    adfGeoTransform[2] = 0.0;
    adfGeoTransform[3] = dfYMin;
    adfGeoTransform[4] = 0.0;
    adfGeoTransform[5] = (dfYMax - dfYMin) / nYSize;
    GDALSetGeoTransform( hDstDS, adfGeoTransform );

/* -------------------------------------------------------------------- */
/*      Apply SRS definition if set.                                    */
/* -------------------------------------------------------------------- */
    if ( pszOutputSRS )
    {
        GDALSetProjection( hDstDS, pszOutputSRS );
        CPLFree( pszOutputSRS );
    }

/* -------------------------------------------------------------------- */
/*      Cleanup                                                         */
/* -------------------------------------------------------------------- */
    OGR_DS_Destroy( hSrcDS );
    GDALClose( hDstDS );
    OGRGeometryFactory::destroyGeometry( poSpatialFilter );

    CPLFree( pOptions );
    CSLDestroy( papszCreateOptions );
    CSLDestroy( argv );
    CSLDestroy( papszLayers );

    OGRCleanupAll();

    GDALDestroyDriverManager();
 
    return 0;
}
Beispiel #11
0
int QgsNineCellFilter::processRaster( QProgressDialog* p )
{
  GDALAllRegister();

  //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
  }

  //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 );

  GDALRasterBandH outputRasterBand = GDALGetRasterBand( outputDataset, 1 );
  if ( outputRasterBand == NULL )
  {
    GDALClose( inputDataset );
    GDALClose( outputDataset );
    return 5;
  }
  //try to set -9999 as nodata value
  GDALSetRasterNoDataValue( outputRasterBand, -9999 );
  mOutputNodataValue = GDALGetRasterNoDataValue( outputRasterBand, NULL );

  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 );

  float* resultLine = ( float * ) CPLMalloc( sizeof( float ) * xSize );

  if ( p )
  {
    p->setMaximum( ySize );
  }

  //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 )
      {
        resultLine[j] = processNineCellWindow( &mInputNodataValue, &scanLine1[j], &scanLine1[j+1], &mInputNodataValue, &scanLine2[j], \
                                               &scanLine2[j+1], &mInputNodataValue, &scanLine3[j], &scanLine3[j+1] );
      }
      else if ( j == xSize - 1 )
      {
        resultLine[j] = processNineCellWindow( &scanLine1[j-1], &scanLine1[j], &mInputNodataValue, &scanLine2[j-1], &scanLine2[j], \
                                               &mInputNodataValue, &scanLine3[j-1], &scanLine3[j], &mInputNodataValue );
      }
      else
      {
        resultLine[j] = 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] );
      }
    }

    GDALRasterIO( outputRasterBand, GF_Write, 0, i, xSize, 1, resultLine, xSize, 1, GDT_Float32, 0, 0 );
  }

  if ( p )
  {
    p->setValue( ySize );
  }

  CPLFree( resultLine );
  CPLFree( scanLine1 );
  CPLFree( scanLine2 );
  CPLFree( scanLine3 );

  GDALClose( inputDataset );

  if ( p && p->wasCanceled() )
  {
    //delete the dataset without closing (because it is faster)
    GDALDeleteDataset( outputDriver, mOutputFile.toLocal8Bit().data() );
    return 7;
  }
  GDALClose( outputDataset );

  return 0;
}
Beispiel #12
0
int
main (int argc, const char *argv[])
{
  GDALDriverH hDriver;
  double adfGeoTransform[6];
  GDALDatasetH in_Dataset;
  GDALDatasetH mask_Dataset;
  GDALDatasetH out_Dataset;
  GDALRasterBandH mask_band;
  char *mask_scan_line, *data_scan_line;
  int nBlockXSize, nBlockYSize;
  int bGotMin, bGotMax;
  int bands;
  int xsize;
  double adfMinMax[2];

  GDALAllRegister ();

  /* Set cache to something reasonable.. - 1/2 gig */
  CPLSetConfigOption ("GDAL_CACHEMAX", "512");

  /* open datasets.. */
  in_Dataset = GDAL_open_read (argv[1]);
  mask_Dataset = GDAL_open_read (argv[2]);
  out_Dataset = make_me_a_sandwitch (&in_Dataset, argv[3]);

  mask_band = GDALGetRasterBand (mask_Dataset, 1);

  /* Basic info on source dataset.. */
  GDALGetBlockSize (GDALGetRasterBand (in_Dataset, 1), &nBlockXSize,
		    &nBlockYSize);
  printf ("Block=%dx%d Type=%s, ColorInterp=%s\n", nBlockXSize, nBlockYSize,
	  GDALGetDataTypeName (GDALGetRasterDataType
			       (GDALGetRasterBand (in_Dataset, 1))),
	  GDALGetColorInterpretationName (GDALGetRasterColorInterpretation
					  (GDALGetRasterBand
					   (in_Dataset, 1))));

  /* Loop though bands, wiping values with mask values of 0.. */
  xsize = GDALGetRasterXSize (in_Dataset);
  mask_scan_line = (char *) CPLMalloc (sizeof (char) * xsize);
  data_scan_line = (char *) CPLMalloc (sizeof (char) * xsize);
  for (bands = 1; bands <= GDALGetRasterCount (in_Dataset); bands++)
    {
      int x;
      GDALRasterBandH data_band, out_band;
      int y_index = 0;
      data_band = GDALGetRasterBand (in_Dataset, bands);
      out_band = GDALGetRasterBand (out_Dataset, bands);
      for (y_index = 0; y_index < GDALGetRasterYSize (in_Dataset); y_index++)
	{
	  /* Read data.. */
	  GDALRasterIO (data_band, GF_Read, 0, y_index, xsize, 1,
			data_scan_line, xsize, 1, GDT_Byte, 0, 0);

	  /* Read mask.. */
	  GDALRasterIO (mask_band, GF_Read, 0, y_index, xsize, 1,
			mask_scan_line, xsize, 1, GDT_Byte, 0, 0);
	  GDALSetRasterNoDataValue (out_band, 0.0);


	  for (x = 0; x < xsize; x++)
	    {
	      /* if mask is set to 0, then mask off... */
	      if (mask_scan_line[x] == 0)
		data_scan_line[x] = 0;
	      /* if mask is not zero, and data is zero, then unmask.. */
	      if (mask_scan_line[x] != 0 && data_scan_line[x] == 0)
		data_scan_line[x] = 1;
	    }

	  /* now write out band.. */
	  GDALRasterIO (out_band, GF_Write, 0, y_index, xsize, 1,
			data_scan_line, xsize, 1, GDT_Byte, 0, 0);
	}

    }


  GDALClose (out_Dataset);

}
void QgsImageWarper::warp( const QString& input, const QString& output,
                           double& xOffset, double& yOffset,
                           ResamplingMethod resampling, bool useZeroAsTrans, const QString& compression )
{
  // Open input file
  GDALAllRegister();
  GDALDatasetH hSrcDS = GDALOpen( QFile::encodeName( input ).constData(), GA_ReadOnly );
  // Setup warp options.
  GDALWarpOptions *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 = &QgsImageWarper::transform;
  psWarpOptions->eResampleAlg = GDALResampleAlg( resampling );

  // check the bounds for the warped raster
  // order: upper right, lower right, lower left (y points down)
  double x[] = { GDALGetRasterXSize( hSrcDS ), GDALGetRasterXSize( hSrcDS ), 0 };
  double y[] = { 0, GDALGetRasterYSize( hSrcDS ), GDALGetRasterYSize( hSrcDS ) };
  int s[] = { 0, 0, 0 };
  TransformParameters tParam = { mAngle, 0, 0 };
  transform( &tParam, FALSE, 3, x, y, NULL, s );
  double minX = 0, minY = 0, maxX = 0, maxY = 0;
  for ( int i = 0; i < 3; ++i )
  {
    minX = minX < x[i] ? minX : x[i];
    minY = minY < y[i] ? minY : y[i];
    maxX = maxX > x[i] ? maxX : x[i];
    maxY = maxY > y[i] ? maxY : y[i];
  }
  int newXSize = int( maxX - minX ) + 1;
  int newYSize = int( maxY - minY ) + 1;
  xOffset = -minX;
  yOffset = -minY;
  tParam.x0 = xOffset;
  tParam.y0 = yOffset;
  psWarpOptions->pTransformerArg = &tParam;

  // create the output file
  GDALDriverH driver = GDALGetDriverByName( "GTiff" );
  char **papszOptions = NULL;
  papszOptions = CSLSetNameValue( papszOptions, "INIT_DEST", "NO_DATA" );
  papszOptions = CSLSetNameValue( papszOptions, "COMPRESS", compression.toAscii() );
  GDALDatasetH hDstDS =
    GDALCreate( driver,
                QFile::encodeName( output ).constData(), newXSize, newYSize,
                GDALGetRasterCount( hSrcDS ),
                GDALGetRasterDataType( GDALGetRasterBand( hSrcDS, 1 ) ),
                papszOptions );

  for ( int i = 0; i < GDALGetRasterCount( hSrcDS ); ++i )
  {
    GDALRasterBandH hSrcBand = GDALGetRasterBand( hSrcDS, i + 1 );
    GDALRasterBandH hDstBand = GDALGetRasterBand( hDstDS, i + 1 );
    GDALColorTableH cTable = GDALGetRasterColorTable( hSrcBand );
    GDALSetRasterColorInterpretation( hDstBand, GDALGetRasterColorInterpretation( hSrcBand ) );
    if ( cTable )
    {
      GDALSetRasterColorTable( hDstBand, cTable );
    }

    double noData = GDALGetRasterNoDataValue( hSrcBand, NULL );
    if ( noData == -1e10 && useZeroAsTrans )
    {
      GDALSetRasterNoDataValue( hDstBand, 0 );
    }
    else
    {
      GDALSetRasterNoDataValue( hDstBand, noData );
    }
  }
  psWarpOptions->hDstDS = hDstDS;

  // Initialize and execute the warp operation.
  GDALWarpOperation oOperation;
  oOperation.Initialize( psWarpOptions );
  oOperation.ChunkAndWarpImage( 0, 0, GDALGetRasterXSize( hDstDS ),
                                GDALGetRasterYSize( hDstDS ) );
  GDALDestroyWarpOptions( psWarpOptions );

  GDALClose( hSrcDS );
  GDALClose( hDstDS );
}
Beispiel #14
0
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( it->raster->source().toLocal8Bit().data(), 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 );
  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;
}
bool QgsImageWarper::createDestinationDataset(
  const QString &outputName, GDALDatasetH hSrcDS, GDALDatasetH &hDstDS,
  uint resX, uint resY, double *adfGeoTransform, bool useZeroAsTrans,
  const QString& compression, const QString &projection )
{
  // create the output file
  GDALDriverH driver = GDALGetDriverByName( "GTiff" );
  if ( !driver )
  {
    return false;
  }
  char **papszOptions = NULL;
  papszOptions = CSLSetNameValue( papszOptions, "COMPRESS", compression.toAscii() );
  hDstDS = GDALCreate( driver,
                       QFile::encodeName( outputName ).constData(), resX, resY,
                       GDALGetRasterCount( hSrcDS ),
                       GDALGetRasterDataType( GDALGetRasterBand( hSrcDS, 1 ) ),
                       papszOptions );
  if ( !hDstDS )
  {
    return false;
  }

  if ( CE_None != GDALSetGeoTransform( hDstDS, adfGeoTransform ) )
  {
    return false;
  }

  if ( !projection.isEmpty() )
  {
    OGRSpatialReference oTargetSRS;
    if ( projection.startsWith( "EPSG", Qt::CaseInsensitive ) )
    {
      QString epsg = projection.mid( projection.indexOf( ":" ) + 1 );
      oTargetSRS.importFromEPSG( epsg.toInt() );
    }
    else
    {
      oTargetSRS.importFromProj4( projection.toLatin1().data() );
    }

    char *wkt = NULL;
    OGRErr err = oTargetSRS.exportToWkt( &wkt );
    if ( err != CE_None || GDALSetProjection( hDstDS, wkt ) != CE_None )
    {
      OGRFree( wkt );
      return false;
    }
    OGRFree( wkt );
  }

  for ( int i = 0; i < GDALGetRasterCount( hSrcDS ); ++i )
  {
    GDALRasterBandH hSrcBand = GDALGetRasterBand( hSrcDS, i + 1 );
    GDALRasterBandH hDstBand = GDALGetRasterBand( hDstDS, i + 1 );
    GDALColorTableH cTable = GDALGetRasterColorTable( hSrcBand );
    GDALSetRasterColorInterpretation( hDstBand, GDALGetRasterColorInterpretation( hSrcBand ) );
    if ( cTable )
    {
      GDALSetRasterColorTable( hDstBand, cTable );
    }

    int success;
    double noData = GDALGetRasterNoDataValue( hSrcBand, &success );
    if ( success )
    {
      GDALSetRasterNoDataValue( hDstBand, noData );
    }
    else if ( useZeroAsTrans )
    {
      GDALSetRasterNoDataValue( hDstBand, 0 );
    }
  }

  return true;
}
Beispiel #16
0
void Dust::MakeGrid(WindNinjaInputs &input, AsciiGrid<double> &grid)
{
    /*------------------------------------------*/
    /* Open grid as a GDAL dataset              */
    /*------------------------------------------*/
    int nXSize = grid.get_nCols();
    int nYSize = grid.get_nRows();
    
    GDALDriverH hDriver = GDALGetDriverByName( "MEM" );
        
    GDALDatasetH hMemDS = GDALCreate(hDriver, "", nXSize, nYSize, 1, GDT_Float64, NULL);
    
    double *padfScanline;
    padfScanline = new double[nXSize];
    
    double adfGeoTransform[6];
    adfGeoTransform[0] = grid.get_xllCorner();
    adfGeoTransform[1] = grid.get_cellSize();
    adfGeoTransform[2] = 0;
    adfGeoTransform[3] = grid.get_yllCorner()+(grid.get_nRows()*grid.get_cellSize());
    adfGeoTransform[4] = 0;
    adfGeoTransform[5] = -grid.get_cellSize();
        
    char* pszDstWKT = (char*)grid.prjString.c_str();
    GDALSetProjection(hMemDS, pszDstWKT);
    GDALSetGeoTransform(hMemDS, adfGeoTransform);
        
    GDALRasterBandH hBand = GDALGetRasterBand( hMemDS, 1 );
        
    GDALSetRasterNoDataValue(hBand, -9999.0);        

    for(int i=nYSize-1; i>=0; i--)
    {
        for(int j=0; j<nXSize; j++)
        {  
            padfScanline[j] = grid.get_cellValue(nYSize-1-i, j);
        }
        GDALRasterIO(hBand, GF_Write, 0, i, nXSize, 1, padfScanline, nXSize,
                     1, GDT_Float64, 0, 0);
    }
    
    /*------------------------------------------*/
    /* Get the geometry info                    */
    /*------------------------------------------*/
    
    OGRDataSourceH hOGRDS = 0;
    hOGRDS = OGROpen(input.dustFilename.c_str(), FALSE, 0);
    if(hOGRDS == NULL)
    {
        throw std::runtime_error("Could not open the fire perimeter file '" +
              input.dustFilename + "' for reading.");
    }
    OGRLayer *poLayer;
    OGRFeature *poFeature;
    OGRGeometry *poGeo;
    
    poLayer = (OGRLayer*)OGR_DS_GetLayer(hOGRDS, 0);
    poLayer->ResetReading();
    poFeature = poLayer->GetNextFeature();
    poGeo = poFeature->GetGeometryRef();
    OGRGeometryH hPolygon = (OGRGeometryH) poGeo;


    /* -------------------------------------------------------------------- */
    /*  Check for same CRS in fire perimeter and DEM files                  */
    /* -------------------------------------------------------------------- */

    char *pszSrcWKT;
    OGRSpatialReference *poSrcSRS, oDstSRS;
    poSrcSRS = poLayer->GetSpatialRef(); //shapefile CRS
    poSrcSRS->exportToWkt( &pszSrcWKT );

    //printf("CRS of DEM is:\n %s\n", pszDstWKT);
    //printf("WKT CRS of .shp is:\n %s\n", pszSrcWKT);
    
    oDstSRS.importFromWkt( &pszDstWKT );
    
    char *pszDstProj4, *pszSrcProj4;
    oDstSRS.exportToProj4( &pszDstProj4 );
    poSrcSRS->exportToProj4( &pszSrcProj4 );
    
    //printf("proj4 of .shp is:\n %s\n", pszSrcProj4);
    //printf("proj4 of dem is:\n %s\n", pszDstProj4);
    
    /* -------------------------------------------------------------------- */
    /*  If the CRSs are not equal, convert shapefile CRS to DEM CRS         */
    /* -------------------------------------------------------------------- */

    GDALTransformerFunc pfnTransformer = NULL;
    if( !EQUAL( pszSrcProj4, pszDstProj4 ) ){ //tranform shp CRS to DEM CRS
        poGeo->transformTo(&oDstSRS);
    }
     
    /* -------------------------------------------------------------------- */
    /*  Rasterize the shapefile                                             */
    /* -------------------------------------------------------------------- */
    
    int nTargetBand = 1;
    double BurnValue = 1.0;
    CPLErr eErr;
    
    eErr = GDALRasterizeGeometries(hMemDS, 1, &nTargetBand, 1, &hPolygon, pfnTransformer, NULL, &BurnValue, NULL, NULL, NULL);
    if(eErr != CE_None)
    {
        throw std::runtime_error("Error in GDALRasterizeGeometies in Dust:MakeGrid().");
    }
    
    GDAL2AsciiGrid((GDALDataset*)hMemDS, 1, grid);
    
    /* -------------------------------------------------------------------- */
    /*   clean up                                                           */
    /* -------------------------------------------------------------------- */
    
    if( hMemDS != NULL ){
        GDALClose( hMemDS );
        hMemDS = NULL;
    }
    
    OGR_DS_Destroy(hOGRDS);
}
Beispiel #17
0
int msSaveImageGDAL( mapObj *map, imageObj *image, char *filename )

{
  int  bFileIsTemporary = MS_FALSE;
  GDALDatasetH hMemDS, hOutputDS;
  GDALDriverH  hMemDriver, hOutputDriver;
  int          nBands = 1;
  int          iLine;
  GByte       *pabyAlphaLine = NULL;
  char        **papszOptions = NULL;
  outputFormatObj *format = image->format;
  rasterBufferObj rb;
  GDALDataType eDataType = GDT_Byte;
  int bUseXmp = MS_FALSE;

  msGDALInitialize();
  memset(&rb,0,sizeof(rasterBufferObj));

#ifdef USE_EXEMPI
  if( map != NULL ) {
    bUseXmp = msXmpPresent(map);
  }
#endif


  /* -------------------------------------------------------------------- */
  /*      Identify the proposed output driver.                            */
  /* -------------------------------------------------------------------- */
  msAcquireLock( TLOCK_GDAL );
  hOutputDriver = GDALGetDriverByName( format->driver+5 );
  if( hOutputDriver == NULL ) {
    msReleaseLock( TLOCK_GDAL );
    msSetError( MS_MISCERR, "Failed to find %s driver.",
                "msSaveImageGDAL()", format->driver+5 );
    return MS_FAILURE;
  }

  /* -------------------------------------------------------------------- */
  /*      We will need to write the output to a temporary file and        */
  /*      then stream to stdout if no filename is passed.  If the         */
  /*      driver supports virtualio then we hold the temporary file in    */
  /*      memory, otherwise we try to put it in a reasonable temporary    */
  /*      file location.                                                  */
  /* -------------------------------------------------------------------- */
  if( filename == NULL ) {
    const char *pszExtension = format->extension;
    if( pszExtension == NULL )
      pszExtension = "img.tmp";

    if( bUseXmp == MS_FALSE && GDALGetMetadataItem( hOutputDriver, GDAL_DCAP_VIRTUALIO, NULL )
        != NULL ) {
      CleanVSIDir( "/vsimem/msout" );
      filename = msTmpFile(map, NULL, "/vsimem/msout/", pszExtension );
    }

    if( filename == NULL && map != NULL)
      filename = msTmpFile(map, map->mappath,NULL,pszExtension);
    else if( filename == NULL ) {
      filename = msTmpFile(map, NULL, NULL, pszExtension );
    }

    bFileIsTemporary = MS_TRUE;
  }

  /* -------------------------------------------------------------------- */
  /*      Establish the characteristics of our memory, and final          */
  /*      dataset.                                                        */
  /* -------------------------------------------------------------------- */

  if( format->imagemode == MS_IMAGEMODE_RGB ) {
    nBands = 3;
    assert( MS_RENDERER_PLUGIN(format) && format->vtable->supports_pixel_buffer );
    format->vtable->getRasterBufferHandle(image,&rb);
  } else if( format->imagemode == MS_IMAGEMODE_RGBA ) {
    pabyAlphaLine = (GByte *) calloc(image->width,1);
    if (pabyAlphaLine == NULL) {
      msReleaseLock( TLOCK_GDAL );
      msSetError( MS_MEMERR, "Out of memory allocating %u bytes.\n", "msSaveImageGDAL()", image->width);
      return MS_FAILURE;
    }
    nBands = 4;
    assert( MS_RENDERER_PLUGIN(format) && format->vtable->supports_pixel_buffer );
    format->vtable->getRasterBufferHandle(image,&rb);
  } else if( format->imagemode == MS_IMAGEMODE_INT16 ) {
    nBands = format->bands;
    eDataType = GDT_Int16;
  } else if( format->imagemode == MS_IMAGEMODE_FLOAT32 ) {
    nBands = format->bands;
    eDataType = GDT_Float32;
  } else if( format->imagemode == MS_IMAGEMODE_BYTE ) {
    nBands = format->bands;
    eDataType = GDT_Byte;
  } else {
#ifdef USE_GD
    assert( format->imagemode == MS_IMAGEMODE_PC256
            && format->renderer == MS_RENDER_WITH_GD );
#else
    {
      msReleaseLock( TLOCK_GDAL );
      msSetError( MS_MEMERR, "GD not compiled in. This is a bug.", "msSaveImageGDAL()");
      return MS_FAILURE;
    }
#endif

  }

  /* -------------------------------------------------------------------- */
  /*      Create a memory dataset which we can use as a source for a      */
  /*      CreateCopy().                                                   */
  /* -------------------------------------------------------------------- */
  hMemDriver = GDALGetDriverByName( "MEM" );
  if( hMemDriver == NULL ) {
    msReleaseLock( TLOCK_GDAL );
    msSetError( MS_MISCERR, "Failed to find MEM driver.",
                "msSaveImageGDAL()" );
    return MS_FAILURE;
  }

  hMemDS = GDALCreate( hMemDriver, "msSaveImageGDAL_temp",
                       image->width, image->height, nBands,
                       eDataType, NULL );
  if( hMemDS == NULL ) {
    msReleaseLock( TLOCK_GDAL );
    msSetError( MS_MISCERR, "Failed to create MEM dataset.",
                "msSaveImageGDAL()" );
    return MS_FAILURE;
  }

  /* -------------------------------------------------------------------- */
  /*      Copy the gd image into the memory dataset.                      */
  /* -------------------------------------------------------------------- */
  for( iLine = 0; iLine < image->height; iLine++ ) {
    int iBand;

    for( iBand = 0; iBand < nBands; iBand++ ) {
      GDALRasterBandH hBand = GDALGetRasterBand( hMemDS, iBand+1 );

      if( format->imagemode == MS_IMAGEMODE_INT16 ) {
        GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
                      image->img.raw_16bit + iLine * image->width
                      + iBand * image->width * image->height,
                      image->width, 1, GDT_Int16, 2, 0 );

      } else if( format->imagemode == MS_IMAGEMODE_FLOAT32 ) {
        GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
                      image->img.raw_float + iLine * image->width
                      + iBand * image->width * image->height,
                      image->width, 1, GDT_Float32, 4, 0 );
      } else if( format->imagemode == MS_IMAGEMODE_BYTE ) {
        GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
                      image->img.raw_byte + iLine * image->width
                      + iBand * image->width * image->height,
                      image->width, 1, GDT_Byte, 1, 0 );
      }
#ifdef USE_GD
      else if(format->renderer == MS_RENDER_WITH_GD) {
        gdImagePtr img = (gdImagePtr)image->img.plugin;
        GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
                      img->pixels[iLine],
                      image->width, 1, GDT_Byte, 0, 0 );
      }
#endif
      else {
        GByte *pabyData;
        unsigned char *pixptr = NULL;
        assert( rb.type == MS_BUFFER_BYTE_RGBA );
        switch(iBand) {
          case 0:
            pixptr = rb.data.rgba.r;
            break;
          case 1:
            pixptr = rb.data.rgba.g;
            break;
          case 2:
            pixptr = rb.data.rgba.b;
            break;
          case 3:
            pixptr = rb.data.rgba.a;
            break;
        }
        assert(pixptr);
        if( pixptr == NULL ) {
          msReleaseLock( TLOCK_GDAL );
          msSetError( MS_MISCERR, "Missing RGB or A buffer.\n",
                      "msSaveImageGDAL()" );
          return MS_FAILURE;
        }

        pabyData = (GByte *)(pixptr + iLine*rb.data.rgba.row_step);

        if( rb.data.rgba.a == NULL || iBand == 3 ) {
          GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
                        pabyData, image->width, 1, GDT_Byte,
                        rb.data.rgba.pixel_step, 0 );
        } else { /* We need to un-pre-multiple RGB by alpha. */
          GByte *pabyUPM = (GByte*) malloc(image->width);
          GByte *pabyAlpha= (GByte *)(rb.data.rgba.a + iLine*rb.data.rgba.row_step);
          int i;

          for( i = 0; i < image->width; i++ ) {
            int alpha = pabyAlpha[i*rb.data.rgba.pixel_step];

            if( alpha == 0 )
              pabyUPM[i] = 0;
            else {
              int result = (pabyData[i*rb.data.rgba.pixel_step] * 255) / alpha;

              if( result > 255 )
                result = 255;

              pabyUPM[i] = result;
            }
          }

          GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
                        pabyUPM, image->width, 1, GDT_Byte, 1, 0 );
          free( pabyUPM );
        }
      }
    }
  }

  if( pabyAlphaLine != NULL )
    free( pabyAlphaLine );

  /* -------------------------------------------------------------------- */
  /*      Attach the palette if appropriate.                              */
  /* -------------------------------------------------------------------- */
#ifdef USE_GD
  if( format->renderer == MS_RENDER_WITH_GD ) {
    GDALColorEntry sEntry;
    int  iColor;
    GDALColorTableH hCT;
    gdImagePtr img = (gdImagePtr)image->img.plugin;
    hCT = GDALCreateColorTable( GPI_RGB );

    for( iColor = 0; iColor < img->colorsTotal; iColor++ ) {
      sEntry.c1 = img->red[iColor];
      sEntry.c2 = img->green[iColor];
      sEntry.c3 = img->blue[iColor];

      if( iColor == gdImageGetTransparent( img ) )
        sEntry.c4 = 0;
      else if( iColor == 0
               && gdImageGetTransparent( img ) == -1
               && format->transparent )
        sEntry.c4 = 0;
      else
        sEntry.c4 = 255;

      GDALSetColorEntry( hCT, iColor, &sEntry );
    }

    GDALSetRasterColorTable( GDALGetRasterBand( hMemDS, 1 ), hCT );

    GDALDestroyColorTable( hCT );
  } else
#endif
    if( format->imagemode == MS_IMAGEMODE_RGB ) {
      GDALSetRasterColorInterpretation(
        GDALGetRasterBand( hMemDS, 1 ), GCI_RedBand );
      GDALSetRasterColorInterpretation(
        GDALGetRasterBand( hMemDS, 2 ), GCI_GreenBand );
      GDALSetRasterColorInterpretation(
        GDALGetRasterBand( hMemDS, 3 ), GCI_BlueBand );
    } else if( format->imagemode == MS_IMAGEMODE_RGBA ) {
      GDALSetRasterColorInterpretation(
        GDALGetRasterBand( hMemDS, 1 ), GCI_RedBand );
      GDALSetRasterColorInterpretation(
        GDALGetRasterBand( hMemDS, 2 ), GCI_GreenBand );
      GDALSetRasterColorInterpretation(
        GDALGetRasterBand( hMemDS, 3 ), GCI_BlueBand );
      GDALSetRasterColorInterpretation(
        GDALGetRasterBand( hMemDS, 4 ), GCI_AlphaBand );
    }

  /* -------------------------------------------------------------------- */
  /*      Assign the projection and coordinate system to the memory       */
  /*      dataset.                                                        */
  /* -------------------------------------------------------------------- */

  if( map != NULL ) {
    char *pszWKT;

    GDALSetGeoTransform( hMemDS, map->gt.geotransform );

    pszWKT = msProjectionObj2OGCWKT( &(map->projection) );
    if( pszWKT != NULL ) {
      GDALSetProjection( hMemDS, pszWKT );
      msFree( pszWKT );
    }
  }

  /* -------------------------------------------------------------------- */
  /*      Possibly assign a nodata value.                                 */
  /* -------------------------------------------------------------------- */
  if( msGetOutputFormatOption(format,"NULLVALUE",NULL) != NULL ) {
    int iBand;
    const char *nullvalue = msGetOutputFormatOption(format,
                            "NULLVALUE",NULL);

    for( iBand = 0; iBand < nBands; iBand++ ) {
      GDALRasterBandH hBand = GDALGetRasterBand( hMemDS, iBand+1 );
      GDALSetRasterNoDataValue( hBand, atof(nullvalue) );
    }
  }

  /* -------------------------------------------------------------------- */
  /*  Try to save resolution in the output file.                          */
  /* -------------------------------------------------------------------- */
  if( image->resolution > 0 ) {
    char res[30];

    sprintf( res, "%lf", image->resolution );
    GDALSetMetadataItem( hMemDS, "TIFFTAG_XRESOLUTION", res, NULL );
    GDALSetMetadataItem( hMemDS, "TIFFTAG_YRESOLUTION", res, NULL );
    GDALSetMetadataItem( hMemDS, "TIFFTAG_RESOLUTIONUNIT", "2", NULL );
  }

  /* -------------------------------------------------------------------- */
  /*      Create a disk image in the selected output format from the      */
  /*      memory image.                                                   */
  /* -------------------------------------------------------------------- */
  papszOptions = (char**)calloc(sizeof(char *),(format->numformatoptions+1));
  if (papszOptions == NULL) {
    msReleaseLock( TLOCK_GDAL );
    msSetError( MS_MEMERR, "Out of memory allocating %u bytes.\n", "msSaveImageGDAL()",
                (unsigned int)(sizeof(char *)*(format->numformatoptions+1)));
    return MS_FAILURE;
  }

  memcpy( papszOptions, format->formatoptions,
          sizeof(char *) * format->numformatoptions );

  hOutputDS = GDALCreateCopy( hOutputDriver, filename, hMemDS, FALSE,
                              papszOptions, NULL, NULL );

  free( papszOptions );

  if( hOutputDS == NULL ) {
    GDALClose( hMemDS );
    msReleaseLock( TLOCK_GDAL );
    msSetError( MS_MISCERR, "Failed to create output %s file.\n%s",
                "msSaveImageGDAL()", format->driver+5,
                CPLGetLastErrorMsg() );
    return MS_FAILURE;
  }

  /* closing the memory DS also frees all associated resources. */
  GDALClose( hMemDS );

  GDALClose( hOutputDS );
  msReleaseLock( TLOCK_GDAL );


  /* -------------------------------------------------------------------- */
  /*      Are we writing license info into the image?                     */
  /*      If so, add it to the temp file on disk now.                     */
  /* -------------------------------------------------------------------- */
#ifdef USE_EXEMPI
  if ( bUseXmp == MS_TRUE ) {
    if( msXmpWrite(map, filename) == MS_FAILURE ) {
      /* Something bad happened. */
      msSetError( MS_MISCERR, "XMP write to %s failed.\n",
                  "msSaveImageGDAL()", filename);
      return MS_FAILURE;
    }
  }
#endif

  /* -------------------------------------------------------------------- */
  /*      Is this supposed to be a temporary file?  If so, stream to      */
  /*      stdout and delete the file.                                     */
  /* -------------------------------------------------------------------- */
  if( bFileIsTemporary ) {
    FILE *fp;
    unsigned char block[4000];
    int bytes_read;

    if( msIO_needBinaryStdout() == MS_FAILURE )
      return MS_FAILURE;

    /* We aren't sure how far back GDAL exports the VSI*L API, so
       we only use it if we suspect we need it.  But we do need it if
       holding temporary file in memory. */
    fp = VSIFOpenL( filename, "rb" );
    if( fp == NULL ) {
      msSetError( MS_MISCERR,
                  "Failed to open %s for streaming to stdout.",
                  "msSaveImageGDAL()", filename );
      return MS_FAILURE;
    }

    while( (bytes_read = VSIFReadL(block, 1, sizeof(block), fp)) > 0 )
      msIO_fwrite( block, 1, bytes_read, stdout );

    VSIFCloseL( fp );

    VSIUnlink( filename );
    CleanVSIDir( "/vsimem/msout" );

    free( filename );
  }

  return MS_SUCCESS;
}
static
GDALDatasetH CreateOutputDataset(std::vector<OGRLayerH> ahLayers,
                                 OGRSpatialReferenceH hSRS,
                                 int bGotBounds, OGREnvelope sEnvelop,
                                 GDALDriverH hDriver, const char* pszDest,
                                 int nXSize, int nYSize, double dfXRes, double dfYRes,
                                 int bTargetAlignedPixels,
                                 int nBandCount, GDALDataType eOutputType,
                                 char** papszCreationOptions, std::vector<double> adfInitVals,
                                 int bNoDataSet, double dfNoData)
{
    int bFirstLayer = TRUE;
    char* pszWKT = NULL;
    GDALDatasetH hDstDS = NULL;
    unsigned int i;

    for( i = 0; i < ahLayers.size(); i++ )
    {
        OGRLayerH hLayer = ahLayers[i];

        if (!bGotBounds)
        {
            OGREnvelope sLayerEnvelop;

            if (OGR_L_GetExtent(hLayer, &sLayerEnvelop, TRUE) != OGRERR_NONE)
            {
                CPLError(CE_Failure, CPLE_AppDefined, "Cannot get layer extent");
                return NULL;
            }

            /* Voluntarily increase the extent by a half-pixel size to avoid */
            /* missing points on the border */
            if (!bTargetAlignedPixels && dfXRes != 0 && dfYRes != 0)
            {
                sLayerEnvelop.MinX -= dfXRes / 2;
                sLayerEnvelop.MaxX += dfXRes / 2;
                sLayerEnvelop.MinY -= dfYRes / 2;
                sLayerEnvelop.MaxY += dfYRes / 2;
            }

            if (bFirstLayer)
            {
                sEnvelop.MinX = sLayerEnvelop.MinX;
                sEnvelop.MinY = sLayerEnvelop.MinY;
                sEnvelop.MaxX = sLayerEnvelop.MaxX;
                sEnvelop.MaxY = sLayerEnvelop.MaxY;

                if (hSRS == NULL)
                    hSRS = OGR_L_GetSpatialRef(hLayer);

                bFirstLayer = FALSE;
            }
            else
            {
                sEnvelop.MinX = MIN(sEnvelop.MinX, sLayerEnvelop.MinX);
                sEnvelop.MinY = MIN(sEnvelop.MinY, sLayerEnvelop.MinY);
                sEnvelop.MaxX = MAX(sEnvelop.MaxX, sLayerEnvelop.MaxX);
                sEnvelop.MaxY = MAX(sEnvelop.MaxY, sLayerEnvelop.MaxY);
            }
        }
        else
        {
            if (bFirstLayer)
            {
                if (hSRS == NULL)
                    hSRS = OGR_L_GetSpatialRef(hLayer);

                bFirstLayer = FALSE;
            }
        }
    }

    if (dfXRes == 0 && dfYRes == 0)
    {
        dfXRes = (sEnvelop.MaxX - sEnvelop.MinX) / nXSize;
        dfYRes = (sEnvelop.MaxY - sEnvelop.MinY) / nYSize;
    }
    else if (bTargetAlignedPixels && dfXRes != 0 && dfYRes != 0)
    {
        sEnvelop.MinX = floor(sEnvelop.MinX / dfXRes) * dfXRes;
        sEnvelop.MaxX = ceil(sEnvelop.MaxX / dfXRes) * dfXRes;
        sEnvelop.MinY = floor(sEnvelop.MinY / dfYRes) * dfYRes;
        sEnvelop.MaxY = ceil(sEnvelop.MaxY / dfYRes) * dfYRes;
    }

    double adfProjection[6];
    adfProjection[0] = sEnvelop.MinX;
    adfProjection[1] = dfXRes;
    adfProjection[2] = 0;
    adfProjection[3] = sEnvelop.MaxY;
    adfProjection[4] = 0;
    adfProjection[5] = -dfYRes;

    if (nXSize == 0 && nYSize == 0)
    {
        nXSize = (int)(0.5 + (sEnvelop.MaxX - sEnvelop.MinX) / dfXRes);
        nYSize = (int)(0.5 + (sEnvelop.MaxY - sEnvelop.MinY) / dfYRes);
    }

    hDstDS = GDALCreate(hDriver, pszDest, nXSize, nYSize,
                        nBandCount, eOutputType, papszCreationOptions);
    if (hDstDS == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot create %s", pszDest);
        return NULL;
    }

    GDALSetGeoTransform(hDstDS, adfProjection);

    if (hSRS)
        OSRExportToWkt(hSRS, &pszWKT);
    if (pszWKT)
        GDALSetProjection(hDstDS, pszWKT);
    CPLFree(pszWKT);

    int iBand;
    /*if( nBandCount == 3 || nBandCount == 4 )
    {
        for(iBand = 0; iBand < nBandCount; iBand++)
        {
            GDALRasterBandH hBand = GDALGetRasterBand(hDstDS, iBand + 1);
            GDALSetRasterColorInterpretation(hBand, (GDALColorInterp)(GCI_RedBand + iBand));
        }
    }*/

    if (bNoDataSet)
    {
        for(iBand = 0; iBand < nBandCount; iBand++)
        {
            GDALRasterBandH hBand = GDALGetRasterBand(hDstDS, iBand + 1);
            GDALSetRasterNoDataValue(hBand, dfNoData);
        }
    }

    if (adfInitVals.size() != 0)
    {
        for(iBand = 0; iBand < MIN(nBandCount,(int)adfInitVals.size()); iBand++)
        {
            GDALRasterBandH hBand = GDALGetRasterBand(hDstDS, iBand + 1);
            GDALFillRaster(hBand, adfInitVals[iBand], 0);
        }
    }

    return hDstDS;
}
Beispiel #19
0
/* Matlab Gateway routine */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
	int	nXYSize;
	double	adfGeoTransform[6] = {0,1,0,0,0,1}, adfDstGeoTransform[6];
	char	*pszSRS_WKT = NULL;
	char	**papszWarpOptions = NULL;
	GDALDatasetH	hSrcDS, hDstDS;
	GDALDriverH	hDriver;
	GDALRasterBandH hBand;
	GDALColorTableH	hColorTable = NULL;
	OGRSpatialReference oSrcSRS, oDstSRS; 
	GDALResampleAlg	interpMethod = GRA_NearestNeighbour;
	GDALTransformerFunc pfnTransformer = NULL;
	CPLErr		eErr;
	GDAL_GCP	*pasGCPs = NULL;
	static int runed_once = FALSE;	/* It will be set to true if reaches end of main */

	const int *dim_array;
	int	nx, ny, i, j, m, n, c, nBands, registration = 1;
	int	n_dims, typeCLASS, nBytes;
	char	*pszSrcSRS = NULL, *pszSrcWKT = NULL;
	char	*pszDstSRS = NULL, *pszDstWKT = NULL;
	void	*in_data;
	mxArray	*mx_ptr;

	unsigned char *tmpByte, *outByte;
	unsigned short int *tmpUI16, *outUI16;
	short int *tmpI16, *outI16;
	int	*tmpI32, *outI32;
	int	nPixels=0, nLines=0, nForceWidth=0, nForceHeight=0;
	int	nGCPCount = 0, nOrder = 0;
	unsigned int *tmpUI32, *outUI32;
	float	*tmpF32, *outF32;
	double	*tmpF64, *outF64, *ptr_d;
	double	dfMinX=0, dfMaxX=0, dfMinY=0, dfMaxY=0, dfResX=0, dfResY=0;
	double	adfExtent[4];
	double	dfXRes=0.0, dfYRes=0.0;
	double	dfWarpMemoryLimit = 0.0;
	double	*pdfDstNodata = NULL; 
	char	**papszMetadataOptions = NULL;
	char	*tmp, *txt;


	if (nrhs == 2 && mxIsStruct(prhs[1])) {
		mx_ptr = mxGetField(prhs[1], 0, "ULx");
		if (mx_ptr == NULL)
			mexErrMsgTxt("GDALWARP 'ULx' field not provided");
		ptr_d = mxGetPr(mx_ptr);
		adfGeoTransform[0] = *ptr_d;

		mx_ptr = mxGetField(prhs[1], 0, "Xinc");
		if (mx_ptr == NULL)
			mexErrMsgTxt("GDALWARP 'Xinc' field not provided");
		ptr_d = mxGetPr(mx_ptr);
		adfGeoTransform[1] = *ptr_d;

		mx_ptr = mxGetField(prhs[1], 0, "ULy");
		if (mx_ptr == NULL)
			mexErrMsgTxt("GDALWARP 'ULy' field not provided");
		ptr_d = mxGetPr(mx_ptr);
		adfGeoTransform[3] = *ptr_d;

		mx_ptr = mxGetField(prhs[1], 0, "Yinc");
		if (mx_ptr == NULL)
			mexErrMsgTxt("GDALWARP 'Yinc' field not provided");
		ptr_d = mxGetPr(mx_ptr);
		adfGeoTransform[5] = -*ptr_d;

		/* -------- See for resolution requests ------------ */
		mx_ptr = mxGetField(prhs[1], 0, "t_size");
		if (mx_ptr != NULL) {
			ptr_d = mxGetPr(mx_ptr);
			if (mxGetN(mx_ptr) == 2) {
				nForceWidth  = (int)ptr_d[0];
				nForceHeight = (int)ptr_d[1];
			}
			else if (mxGetN(mx_ptr) == 1) {	/* pick max(nrow,ncol) */
				if (mxGetM(prhs[0]) > getNK(prhs[0],1))
					nForceHeight = mxGetM(prhs[0]);
				else
					nForceWidth  = getNK(prhs[0], 1);
			}
			else {
				nForceHeight = mxGetM(prhs[0]);
				nForceWidth  = getNK(prhs[0], 1);
			}
		}

		mx_ptr = mxGetField(prhs[1], 0, "t_res");
		if (mx_ptr != NULL) {
			ptr_d = mxGetPr(mx_ptr);
			if (mxGetN(mx_ptr) == 2) {
				dfXRes = ptr_d[0];
				dfYRes = ptr_d[1];
			}
			else if (mxGetN(mx_ptr) == 1) {
				dfXRes = dfYRes = ptr_d[0];
			}
		}
		/* -------------------------------------------------- */

		/* -------- Change Warping cache size?  ------------ */
		mx_ptr = mxGetField(prhs[1], 0, "wm");
		if (mx_ptr != NULL) {
			ptr_d = mxGetPr(mx_ptr);
			dfWarpMemoryLimit = *ptr_d * 1024 * 1024;
		}
		/* -------------------------------------------------- */

		/* -------- Have a nodata value order? -------------- */
		mx_ptr = mxGetField(prhs[1], 0, "nodata");
		if (mx_ptr != NULL) {
			pdfDstNodata = mxGetPr(mx_ptr);
		}
		/* -------------------------------------------------- */

		/* -------- See for projection stuff ---------------- */
		mx_ptr = mxGetField(prhs[1], 0, "SrcProjSRS");
		if (mx_ptr != NULL)
			pszSrcSRS = (char *)mxArrayToString(mx_ptr);

		mx_ptr = mxGetField(prhs[1], 0, "SrcProjWKT");
		if (mx_ptr != NULL)
			pszSrcWKT = (char *)mxArrayToString(mx_ptr);

		mx_ptr = mxGetField(prhs[1], 0, "DstProjSRS");
		if (mx_ptr != NULL)
			pszDstSRS = (char *)mxArrayToString(mx_ptr);

		mx_ptr = mxGetField(prhs[1], 0, "DstProjWKT");
		if (mx_ptr != NULL)
			pszDstWKT = (char *)mxArrayToString(mx_ptr);
		/* -------------------------------------------------- */

		/* -------- Do we have GCPs? ----------------------- */
		mx_ptr = mxGetField(prhs[1], 0, "gcp");
		if (mx_ptr != NULL) {
			nGCPCount = mxGetM(mx_ptr);
			if (mxGetN(mx_ptr) != 4)
				mexErrMsgTxt("GDALWARP: GCPs must be a Mx4 array");
			ptr_d = mxGetPr(mx_ptr);
			pasGCPs = (GDAL_GCP *) mxCalloc( nGCPCount, sizeof(GDAL_GCP) );
			GDALInitGCPs( 1, pasGCPs + nGCPCount - 1 );
			for (i = 0; i < nGCPCount; i++) {
				pasGCPs[i].dfGCPPixel = ptr_d[i];
				pasGCPs[i].dfGCPLine = ptr_d[i+nGCPCount];
				pasGCPs[i].dfGCPX = ptr_d[i+2*nGCPCount];
				pasGCPs[i].dfGCPY = ptr_d[i+3*nGCPCount];
				pasGCPs[i].dfGCPZ = 0;
			}
		}
			/* ---- Have we an order request? --- */
		mx_ptr = mxGetField(prhs[1], 0, "order");
		if (mx_ptr != NULL) {
			ptr_d = mxGetPr(mx_ptr);
			nOrder = (int)*ptr_d;
			if (nOrder != -1 || nOrder != 0 || nOrder != 1 || nOrder != 2 || nOrder != 3)
				nOrder = 0;
		}
		/* -------------------------------------------------- */

		mx_ptr = mxGetField(prhs[1], 0, "ResampleAlg");
		if (mx_ptr != NULL) {
			txt = (char *)mxArrayToString(mx_ptr);
			if (!strcmp(txt,"nearest"))
				interpMethod = GRA_NearestNeighbour;
			else if (!strcmp(txt,"bilinear"))
				interpMethod = GRA_Bilinear;
			else if (!strcmp(txt,"cubic") || !strcmp(txt,"bicubic"))
				interpMethod = GRA_Cubic;
			else if (!strcmp(txt,"spline"))
				interpMethod = GRA_CubicSpline;
		}

		/* If grid limits were in grid registration, convert them to pixel reg */
		mx_ptr = mxGetField(prhs[1], 0, "Reg");
		if (mx_ptr != NULL) {
			ptr_d = mxGetPr(mx_ptr);
			registration = (int)ptr_d[0];
		}

		if (registration == 0) {
			adfGeoTransform[0] -= adfGeoTransform[1]/2.;
			adfGeoTransform[3] -= adfGeoTransform[5]/2.;
		}
	}
	else {
		mexPrintf("Usage: B = gdalwarp_mex(IMG,HDR_STRUCT)\n\n");
		mexPrintf("\tIMG -> is a Mx2 or Mx3 array with an grid/image data to reproject\n");
		mexPrintf("\tHDR_STRUCT -> is a structure with the following fields:\n");
		mexPrintf("\t\t'ULx' X coordinate of the uper left corner\n");
		mexPrintf("\t\t'ULy' Y coordinate of the uper left corner\n");
		mexPrintf("\t\t'Xinc' distance between columns in target grid/image coordinates\n");
		mexPrintf("\t\t'Yinc' distance between rows in target grid/image coordinates\n");
		mexPrintf("\t\t'SrcProjSRS', 'SrcProjWKT' -> Source projection string\n");
		mexPrintf("\t\t'DstProjSRS', 'DstProjWKT' -> Target projection string\n");
		mexPrintf("\t\t\tSRS stands for a string of the type used by proj4\n");
		mexPrintf("\t\t\tWKT stands for a string on the 'Well Known Text' format\n\n");
		mexPrintf("\t\t\tIf one of the Src or Dst fields is absent a GEOGRAPHIC WGS84 is assumed\n");
		mexPrintf("\nOPTIONS\n");
		mexPrintf("\t\t'gcp' a [Mx4] array with Ground Control Points\n");
		mexPrintf("\t\t't_size' a [width height] vector to set output file size in pixels\n");
		mexPrintf("\t\t't_res' a [xres yres] vector to set output file resolution (in target georeferenced units)\n");
		mexPrintf("\t\t'wm' amount of memory (in megabytes) that the warp API is allowed to use for caching\n");
		mexPrintf("\t\t'nodata' Set nodata values for output bands.\n");
		mexPrintf("\t\t'ResampleAlg' To set up the algorithm used during warp operation. Options are: \n");
		mexPrintf("\t\t\t'nearest' Use nearest neighbour resampling (default, fastest algorithm, worst interpolation quality).\n");
		mexPrintf("\t\t\t'bilinear' Use bilinear resampling.\n");
		mexPrintf("\t\t\t'cubic' Use cubic resampling.\n");
		mexPrintf("\t\t\t'spline' Use cubic spline resampling.\n\n");

		if (!runed_once)		/* Do next call only at first time this MEX is loaded */
			GDALAllRegister();

        	mexPrintf( "The following format drivers are configured and support Create() method:\n" );
        	for( i = 0; i < GDALGetDriverCount(); i++ ) {
			hDriver = GDALGetDriver(i);
			if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) != NULL)
				mexPrintf("%s: %s\n", GDALGetDriverShortName(hDriver), 
							GDALGetDriverLongName(hDriver));
		}
		return;
	}

	n_dims = mxGetNumberOfDimensions(prhs[0]);
	dim_array=mxGetDimensions(prhs[0]);
	ny = dim_array[0];
	nx = dim_array[1];
	nBands = dim_array[2];

	if (n_dims == 2)	/* Otherwise it would stay undefined */
		nBands = 1;

	/* Find out in which data type was given the input array */
	if (mxIsUint8(prhs[0])) {
		typeCLASS = GDT_Byte;		nBytes = 1;
		outByte = (unsigned char *)mxMalloc (nx*ny * sizeof(unsigned char));
	}
	else if (mxIsUint16(prhs[0])) {
		typeCLASS = GDT_UInt16;		nBytes = 2;
		outUI16 = (unsigned short int *)mxMalloc (nx*ny * sizeof(short int));
	}
	else if (mxIsInt16(prhs[0])) {
		typeCLASS = GDT_Int16;		nBytes = 2;
		outI16 = (short int *)mxMalloc (nx*ny * sizeof(short int));
	}
	else if (mxIsInt32(prhs[0])) {
		typeCLASS = GDT_Int32;		nBytes = 4;
		outI32 = (int *)mxMalloc (nx*ny * sizeof(int));
	}
	else if (mxIsUint32(prhs[0])) {
		typeCLASS = GDT_UInt32;		nBytes = 4;
		outUI32 = (unsigned int *)mxMalloc (nx*ny * sizeof(int));
	}
	else if (mxIsSingle(prhs[0])) {
		typeCLASS = GDT_Float32;	nBytes = 4;
		outF32 = (float *)mxMalloc (nx*ny * sizeof(float));
	}
	else if (mxIsDouble(prhs[0])) {
		typeCLASS = GDT_Float64;	nBytes = 8;
		outF64 = (double *)mxMalloc (nx*ny * sizeof(double));
	}
	else
		mexErrMsgTxt("GDALWARP Unknown input data class!");


	in_data = (void *)mxGetData(prhs[0]);

	if (!runed_once)		/* Do next call only at first time this MEX is loaded */
		GDALAllRegister();

	hDriver = GDALGetDriverByName( "MEM" ); 

	hSrcDS = GDALCreate( hDriver, "mem", nx, ny, nBands, (GDALDataType)typeCLASS, NULL );
	if (hSrcDS == NULL) {
		mexPrintf ("GDALOpen failed - %d\n%s\n", CPLGetLastErrorNo(), CPLGetLastErrorMsg());
		return;
	}
	GDALSetGeoTransform( hSrcDS, adfGeoTransform ); 

	/* ---------- Set the Source projection ---------------------------- */
	/* If it was not provided assume it is Geog WGS84 */
	if (pszSrcSRS == NULL && pszSrcWKT == NULL)
		oSrcSRS.SetWellKnownGeogCS( "WGS84" ); 
	else if (pszSrcWKT != NULL)
		oSrcSRS.importFromWkt( &pszSrcWKT );

	else {
		if( oSrcSRS.SetFromUserInput( pszSrcSRS ) != OGRERR_NONE )
			mexErrMsgTxt("GDAL_WARP_MEX: Translating source SRS failed.");
	}
	if (pszSrcWKT == NULL)
		oSrcSRS.exportToWkt( &pszSrcWKT );

	GDALSetProjection( hSrcDS, pszSrcWKT );	
	//pszSrcWKT = (char *)GDALGetProjectionRef( hSrcDS );
	CPLAssert( pszSrcWKT != NULL && strlen(pszSrcWKT) > 0 );
	/* ------------------------------------------------------------------ */


	/* -------------- Copy input data into the hSrcDS dataset ----------- */
	for (i = 1; i <= nBands; i++) {
		hBand = GDALGetRasterBand( hSrcDS, i ); 
		nXYSize = (i-1)*nx*ny;
		switch( typeCLASS ) {
			case GDT_Byte:
			 	tmpByte = (unsigned char *)in_data;	
				for (m = ny-1, c = 0; m >= 0; m--) for (n = 0; n < nx; n++)
					outByte[c++] = tmpByte[m + n*ny + nXYSize];
				GDALRasterIO( hBand, GF_Write, 0, 0, nx, ny,outByte, nx, ny, (GDALDataType)typeCLASS, 0, 0 );
				break;
			case GDT_UInt16:
			 	tmpUI16 = (unsigned short int *)in_data;	
				for (m = ny-1, c = 0; m >= 0; m--) for (n = 0; n < nx; n++)
					outUI16[c++] = tmpUI16[m + n*ny + nXYSize];
				GDALRasterIO( hBand, GF_Write, 0, 0, nx, ny,outUI16, nx, ny, (GDALDataType)typeCLASS, 0, 0 );
				break;
			case GDT_Int16:
			 	tmpI16 = (short int *)in_data;	
				for (m = ny-1, c = 0; m >= 0; m--) for (n = 0; n < nx; n++)
					outI16[c++] = tmpI16[m + n*ny + nXYSize];
				GDALRasterIO( hBand, GF_Write, 0, 0, nx, ny,outI16, nx, ny, (GDALDataType)typeCLASS, 0, 0 );
				break;
			case GDT_UInt32:
			 	tmpUI32 = (unsigned int *)in_data;	
				for (m = ny-1, c = 0; m >= 0; m--) for (n = 0; n < nx; n++)
					outUI32[c++] = tmpUI32[m + n*ny + nXYSize];
				GDALRasterIO( hBand, GF_Write, 0, 0, nx, ny,outUI32, nx, ny, (GDALDataType)typeCLASS, 0, 0 );
				break;
			case GDT_Int32:
			 	tmpI32 = (int *)in_data;	
				for (m = ny-1, c = 0; m >= 0; m--) for (n = 0; n < nx; n++)
					outI32[c++] = tmpI32[m + n*ny + nXYSize];
				GDALRasterIO( hBand, GF_Write, 0, 0, nx, ny,outI32, nx, ny, (GDALDataType)typeCLASS, 0, 0 );
				break;
			case GDT_Float32:
			 	tmpF32 = (float *)in_data;	
				for (m = ny-1, c = 0; m >= 0; m--) for (n = 0; n < nx; n++)
					outF32[c++] = tmpF32[m + n*ny + nXYSize];
				GDALRasterIO( hBand, GF_Write, 0, 0, nx, ny,outF32, nx, ny, (GDALDataType)typeCLASS, 0, 0 );
				break;
			case GDT_Float64:
			 	tmpF64 = (double *)in_data;	
				for (m = ny-1, c = 0; m >= 0; m--) for (n = 0; n < nx; n++)
					outF64[c++] = tmpF64[m + n*ny + nXYSize];
				GDALRasterIO( hBand, GF_Write, 0, 0, nx, ny,outF64, nx, ny, (GDALDataType)typeCLASS, 0, 0 );
				break;
		}
	}

	/* ---------- Set up the Target coordinate system ------------------- */
	/* If it was not provided assume it is Geog WGS84 */
	CPLErrorReset();
	if (pszDstSRS == NULL && pszDstWKT == NULL)
		oDstSRS.SetWellKnownGeogCS( "WGS84" ); 
	else if (pszDstWKT != NULL)
		oDstSRS.importFromWkt( &pszDstWKT );
	else {
		if( oDstSRS.SetFromUserInput( pszDstSRS ) != OGRERR_NONE )
			mexErrMsgTxt("GDAL_WARP_MEX: Translating target SRS failed.");
	}
	if (pszDstWKT == NULL)
		oDstSRS.exportToWkt( &pszDstWKT );
	/* ------------------------------------------------------------------ */

	if ( nGCPCount != 0 ) {
		if (GDALSetGCPs(hSrcDS, nGCPCount, pasGCPs, "") != CE_None)
			mexPrintf("GDALWARP WARNING: writing GCPs failed.\n");
	}

	/* Create a transformer that maps from source pixel/line coordinates
	   to destination georeferenced coordinates (not destination pixel line) 
	   We do that by omitting the destination dataset handle (setting it to NULL). */

	void *hTransformArg;

	hTransformArg = GDALCreateGenImgProjTransformer(hSrcDS, pszSrcWKT, NULL, pszDstWKT, 
											nGCPCount == 0 ? FALSE : TRUE, 0, nOrder);
	if( hTransformArg == NULL )
		mexErrMsgTxt("GDALTRANSFORM: Generating transformer failed.");

	GDALTransformerInfo *psInfo = (GDALTransformerInfo*)hTransformArg;

	/* -------------------------------------------------------------------------- */
	/*      Get approximate output georeferenced bounds and resolution for file
	/* -------------------------------------------------------------------------- */
	if (GDALSuggestedWarpOutput2(hSrcDS, GDALGenImgProjTransform, hTransformArg, 
	                             adfDstGeoTransform, &nPixels, &nLines, adfExtent,
	                             0) != CE_None ) {
	    GDALClose(hSrcDS);
		mexErrMsgTxt("GDALWARP: GDALSuggestedWarpOutput2 failed.");
	}

	if (CPLGetConfigOption( "CHECK_WITH_INVERT_PROJ", NULL ) == NULL) {
		double MinX = adfExtent[0];
		double MaxX = adfExtent[2];
		double MaxY = adfExtent[3];
		double MinY = adfExtent[1];
		int bSuccess = TRUE;
            
		/* Check that the the edges of the target image are in the validity area */
		/* of the target projection */
#define N_STEPS 20
		for (i = 0; i <= N_STEPS && bSuccess; i++) {
			for (j = 0; j <= N_STEPS && bSuccess; j++) {
				double dfRatioI = i * 1.0 / N_STEPS;
				double dfRatioJ = j * 1.0 / N_STEPS;
				double expected_x = (1 - dfRatioI) * MinX + dfRatioI * MaxX;
				double expected_y = (1 - dfRatioJ) * MinY + dfRatioJ * MaxY;
				double x = expected_x;
				double y = expected_y;
				double z = 0;
				/* Target SRS coordinates to source image pixel coordinates */
				if (!psInfo->pfnTransform(hTransformArg, TRUE, 1, &x, &y, &z, &bSuccess) || !bSuccess)
					bSuccess = FALSE;
				/* Source image pixel coordinates to target SRS coordinates */
				if (!psInfo->pfnTransform(hTransformArg, FALSE, 1, &x, &y, &z, &bSuccess) || !bSuccess)
					bSuccess = FALSE;
				if (fabs(x - expected_x) > (MaxX - MinX) / nPixels ||
					fabs(y - expected_y) > (MaxY - MinY) / nLines)
					bSuccess = FALSE;
			}
		}
            
		/* If not, retry with CHECK_WITH_INVERT_PROJ=TRUE that forces ogrct.cpp */
		/* to check the consistency of each requested projection result with the */
		/* invert projection */
		if (!bSuccess) {
			CPLSetConfigOption( "CHECK_WITH_INVERT_PROJ", "TRUE" );
			CPLDebug("WARP", "Recompute out extent with CHECK_WITH_INVERT_PROJ=TRUE");

			if (GDALSuggestedWarpOutput2(hSrcDS, GDALGenImgProjTransform, hTransformArg, 
			                             adfDstGeoTransform, &nPixels, &nLines, adfExtent,
			                              0) != CE_None ) {
			    GDALClose(hSrcDS);
				mexErrMsgTxt("GDALWARO: GDALSuggestedWarpOutput2 failed.");
			}
		}
	}

	/* -------------------------------------------------------------------- */
	/*      Expand the working bounds to include this region, ensure the    */
	/*      working resolution is no more than this resolution.             */
	/* -------------------------------------------------------------------- */
	if( dfMaxX == 0.0 && dfMinX == 0.0 ) {
		dfMinX = adfExtent[0];
		dfMaxX = adfExtent[2];
		dfMaxY = adfExtent[3];
		dfMinY = adfExtent[1];
		dfResX = adfDstGeoTransform[1];
		dfResY = ABS(adfDstGeoTransform[5]);
	}
	else {
		dfMinX = MIN(dfMinX,adfExtent[0]);
		dfMaxX = MAX(dfMaxX,adfExtent[2]);
		dfMaxY = MAX(dfMaxY,adfExtent[3]);
		dfMinY = MIN(dfMinY,adfExtent[1]);
		dfResX = MIN(dfResX,adfDstGeoTransform[1]);
		dfResY = MIN(dfResY,ABS(adfDstGeoTransform[5]));
	}

	GDALDestroyGenImgProjTransformer( hTransformArg );

	/* -------------------------------------------------------------------- */
	/*      Turn the suggested region into a geotransform and suggested     */
	/*      number of pixels and lines.                                     */
	/* -------------------------------------------------------------------- */

	adfDstGeoTransform[0] = dfMinX;
	adfDstGeoTransform[1] = dfResX;
	adfDstGeoTransform[2] = 0.0;
	adfDstGeoTransform[3] = dfMaxY;
	adfDstGeoTransform[4] = 0.0;
	adfDstGeoTransform[5] = -1 * dfResY;

	nPixels = (int) ((dfMaxX - dfMinX) / dfResX + 0.5);
	nLines  = (int) ((dfMaxY - dfMinY) / dfResY + 0.5);

	/* -------------------------------------------------------------------- */
	/*      Did the user override some parameters?                          */
	/* -------------------------------------------------------------------- */
	if( dfXRes != 0.0 && dfYRes != 0.0 ) {
		dfMinX = adfDstGeoTransform[0];
		dfMaxX = adfDstGeoTransform[0] + adfDstGeoTransform[1] * nPixels;
		dfMaxY = adfDstGeoTransform[3];
		dfMinY = adfDstGeoTransform[3] + adfDstGeoTransform[5] * nLines;

		nPixels = (int) ((dfMaxX - dfMinX + (dfXRes/2.0)) / dfXRes);
		nLines = (int) ((dfMaxY - dfMinY + (dfYRes/2.0)) / dfYRes);
		adfDstGeoTransform[0] = dfMinX;
		adfDstGeoTransform[3] = dfMaxY;
		adfDstGeoTransform[1] = dfXRes;
		adfDstGeoTransform[5] = -dfYRes;
	}
	else if( nForceWidth != 0 && nForceHeight != 0 ) {
		dfXRes = (dfMaxX - dfMinX) / nForceWidth;
		dfYRes = (dfMaxY - dfMinY) / nForceHeight;

		adfDstGeoTransform[0] = dfMinX;
		adfDstGeoTransform[3] = dfMaxY;
		adfDstGeoTransform[1] = dfXRes;
		adfDstGeoTransform[5] = -dfYRes;

		nPixels = nForceWidth;
		nLines = nForceHeight;
	}
	else if( nForceWidth != 0) {
		dfXRes = (dfMaxX - dfMinX) / nForceWidth;
		dfYRes = dfXRes;

		adfDstGeoTransform[0] = dfMinX;
		adfDstGeoTransform[3] = dfMaxY;
		adfDstGeoTransform[1] = dfXRes;
		adfDstGeoTransform[5] = -dfYRes;

		nPixels = nForceWidth;
		nLines = (int) ((dfMaxY - dfMinY + (dfYRes/2.0)) / dfYRes);
	}
	else if( nForceHeight != 0) {
		dfYRes = (dfMaxY - dfMinY) / nForceHeight;
		dfXRes = dfYRes;

		adfDstGeoTransform[0] = dfMinX;
		adfDstGeoTransform[3] = dfMaxY;
		adfDstGeoTransform[1] = dfXRes;
		adfDstGeoTransform[5] = -dfYRes;

		nPixels = (int) ((dfMaxX - dfMinX + (dfXRes/2.0)) / dfXRes);
		nLines = nForceHeight;
	}

	/* --------------------- Create the output --------------------------- */
	hDstDS = GDALCreate( hDriver, "mem", nPixels, nLines, 
			GDALGetRasterCount(hSrcDS), (GDALDataType)typeCLASS, NULL );
    
	CPLAssert( hDstDS != NULL );

	/* -------------- Write out the projection definition ---------------- */
	GDALSetProjection( hDstDS, pszDstWKT );
	GDALSetGeoTransform( hDstDS, adfDstGeoTransform );

	/* --------------------- Setup warp options -------------------------- */
	GDALWarpOptions *psWO = GDALCreateWarpOptions();

	psWO->hSrcDS = hSrcDS;
	psWO->hDstDS = hDstDS;

	psWO->nBandCount = nBands;
	psWO->panSrcBands = (int *) CPLMalloc(psWO->nBandCount * sizeof(int) );
	psWO->panDstBands = (int *) CPLMalloc(psWO->nBandCount * sizeof(int) );
	for( i = 0; i < nBands; i++ ) {
		psWO->panSrcBands[i] = i+1;
		psWO->panDstBands[i] = i+1;
	}

	if( dfWarpMemoryLimit != 0.0 )
		psWO->dfWarpMemoryLimit = dfWarpMemoryLimit;

	/* --------------------- Setup the Resampling Algo ------------------- */
	psWO->eResampleAlg = interpMethod;


	/* --------------------- Setup NODATA options ------------------------ */
	papszWarpOptions = CSLSetNameValue(papszWarpOptions, "INIT_DEST", "NO_DATA" );

	if ( pdfDstNodata == NULL && (typeCLASS == GDT_Float32 || typeCLASS == GDT_Float64) ) {
		pdfDstNodata = (double *) mxCalloc((size_t)1, sizeof(double));
		*pdfDstNodata = mxGetNaN();
	}
	else if (pdfDstNodata != NULL) {
#define CLAMP(val,type,minval,maxval) \
    do { if (val < minval) { val = minval; } \
    else if (val > maxval) { val = maxval; } \
    else if (val != (type)val) { val = (type)(val + 0.5); } } \
    while(0)
		switch( typeCLASS ) {
			case GDT_Byte:
				CLAMP(pdfDstNodata[0], GByte, 0.0, 255.0);
				break;
			case GDT_UInt16:
				CLAMP(pdfDstNodata[0], GInt16, -32768.0, 32767.0);
				break;
			case GDT_Int16:
				CLAMP(pdfDstNodata[0], GUInt16, 0.0, 65535.0);
				break;
			case GDT_UInt32:
				CLAMP(pdfDstNodata[0], GInt32, -2147483648.0, 2147483647.0);
				break;
			case GDT_Int32:
				CLAMP(pdfDstNodata[0], GUInt32, 0.0, 4294967295.0);
				break;
			default:
				break;
		}
	}

	psWO->papszWarpOptions = CSLDuplicate(papszWarpOptions);

	if (pdfDstNodata != NULL) {
		psWO->padfDstNoDataReal = (double *) CPLMalloc(psWO->nBandCount*sizeof(double));
		psWO->padfDstNoDataImag = (double *) CPLMalloc(psWO->nBandCount*sizeof(double));
		for (i = 0; i < nBands; i++) {
                        psWO->padfDstNoDataReal[i] = pdfDstNodata[0];
                        psWO->padfDstNoDataImag[i] = 0.0;
			GDALSetRasterNoDataValue( GDALGetRasterBand(hDstDS, i+1), pdfDstNodata[0]);
		}
	}

	/* ------------ Establish reprojection transformer ------------------- */
	psWO->pTransformerArg = GDALCreateGenImgProjTransformer( hSrcDS, GDALGetProjectionRef(hSrcDS), 
							hDstDS, GDALGetProjectionRef(hDstDS), 
							nGCPCount == 0 ? FALSE : TRUE, 0.0, nOrder );
	psWO->pfnTransformer = GDALGenImgProjTransform;

	/* ----------- Initialize and execute the warp operation ------------- */
	GDALWarpOperation oOperation;

	oOperation.Initialize( psWO );
	eErr = oOperation.ChunkAndWarpImage( 0, 0, GDALGetRasterXSize( hDstDS ),
						GDALGetRasterYSize( hDstDS ) );
	CPLAssert( eErr == CE_None );

	GDALDestroyGenImgProjTransformer( psWO->pTransformerArg );
	GDALDestroyWarpOptions( psWO );
	GDALClose( hSrcDS );

	/* ------------ Free memory used to fill the hSrcDS dataset ---------- */
	switch( typeCLASS ) {
		case GDT_Byte:		mxFree((void *)outByte);	break;
		case GDT_UInt16:	mxFree((void *)outUI16);	break; 
		case GDT_Int16:		mxFree((void *)outI16);		break; 
		case GDT_UInt32:	mxFree((void *)outUI32);	break; 
		case GDT_Int32:		mxFree((void *)outI32);		break; 
		case GDT_Float32:	mxFree((void *)outF32);		break; 
		case GDT_Float64:	mxFree((void *)outF64);		break; 
	}

	int out_dims[3];
	out_dims[0] = nLines;
	out_dims[1] = nPixels;
	out_dims[2] = nBands;
	plhs[0] = mxCreateNumericArray (n_dims,out_dims,mxGetClassID(prhs[0]), mxREAL);
	tmp = (char *)mxCalloc(nPixels * nLines, nBytes);

	/* ------ Allocate memory to be used in filling the hDstDS dataset ---- */
	switch( typeCLASS ) {
		case GDT_Byte:
			outByte = (unsigned char *)mxGetData(plhs[0]);		break;
		case GDT_UInt16:
			outUI16 = (unsigned short int *)mxGetData(plhs[0]);	break;
		case GDT_Int16:
			outI16 = (short int *)mxGetData(plhs[0]);		break;
		case GDT_UInt32:
			outUI32 = (unsigned int *)mxGetData(plhs[0]);		break;
		case GDT_Int32:
			outI32 = (int *)mxGetData(plhs[0]);			break;
		case GDT_Float32:
			outF32 = (float *)mxGetData(plhs[0]);			break;
		case GDT_Float64:
			outF64 = (double *)mxGetData(plhs[0]);			break;
	}

	/* ----------- Copy the output hSrcDS dataset data into plhs  ---------- */
	for (i = 1; i <= nBands; i++) {
		hBand = GDALGetRasterBand( hDstDS, i ); 
		GDALRasterIO( hBand, GF_Read, 0, 0, nPixels, nLines, tmp, nPixels, nLines,
				(GDALDataType)typeCLASS, 0, 0 );
		nXYSize = (i-1) * nPixels * nLines;
		switch( typeCLASS ) {
			case GDT_Byte:
				for (m = nLines-1, c = 0; m >= 0; m--) for (n = 0; n < nPixels; n++)
					outByte[m + n*nLines + nXYSize] = tmp[c++];
				break;
			case GDT_UInt16:
				tmpUI16 = (GUInt16 *) tmp;
				for (m = nLines-1, c = 0; m >= 0; m--) for (n = 0; n < nPixels; n++)
					outUI16[m + n*nLines + nXYSize] = tmpUI16[c++];
				break;
			case GDT_Int16:
				tmpI16 = (GInt16 *) tmp;
				for (m = nLines-1, c = 0; m >= 0; m--) for (n = 0; n < nPixels; n++)
					outI16[m + n*nLines + nXYSize] = tmpI16[c++];
				break;
			case GDT_UInt32:
				tmpUI32 = (GUInt32 *) tmp;
				for (m = nLines-1, c = 0; m >= 0; m--) for (n = 0; n < nPixels; n++)
					outUI32[m + n*nLines + nXYSize] = tmpUI32[c++];
				break;
			case GDT_Int32:
				tmpI32 = (GInt32 *) tmp;
				for (m = nLines-1, c = 0; m >= 0; m--) for (n = 0; n < nPixels; n++)
					outI32[m + n*nLines + nXYSize] = tmpI32[c++];
				break;
			case GDT_Float32:
				tmpF32 = (float *) tmp;
				for (m = nLines-1, c = 0; m >= 0; m--) for (n = 0; n < nPixels; n++)
					outF32[m + n*nLines + nXYSize] = tmpF32[c++];
				break;
			case GDT_Float64:
				tmpF64 = (double *) tmp;
				for (m = nLines-1, c = 0; m >= 0; m--) for (n = 0; n < nPixels; n++)
					outF64[m + n*nLines + nXYSize] = tmpF64[c++];
				break;
		}
	}

	mxFree(tmp);
	if (nGCPCount) {
		GDALDeinitGCPs( nGCPCount, pasGCPs );	/* makes this mex crash in the next call - Is it still true??? */
		mxFree((void *) pasGCPs );
	}

	if (nlhs == 2)
		plhs[1] = populate_metadata_struct (hDstDS, 1);

	runed_once = TRUE;	/* Signals that next call won't need to call GDALAllRegister() again */

	/*GDALDestroyDriverManager();
	OGRFree(pszDstWKT);*/
	GDALClose( hDstDS );
	CSLDestroy( papszWarpOptions );
	if (pszDstWKT && strlen(pszDstWKT) > 1 ) OGRFree(pszDstWKT);	
	if (pszSrcWKT && strlen(pszSrcWKT) > 1 ) OGRFree(pszSrcWKT);
}