Exemple #1
0
bool QgsAlignRaster::suggestedWarpOutput( const QgsAlignRaster::RasterInfo& info, const QString& destWkt, QSizeF* cellSize, QPointF* gridOffset, QgsRectangle* rect )
{
  // 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 = GDALCreateGenImgProjTransformer( info.mDataset, info.mCrsWkt.toAscii().constData(), NULL, destWkt.toAscii().constData(), FALSE, 0, 1 );
  if ( !hTransformArg )
    return false;

  // Get approximate output georeferenced bounds and resolution for file.
  double adfDstGeoTransform[6];
  double extents[4];
  int nPixels = 0, nLines = 0;
  CPLErr eErr;
  eErr = GDALSuggestedWarpOutput2( info.mDataset,
                                   GDALGenImgProjTransform, hTransformArg,
                                   adfDstGeoTransform, &nPixels, &nLines, extents, 0 );
  GDALDestroyGenImgProjTransformer( hTransformArg );

  if ( eErr != CE_None )
    return false;

  QSizeF cs( qAbs( adfDstGeoTransform[1] ), qAbs( adfDstGeoTransform[5] ) );

  if ( rect )
    *rect = QgsRectangle( extents[0], extents[1], extents[2], extents[3] );
  if ( cellSize )
    *cellSize = cs;
  if ( gridOffset )
    *gridOffset = QPointF( fmod_with_tolerance( adfDstGeoTransform[0], cs.width() ),
                           fmod_with_tolerance( adfDstGeoTransform[3], cs.height() ) );
  return true;
}
Exemple #2
0
/**
 * GDALReprojectImage() method with a ChunkAndWarpImage replaced with ChunkAndWarpMulti
 */
CPLErr GDALReprojectImageMulti( GDALDatasetH hSrcDS, const char *pszSrcWKT,
                    GDALDatasetH hDstDS, const char *pszDstWKT,
                    GDALResampleAlg eResampleAlg,
                    double dfWarpMemoryLimit,
                    double dfMaxError,
                    GDALProgressFunc pfnProgress, void *pProgressArg,
                    GDALWarpOptions *psOptions )

{
    GDALWarpOptions *psWOptions;

/* -------------------------------------------------------------------- */
/*      Setup a reprojection based transformer.                         */
/* -------------------------------------------------------------------- */
    void *hTransformArg;

    hTransformArg = 
        GDALCreateGenImgProjTransformer( hSrcDS, pszSrcWKT, hDstDS, pszDstWKT, 
                                         TRUE, 1000.0, 0 );

    if( hTransformArg == NULL )
        return CE_Failure;

/* -------------------------------------------------------------------- */
/*      Create a copy of the user provided options, or a defaulted      */
/*      options structure.                                              */
/* -------------------------------------------------------------------- */
    if( psOptions == NULL )
        psWOptions = GDALCreateWarpOptions();
    else
        psWOptions = GDALCloneWarpOptions( psOptions );

    psWOptions->eResampleAlg = eResampleAlg;

/* -------------------------------------------------------------------- */
/*      Set transform.                                                  */
/* -------------------------------------------------------------------- */
    if( dfMaxError > 0.0 )
    {
        psWOptions->pTransformerArg = 
            GDALCreateApproxTransformer( GDALGenImgProjTransform, 
                                         hTransformArg, dfMaxError );

        psWOptions->pfnTransformer = GDALApproxTransform;
    }
    else
    {
        psWOptions->pfnTransformer = GDALGenImgProjTransform;
        psWOptions->pTransformerArg = hTransformArg;
    }

/* -------------------------------------------------------------------- */
/*      Set file and band mapping.                                      */
/* -------------------------------------------------------------------- */
    int  iBand;

    psWOptions->hSrcDS = hSrcDS;
    psWOptions->hDstDS = hDstDS;

    if( psWOptions->nBandCount == 0 )
    {
        psWOptions->nBandCount = MIN(GDALGetRasterCount(hSrcDS),
                                     GDALGetRasterCount(hDstDS));
        
        psWOptions->panSrcBands = (int *) 
            CPLMalloc(sizeof(int) * psWOptions->nBandCount);
        psWOptions->panDstBands = (int *) 
            CPLMalloc(sizeof(int) * psWOptions->nBandCount);

        for( iBand = 0; iBand < psWOptions->nBandCount; iBand++ )
        {
            psWOptions->panSrcBands[iBand] = iBand+1;
            psWOptions->panDstBands[iBand] = iBand+1;
        }
    }

/* -------------------------------------------------------------------- */
/*      Set source nodata values if the source dataset seems to have    */
/*      any. Same for target nodata values                              */
/* -------------------------------------------------------------------- */
    for( iBand = 0; iBand < psWOptions->nBandCount; iBand++ )
    {
        GDALRasterBandH hBand = GDALGetRasterBand( hSrcDS, iBand+1 );
        int             bGotNoData = FALSE;
        double          dfNoDataValue;

        if (GDALGetRasterColorInterpretation(hBand) == GCI_AlphaBand)
        {
            psWOptions->nSrcAlphaBand = iBand + 1;
        }

        dfNoDataValue = GDALGetRasterNoDataValue( hBand, &bGotNoData );
        if( bGotNoData )
        {
            if( psWOptions->padfSrcNoDataReal == NULL )
            {
                int  ii;

                psWOptions->padfSrcNoDataReal = (double *) 
                    CPLMalloc(sizeof(double) * psWOptions->nBandCount);
                psWOptions->padfSrcNoDataImag = (double *) 
                    CPLMalloc(sizeof(double) * psWOptions->nBandCount);

                for( ii = 0; ii < psWOptions->nBandCount; ii++ )
                {
                    psWOptions->padfSrcNoDataReal[ii] = -1.1e20;
                    psWOptions->padfSrcNoDataImag[ii] = 0.0;
                }
            }

            psWOptions->padfSrcNoDataReal[iBand] = dfNoDataValue;
        }

        // Deal with target band
        hBand = GDALGetRasterBand( hDstDS, iBand+1 );
        if (hBand && GDALGetRasterColorInterpretation(hBand) == GCI_AlphaBand)
        {
            psWOptions->nDstAlphaBand = iBand + 1;
        }

        dfNoDataValue = GDALGetRasterNoDataValue( hBand, &bGotNoData );
        if( bGotNoData )
        {
            if( psWOptions->padfDstNoDataReal == NULL )
            {
                int  ii;

                psWOptions->padfDstNoDataReal = (double *) 
                    CPLMalloc(sizeof(double) * psWOptions->nBandCount);
                psWOptions->padfDstNoDataImag = (double *) 
                    CPLMalloc(sizeof(double) * psWOptions->nBandCount);

                for( ii = 0; ii < psWOptions->nBandCount; ii++ )
                {
                    psWOptions->padfDstNoDataReal[ii] = -1.1e20;
                    psWOptions->padfDstNoDataImag[ii] = 0.0;
                }
            }

            psWOptions->padfDstNoDataReal[iBand] = dfNoDataValue;
        }
    }

/* -------------------------------------------------------------------- */
/*      Set the progress function.                                      */
/* -------------------------------------------------------------------- */
    if( pfnProgress != NULL )
    {
        psWOptions->pfnProgress = pfnProgress;
        psWOptions->pProgressArg = pProgressArg;
    }

/* -------------------------------------------------------------------- */
/*      Create a warp options based on the options.                     */
/* -------------------------------------------------------------------- */
    GDALWarpOperation  oWarper;
    CPLErr eErr;

    eErr = oWarper.Initialize( psWOptions );

    if( eErr == CE_None )
        eErr = oWarper.ChunkAndWarpMulti( 0, 0, 
                                          GDALGetRasterXSize(hDstDS),
                                          GDALGetRasterYSize(hDstDS) );

/* -------------------------------------------------------------------- */
/*      Cleanup.                                                        */
/* -------------------------------------------------------------------- */
    GDALDestroyGenImgProjTransformer( hTransformArg );

    if( dfMaxError > 0.0 )
        GDALDestroyApproxTransformer( psWOptions->pTransformerArg );
        
    GDALDestroyWarpOptions( psWOptions );

    return eErr;
}
Exemple #3
0
/**
 * \private \memberof mapcache_source_gdal
 * \sa mapcache_source::render_metatile()
 */
void _mapcache_source_gdal_render_metatile(mapcache_context *ctx, mapcache_metatile *tile)
{
  mapcache_source_gdal *gdal = (mapcache_source_gdal*)tile->tile.tileset->source;
  char *srcSRS = "", *dstSRS;
  mapcache_buffer *data = mapcache_buffer_create(0,ctx->pool);
  GC_CHECK_ERROR(ctx);
  GDALDatasetH  hDataset;

  GDALAllRegister();
  OGRSpatialReferenceH hSRS;
  CPLErrorReset();

  hSRS = OSRNewSpatialReference( NULL );
  if( OSRSetFromUserInput( hSRS, tile->tile.grid->srs ) == OGRERR_NONE )
    OSRExportToWkt( hSRS, &dstSRS );
  else {
    ctx->set_error(ctx,MAPCACHE_SOURCE_GDAL_ERROR,"failed to parse gdal srs %s",tile->tile.grid->srs);
    return;
  }

  OSRDestroySpatialReference( hSRS );

  hDataset = GDALOpen( gdal->datastr, GA_ReadOnly );
  if( hDataset == NULL ) {
    ctx->set_error(ctx,MAPCACHE_SOURCE_GDAL_ERROR,"GDAL failed to open %s",gdal->datastr);
    return;
  }

  /* -------------------------------------------------------------------- */
  /*      Check that there's at least one raster band                     */
  /* -------------------------------------------------------------------- */
  if ( GDALGetRasterCount(hDataset) == 0 ) {
    ctx->set_error(ctx,MAPCACHE_SOURCE_GDAL_ERROR,"raster %s has no bands",gdal->datastr);
    return;
  }

  if( GDALGetProjectionRef( hDataset ) != NULL
      && strlen(GDALGetProjectionRef( hDataset )) > 0 )
    srcSRS = apr_pstrdup(ctx->pool,GDALGetProjectionRef( hDataset ));

  else if( GDALGetGCPProjection( hDataset ) != NULL
           && strlen(GDALGetGCPProjection(hDataset)) > 0
           && GDALGetGCPCount( hDataset ) > 1 )
    srcSRS = apr_pstrdup(ctx->pool,GDALGetGCPProjection( hDataset ));

  GDALDriverH hDriver = GDALGetDriverByName( "MEM" );
  GDALDatasetH hDstDS;
  /* -------------------------------------------------------------------- */
  /*      Create a transformation object from the source to               */
  /*      destination coordinate system.                                  */
  /* -------------------------------------------------------------------- */
  void *hTransformArg =
    GDALCreateGenImgProjTransformer( hDataset, srcSRS,
                                     NULL, dstSRS,
                                     TRUE, 1000.0, 0 );

  if( hTransformArg == NULL ) {
    ctx->set_error(ctx,MAPCACHE_SOURCE_GDAL_ERROR,"gdal failed to create SRS transformation object");
    return;
  }

  /* -------------------------------------------------------------------- */
  /*      Get approximate output definition.                              */
  /* -------------------------------------------------------------------- */
  int nPixels, nLines;
  double adfDstGeoTransform[6];
  if( GDALSuggestedWarpOutput( hDataset,
                               GDALGenImgProjTransform, hTransformArg,
                               adfDstGeoTransform, &nPixels, &nLines )
      != CE_None ) {
    ctx->set_error(ctx,MAPCACHE_SOURCE_GDAL_ERROR,"gdal failed to create suggested warp output");
    return;
  }

  GDALDestroyGenImgProjTransformer( hTransformArg );
  double dfXRes = (tile->bbox[2] - tile->bbox[0]) / tile->sx;
  double dfYRes = (tile->bbox[3] - tile->bbox[1]) / tile->sy;

  adfDstGeoTransform[0] = tile->bbox[0];
  adfDstGeoTransform[3] = tile->bbox[3];
  adfDstGeoTransform[1] = dfXRes;
  adfDstGeoTransform[5] = -dfYRes;
  hDstDS = GDALCreate( hDriver, "tempd_gdal_image", tile->sx, tile->sy, 4, GDT_Byte, NULL );

  /* -------------------------------------------------------------------- */
  /*      Write out the projection definition.                            */
  /* -------------------------------------------------------------------- */
  GDALSetProjection( hDstDS, dstSRS );
  GDALSetGeoTransform( hDstDS, adfDstGeoTransform );
  char               **papszWarpOptions = NULL;
  papszWarpOptions = CSLSetNameValue( papszWarpOptions, "INIT", "0" );



  /* -------------------------------------------------------------------- */
  /*      Create a transformation object from the source to               */
  /*      destination coordinate system.                                  */
  /* -------------------------------------------------------------------- */
  GDALTransformerFunc pfnTransformer = NULL;
  void               *hGenImgProjArg=NULL, *hApproxArg=NULL;
  hTransformArg = hGenImgProjArg =
                    GDALCreateGenImgProjTransformer( hDataset, srcSRS,
                        hDstDS, dstSRS,
                        TRUE, 1000.0, 0 );

  if( hTransformArg == NULL )
    exit( 1 );

  pfnTransformer = GDALGenImgProjTransform;

  hTransformArg = hApproxArg =
                    GDALCreateApproxTransformer( GDALGenImgProjTransform,
                        hGenImgProjArg, 0.125 );
  pfnTransformer = GDALApproxTransform;

  /* -------------------------------------------------------------------- */
  /*      Now actually invoke the warper to do the work.                  */
  /* -------------------------------------------------------------------- */
  GDALSimpleImageWarp( hDataset, hDstDS, 0, NULL,
                       pfnTransformer, hTransformArg,
                       GDALDummyProgress, NULL, papszWarpOptions );

  CSLDestroy( papszWarpOptions );

  if( hApproxArg != NULL )
    GDALDestroyApproxTransformer( hApproxArg );

  if( hGenImgProjArg != NULL )
    GDALDestroyGenImgProjTransformer( hGenImgProjArg );

  if(GDALGetRasterCount(hDstDS) != 4) {
    ctx->set_error(ctx,MAPCACHE_SOURCE_GDAL_ERROR,"gdal did not create a 4 band image");
    return;
  }

  GDALRasterBandH *redband, *greenband, *blueband, *alphaband;

  redband = GDALGetRasterBand(hDstDS,1);
  greenband = GDALGetRasterBand(hDstDS,2);
  blueband = GDALGetRasterBand(hDstDS,3);
  alphaband = GDALGetRasterBand(hDstDS,4);

  unsigned char *rasterdata = apr_palloc(ctx->pool,tile->sx*tile->sy*4);
  data->buf = rasterdata;
  data->avail = tile->sx*tile->sy*4;
  data->size = tile->sx*tile->sy*4;

  GDALRasterIO(redband,GF_Read,0,0,tile->sx,tile->sy,(void*)(rasterdata),tile->sx,tile->sy,GDT_Byte,4,4*tile->sx);
  GDALRasterIO(greenband,GF_Read,0,0,tile->sx,tile->sy,(void*)(rasterdata+1),tile->sx,tile->sy,GDT_Byte,4,4*tile->sx);
  GDALRasterIO(blueband,GF_Read,0,0,tile->sx,tile->sy,(void*)(rasterdata+2),tile->sx,tile->sy,GDT_Byte,4,4*tile->sx);
  if(GDALGetRasterCount(hDataset)==4)
    GDALRasterIO(alphaband,GF_Read,0,0,tile->sx,tile->sy,(void*)(rasterdata+3),tile->sx,tile->sy,GDT_Byte,4,4*tile->sx);
  else {
    unsigned char *alphaptr;
    int i;
    for(alphaptr = rasterdata+3, i=0; i<tile->sx*tile->sy; i++, alphaptr+=4) {
      *alphaptr = 255;
    }
  }

  tile->imdata = mapcache_image_create(ctx);
  tile->imdata->w = tile->sx;
  tile->imdata->h = tile->sy;
  tile->imdata->stride = tile->sx * 4;
  tile->imdata->data = rasterdata;


  GDALClose( hDstDS );
  GDALClose( hDataset);
}
Exemple #4
0
bool QgsAlignRaster::createAndWarp( const Item& raster )
{
  GDALDriverH hDriver = GDALGetDriverByName( "GTiff" );
  if ( !hDriver )
  {
    mErrorMessage = QString( "GDALGetDriverByName(GTiff) failed." );
    return false;
  }

  // Open the source file.
  GDALDatasetH hSrcDS = GDALOpen( raster.inputFilename.toLocal8Bit().constData(), GA_ReadOnly );
  if ( !hSrcDS )
  {
    mErrorMessage = QObject::tr( "Unable to open input file: " ) + raster.inputFilename;
    return false;
  }

  // Create output with same datatype as first input band.

  int bandCount = GDALGetRasterCount( hSrcDS );
  GDALDataType eDT = GDALGetRasterDataType( GDALGetRasterBand( hSrcDS, 1 ) );

  // Create the output file.
  GDALDatasetH hDstDS;
  hDstDS = GDALCreate( hDriver, raster.outputFilename.toLocal8Bit().constData(), mXSize, mYSize,
                       bandCount, eDT, NULL );
  if ( !hDstDS )
  {
    GDALClose( hSrcDS );
    mErrorMessage = QObject::tr( "Unable to create output file: " ) + raster.outputFilename;
    return false;
  }

  // Write out the projection definition.
  GDALSetProjection( hDstDS, mCrsWkt.toAscii().constData() );
  GDALSetGeoTransform( hDstDS, ( double* )mGeoTransform );

  // Copy the color table, if required.
  GDALColorTableH hCT = GDALGetRasterColorTable( GDALGetRasterBand( hSrcDS, 1 ) );
  if ( hCT != NULL )
    GDALSetRasterColorTable( GDALGetRasterBand( hDstDS, 1 ), hCT );

  // -----------------------------------------------------------------------

  // Setup warp options.
  GDALWarpOptions* psWarpOptions = GDALCreateWarpOptions();
  psWarpOptions->hSrcDS = hSrcDS;
  psWarpOptions->hDstDS = hDstDS;

  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->eResampleAlg = ( GDALResampleAlg ) raster.resampleMethod;

  // our progress function
  psWarpOptions->pfnProgress = _progress;
  psWarpOptions->pProgressArg = this;

  // Establish reprojection transformer.
  psWarpOptions->pTransformerArg =
    GDALCreateGenImgProjTransformer( hSrcDS, GDALGetProjectionRef( hSrcDS ),
                                     hDstDS, GDALGetProjectionRef( hDstDS ),
                                     FALSE, 0.0, 1 );
  psWarpOptions->pfnTransformer = GDALGenImgProjTransform;

  double rescaleArg[2];
  if ( raster.rescaleValues )
  {
    rescaleArg[0] = raster.srcCellSizeInDestCRS; // source cell size
    rescaleArg[1] = mCellSizeX * mCellSizeY;  // destination cell size
    psWarpOptions->pfnPreWarpChunkProcessor = rescalePreWarpChunkProcessor;
    psWarpOptions->pfnPostWarpChunkProcessor = rescalePostWarpChunkProcessor;
    psWarpOptions->pPreWarpProcessorArg = rescaleArg;
    psWarpOptions->pPostWarpProcessorArg = rescaleArg;
    // force use of float32 data type as that is what our pre/post-processor uses
    psWarpOptions->eWorkingDataType = GDT_Float32;
  }

  // Initialize and execute the warp operation.
  GDALWarpOperation oOperation;
  oOperation.Initialize( psWarpOptions );
  oOperation.ChunkAndWarpImage( 0, 0, mXSize, mYSize );

  GDALDestroyGenImgProjTransformer( psWarpOptions->pTransformerArg );
  GDALDestroyWarpOptions( psWarpOptions );

  GDALClose( hDstDS );
  GDALClose( hSrcDS );
  return true;
}
CPLErr GDALRasterizeLayers( GDALDatasetH hDS, 
                            int nBandCount, int *panBandList,
                            int nLayerCount, OGRLayerH *pahLayers,
                            GDALTransformerFunc pfnTransformer, 
                            void *pTransformArg, 
                            double *padfLayerBurnValues,
                            char **papszOptions,
                            GDALProgressFunc pfnProgress, 
                            void *pProgressArg )

{
    GDALDataType   eType;
    unsigned char *pabyChunkBuf;
    GDALDataset *poDS = (GDALDataset *) hDS;

    if( pfnProgress == NULL )
        pfnProgress = GDALDummyProgress;

/* -------------------------------------------------------------------- */
/*      Do some rudimentary arg checking.                               */
/* -------------------------------------------------------------------- */
    if( nBandCount == 0 || nLayerCount == 0 )
        return CE_None;

    // prototype band.
    GDALRasterBand *poBand = poDS->GetRasterBand( panBandList[0] );
    if (poBand == NULL)
        return CE_Failure;

    int bAllTouched = CSLFetchBoolean( papszOptions, "ALL_TOUCHED", FALSE );
    const char *pszOpt = CSLFetchNameValue( papszOptions, "BURN_VALUE_FROM" );
    GDALBurnValueSrc eBurnValueSource = GBV_UserBurnValue;
    if( pszOpt )
    {
        if( EQUAL(pszOpt,"Z"))
            eBurnValueSource = GBV_Z;
        /*else if( EQUAL(pszOpt,"M"))
            eBurnValueSource = GBV_M;*/
    }

/* -------------------------------------------------------------------- */
/*      Establish a chunksize to operate on.  The larger the chunk      */
/*      size the less times we need to make a pass through all the      */
/*      shapes.                                                         */
/* -------------------------------------------------------------------- */
    int         nYChunkSize, nScanlineBytes;
    const char  *pszYChunkSize =
        CSLFetchNameValue( papszOptions, "CHUNKYSIZE" );

    if( poBand->GetRasterDataType() == GDT_Byte )
        eType = GDT_Byte;
    else
        eType = GDT_Float32;

    nScanlineBytes = nBandCount * poDS->GetRasterXSize()
        * (GDALGetDataTypeSize(eType)/8);

    if ( pszYChunkSize && (nYChunkSize = atoi(pszYChunkSize)) )
        ;
    else
        nYChunkSize = GDALGetCacheMax() / nScanlineBytes;

    if( nYChunkSize < 1 )
        nYChunkSize = 1;
    if( nYChunkSize > poDS->GetRasterYSize() )
        nYChunkSize = poDS->GetRasterYSize();

    pabyChunkBuf = (unsigned char *) VSIMalloc(nYChunkSize * nScanlineBytes);
    if( pabyChunkBuf == NULL )
    {
        CPLError( CE_Failure, CPLE_OutOfMemory, 
                  "Unable to allocate rasterization buffer." );
        return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Read the image once for all layers if user requested to render  */
/*      the whole raster in single chunk.                               */
/* -------------------------------------------------------------------- */
    if ( nYChunkSize == poDS->GetRasterYSize() )
    {
        if ( poDS->RasterIO( GF_Read, 0, 0, poDS->GetRasterXSize(),
                             nYChunkSize, pabyChunkBuf,
                             poDS->GetRasterXSize(), nYChunkSize,
                             eType, nBandCount, panBandList, 0, 0, 0 )
             != CE_None )
        {
            CPLError( CE_Failure, CPLE_OutOfMemory, 
                      "Unable to read buffer." );
            CPLFree( pabyChunkBuf );
            return CE_Failure;
        }
    }

/* ==================================================================== */
/*      Read the specified layers transfoming and rasterizing           */
/*      geometries.                                                     */
/* ==================================================================== */
    CPLErr      eErr = CE_None;
    int         iLayer;
    const char  *pszBurnAttribute =
        CSLFetchNameValue( papszOptions, "ATTRIBUTE" );

    pfnProgress( 0.0, NULL, pProgressArg );

    for( iLayer = 0; iLayer < nLayerCount; iLayer++ )
    {
        int         iBurnField = -1;
        double      *padfBurnValues = NULL;
        OGRLayer    *poLayer = (OGRLayer *) pahLayers[iLayer];

        if ( !poLayer )
        {
            CPLError( CE_Warning, CPLE_AppDefined, 
                      "Layer element number %d is NULL, skipping.\n", iLayer );
            continue;
        }

/* -------------------------------------------------------------------- */
/*      If the layer does not contain any features just skip it.        */
/*      Do not force the feature count, so if driver doesn't know       */
/*      exact number of features, go down the normal way.               */
/* -------------------------------------------------------------------- */
        if ( poLayer->GetFeatureCount(FALSE) == 0 )
            continue;

        if ( pszBurnAttribute )
        {
            iBurnField =
                poLayer->GetLayerDefn()->GetFieldIndex( pszBurnAttribute );
            if ( iBurnField == -1 )
            {
                CPLError( CE_Warning, CPLE_AppDefined, 
                          "Failed to find field %s on layer %s, skipping.\n",
                          pszBurnAttribute, 
                          poLayer->GetLayerDefn()->GetName() );
                continue;
            }
        }
        else
            padfBurnValues = padfLayerBurnValues + iLayer * nBandCount;

/* -------------------------------------------------------------------- */
/*      If we have no transformer, create the one from input file       */
/*      projection. Note that each layer can be georefernced            */
/*      separately.                                                     */
/* -------------------------------------------------------------------- */
        int bNeedToFreeTransformer = FALSE;

        if( pfnTransformer == NULL )
        {
            char    *pszProjection = NULL;
            bNeedToFreeTransformer = TRUE;

            OGRSpatialReference *poSRS = poLayer->GetSpatialRef();
            if ( !poSRS )
            {
                CPLError( CE_Warning, CPLE_AppDefined, 
                          "Failed to fetch spatial reference on layer %s "
                          "to build transformer, assuming matching coordinate systems.\n",
                          poLayer->GetLayerDefn()->GetName() );
            }
            else
                poSRS->exportToWkt( &pszProjection );

            pTransformArg = 
                GDALCreateGenImgProjTransformer( NULL, pszProjection,
                                                 hDS, NULL, FALSE, 0.0, 0 );
            pfnTransformer = GDALGenImgProjTransform;

            CPLFree( pszProjection );
        }

        OGRFeature *poFeat;

        poLayer->ResetReading();

/* -------------------------------------------------------------------- */
/*      Loop over image in designated chunks.                           */
/* -------------------------------------------------------------------- */
        int     iY;
        for( iY = 0; 
             iY < poDS->GetRasterYSize() && eErr == CE_None; 
             iY += nYChunkSize )
        {
            int	nThisYChunkSize;

            nThisYChunkSize = nYChunkSize;
            if( nThisYChunkSize + iY > poDS->GetRasterYSize() )
                nThisYChunkSize = poDS->GetRasterYSize() - iY;

            // Only re-read image if not a single chunk is being rendered
            if ( nYChunkSize < poDS->GetRasterYSize() )
            {
                eErr = 
                    poDS->RasterIO( GF_Read, 0, iY,
                                    poDS->GetRasterXSize(), nThisYChunkSize, 
                                    pabyChunkBuf,
                                    poDS->GetRasterXSize(), nThisYChunkSize,
                                    eType, nBandCount, panBandList, 0, 0, 0 );
                if( eErr != CE_None )
                    break;
            }

            double *padfAttrValues = (double *) VSIMalloc(sizeof(double) * nBandCount);
            while( (poFeat = poLayer->GetNextFeature()) != NULL )
            {
                OGRGeometry *poGeom = poFeat->GetGeometryRef();

                if ( pszBurnAttribute )
                {
                    int         iBand;
                    double      dfAttrValue;

                    dfAttrValue = poFeat->GetFieldAsDouble( iBurnField );
                    for (iBand = 0 ; iBand < nBandCount ; iBand++)
                        padfAttrValues[iBand] = dfAttrValue;

                    padfBurnValues = padfAttrValues;
                }
                
                gv_rasterize_one_shape( pabyChunkBuf, iY,
                                        poDS->GetRasterXSize(),
                                        nThisYChunkSize,
                                        nBandCount, eType, bAllTouched, poGeom,
                                        padfBurnValues, eBurnValueSource,
                                        pfnTransformer, pTransformArg );

                delete poFeat;
            }
            VSIFree( padfAttrValues );

            // Only write image if not a single chunk is being rendered
            if ( nYChunkSize < poDS->GetRasterYSize() )
            {
                eErr = 
                    poDS->RasterIO( GF_Write, 0, iY,
                                    poDS->GetRasterXSize(), nThisYChunkSize, 
                                    pabyChunkBuf,
                                    poDS->GetRasterXSize(), nThisYChunkSize, 
                                    eType, nBandCount, panBandList, 0, 0, 0 );
            }

            poLayer->ResetReading();

            if( !pfnProgress((iY+nThisYChunkSize)/((double)poDS->GetRasterYSize()),
                             "", pProgressArg) )
            {
                CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
                eErr = CE_Failure;
            }
        }

        if ( bNeedToFreeTransformer )
        {
            GDALDestroyTransformer( pTransformArg );
            pTransformArg = NULL;
            pfnTransformer = NULL;
        }
    }
    
/* -------------------------------------------------------------------- */
/*      Write out the image once for all layers if user requested       */
/*      to render the whole raster in single chunk.                     */
/* -------------------------------------------------------------------- */
    if ( nYChunkSize == poDS->GetRasterYSize() )
    {
        poDS->RasterIO( GF_Write, 0, 0,
                                poDS->GetRasterXSize(), nYChunkSize, 
                                pabyChunkBuf,
                                poDS->GetRasterXSize(), nYChunkSize, 
                                eType, nBandCount, panBandList, 0, 0, 0 );
    }

/* -------------------------------------------------------------------- */
/*      cleanup                                                         */
/* -------------------------------------------------------------------- */
    VSIFree( pabyChunkBuf );
    
    return eErr;
}
Exemple #6
0
GDALDatasetH CPL_STDCALL 
GDALAutoCreateWarpedVRT( GDALDatasetH hSrcDS, 
                         const char *pszSrcWKT,
                         const char *pszDstWKT,
                         GDALResampleAlg eResampleAlg, 
                         double dfMaxError, 
                         const GDALWarpOptions *psOptionsIn )
    
{
    GDALWarpOptions *psWO;
    int i;

    VALIDATE_POINTER1( hSrcDS, "GDALAutoCreateWarpedVRT", NULL );

/* -------------------------------------------------------------------- */
/*      Populate the warp options.                                      */
/* -------------------------------------------------------------------- */
    if( psOptionsIn != NULL )
        psWO = GDALCloneWarpOptions( psOptionsIn );
    else
        psWO = GDALCreateWarpOptions();

    psWO->eResampleAlg = eResampleAlg;

    psWO->hSrcDS = hSrcDS;

    psWO->nBandCount = GDALGetRasterCount( hSrcDS );
    psWO->panSrcBands = (int *) CPLMalloc(sizeof(int) * psWO->nBandCount);
    psWO->panDstBands = (int *) CPLMalloc(sizeof(int) * psWO->nBandCount);

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

    /* TODO: should fill in no data where available */

/* -------------------------------------------------------------------- */
/*      Create the transformer.                                         */
/* -------------------------------------------------------------------- */
    psWO->pfnTransformer = GDALGenImgProjTransform;
    psWO->pTransformerArg = 
        GDALCreateGenImgProjTransformer( psWO->hSrcDS, pszSrcWKT, 
                                         NULL, pszDstWKT,
                                         TRUE, 1.0, 0 );

    if( psWO->pTransformerArg == NULL )
    {
        GDALDestroyWarpOptions( psWO );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Figure out the desired output bounds and resolution.            */
/* -------------------------------------------------------------------- */
    double adfDstGeoTransform[6];
    int    nDstPixels, nDstLines;
    CPLErr eErr;

    eErr = 
        GDALSuggestedWarpOutput( hSrcDS, psWO->pfnTransformer, 
                                 psWO->pTransformerArg, 
                                 adfDstGeoTransform, &nDstPixels, &nDstLines );

/* -------------------------------------------------------------------- */
/*      Update the transformer to include an output geotransform        */
/*      back to pixel/line coordinates.                                 */
/*                                                                      */
/* -------------------------------------------------------------------- */
    GDALSetGenImgProjTransformerDstGeoTransform( 
        psWO->pTransformerArg, adfDstGeoTransform );

/* -------------------------------------------------------------------- */
/*      Do we want to apply an approximating transformation?            */
/* -------------------------------------------------------------------- */
    if( dfMaxError > 0.0 )
    {
        psWO->pTransformerArg = 
            GDALCreateApproxTransformer( psWO->pfnTransformer, 
                                         psWO->pTransformerArg, 
                                         dfMaxError );
        psWO->pfnTransformer = GDALApproxTransform;
    }

/* -------------------------------------------------------------------- */
/*      Create the VRT file.                                            */
/* -------------------------------------------------------------------- */
    GDALDatasetH hDstDS;

    hDstDS = GDALCreateWarpedVRT( hSrcDS, nDstPixels, nDstLines, 
                                  adfDstGeoTransform, psWO );

    GDALDestroyWarpOptions( psWO );

    if( pszDstWKT != NULL )
        GDALSetProjection( hDstDS, pszDstWKT );
    else if( pszSrcWKT != NULL )
        GDALSetProjection( hDstDS, pszDstWKT );
    else if( GDALGetGCPCount( hSrcDS ) > 0 )
        GDALSetProjection( hDstDS, GDALGetGCPProjection( hSrcDS ) );
    else 
        GDALSetProjection( hDstDS, GDALGetProjectionRef( hSrcDS ) );

    return hDstDS;
}
CPLErr GDALRasterizeGeometries( GDALDatasetH hDS, 
                                int nBandCount, int *panBandList,
                                int nGeomCount, OGRGeometryH *pahGeometries,
                                GDALTransformerFunc pfnTransformer, 
                                void *pTransformArg, 
                                double *padfGeomBurnValue,
                                char **papszOptions,
                                GDALProgressFunc pfnProgress, 
                                void *pProgressArg )

{
    GDALDataType   eType;
    int            nYChunkSize, nScanlineBytes;
    unsigned char *pabyChunkBuf;
    int            iY;
    GDALDataset *poDS = (GDALDataset *) hDS;

    if( pfnProgress == NULL )
        pfnProgress = GDALDummyProgress;

/* -------------------------------------------------------------------- */
/*      Do some rudimentary arg checking.                               */
/* -------------------------------------------------------------------- */
    if( nBandCount == 0 || nGeomCount == 0 )
        return CE_None;

    // prototype band.
    GDALRasterBand *poBand = poDS->GetRasterBand( panBandList[0] );
    if (poBand == NULL)
        return CE_Failure;

    int bAllTouched = CSLFetchBoolean( papszOptions, "ALL_TOUCHED", FALSE );
    const char *pszOpt = CSLFetchNameValue( papszOptions, "BURN_VALUE_FROM" );
    GDALBurnValueSrc eBurnValueSource = GBV_UserBurnValue;
    if( pszOpt )
    {
        if( EQUAL(pszOpt,"Z"))
            eBurnValueSource = GBV_Z;
        /*else if( EQUAL(pszOpt,"M"))
            eBurnValueSource = GBV_M;*/
    }

/* -------------------------------------------------------------------- */
/*      If we have no transformer, assume the geometries are in file    */
/*      georeferenced coordinates, and create a transformer to          */
/*      convert that to pixel/line coordinates.                         */
/*                                                                      */
/*      We really just need to apply an affine transform, but for       */
/*      simplicity we use the more general GenImgProjTransformer.       */
/* -------------------------------------------------------------------- */
    int bNeedToFreeTransformer = FALSE;

    if( pfnTransformer == NULL )
    {
        bNeedToFreeTransformer = TRUE;

        pTransformArg = 
            GDALCreateGenImgProjTransformer( NULL, NULL, hDS, NULL, 
                                             FALSE, 0.0, 0);
        pfnTransformer = GDALGenImgProjTransform;
    }

/* -------------------------------------------------------------------- */
/*      Establish a chunksize to operate on.  The larger the chunk      */
/*      size the less times we need to make a pass through all the      */
/*      shapes.                                                         */
/* -------------------------------------------------------------------- */
    if( poBand->GetRasterDataType() == GDT_Byte )
        eType = GDT_Byte;
    else
        eType = GDT_Float32;

    nScanlineBytes = nBandCount * poDS->GetRasterXSize()
        * (GDALGetDataTypeSize(eType)/8);
    nYChunkSize = 10000000 / nScanlineBytes;
    if( nYChunkSize > poDS->GetRasterYSize() )
        nYChunkSize = poDS->GetRasterYSize();

    pabyChunkBuf = (unsigned char *) VSIMalloc(nYChunkSize * nScanlineBytes);
    if( pabyChunkBuf == NULL )
    {
        CPLError( CE_Failure, CPLE_OutOfMemory, 
                  "Unable to allocate rasterization buffer." );
        return CE_Failure;
    }

/* ==================================================================== */
/*      Loop over image in designated chunks.                           */
/* ==================================================================== */
    CPLErr  eErr = CE_None;

    pfnProgress( 0.0, NULL, pProgressArg );

    for( iY = 0; 
         iY < poDS->GetRasterYSize() && eErr == CE_None; 
         iY += nYChunkSize )
    {
        int	nThisYChunkSize;
        int     iShape;

        nThisYChunkSize = nYChunkSize;
        if( nThisYChunkSize + iY > poDS->GetRasterYSize() )
            nThisYChunkSize = poDS->GetRasterYSize() - iY;

        eErr = 
            poDS->RasterIO(GF_Read, 
                           0, iY, poDS->GetRasterXSize(), nThisYChunkSize, 
                           pabyChunkBuf,poDS->GetRasterXSize(),nThisYChunkSize,
                           eType, nBandCount, panBandList,
                           0, 0, 0 );
        if( eErr != CE_None )
            break;

        for( iShape = 0; iShape < nGeomCount; iShape++ )
        {
            gv_rasterize_one_shape( pabyChunkBuf, iY,
                                    poDS->GetRasterXSize(), nThisYChunkSize,
                                    nBandCount, eType, bAllTouched,
                                    (OGRGeometry *) pahGeometries[iShape],
                                    padfGeomBurnValue + iShape*nBandCount,
                                    eBurnValueSource,
                                    pfnTransformer, pTransformArg );
        }

        eErr = 
            poDS->RasterIO( GF_Write, 0, iY,
                            poDS->GetRasterXSize(), nThisYChunkSize, 
                            pabyChunkBuf,
                            poDS->GetRasterXSize(), nThisYChunkSize, 
                            eType, nBandCount, panBandList, 0, 0, 0 );

        if( !pfnProgress((iY+nThisYChunkSize)/((double)poDS->GetRasterYSize()),
                         "", pProgressArg ) )
        {
            CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
            eErr = CE_Failure;
        }
    }
    
/* -------------------------------------------------------------------- */
/*      cleanup                                                         */
/* -------------------------------------------------------------------- */
    VSIFree( pabyChunkBuf );
    
    if( bNeedToFreeTransformer )
        GDALDestroyTransformer( pTransformArg );

    return eErr;
}
Exemple #8
0
int main( int argc, char ** argv )

{
    GDALDatasetH	hSrcDS, hDstDS;
    const char         *pszFormat = "GTiff";
    char               *pszTargetSRS = NULL;
    char               *pszSourceSRS = NULL;
    const char         *pszSrcFilename = NULL, *pszDstFilename = NULL;
    int                 bCreateOutput = FALSE, i, nOrder = 0;
    void               *hTransformArg, *hGenImgProjArg=NULL, *hApproxArg=NULL;
    char               **papszWarpOptions = NULL;
    double             dfErrorThreshold = 0.125;
    GDALTransformerFunc pfnTransformer = NULL;
    char                **papszCreateOptions = NULL;

    GDALAllRegister();

/* -------------------------------------------------------------------- */
/*      Parse arguments.                                                */
/* -------------------------------------------------------------------- */
    for( i = 1; i < argc; i++ )
    {
        if( EQUAL(argv[i],"--version") )
        {
            printf( "%s\n", GDALVersionInfo( "--version" ) );
            exit( 0 );
        }
        else if( EQUAL(argv[i],"--formats") )
        {
            int iDr;

            printf( "Supported Formats:\n" );
            for( iDr = 0; iDr < GDALGetDriverCount(); iDr++ )
            {
                GDALDriverH hDriver = GDALGetDriver(iDr);
                
                printf( "  %s: %s\n",
                        GDALGetDriverShortName( hDriver ),
                        GDALGetDriverLongName( hDriver ) );
            }

            exit( 0 );
        }
        else if( EQUAL(argv[i],"-co") && i < argc-1 )
        {
            papszCreateOptions = CSLAddString( papszCreateOptions, argv[++i] );
            bCreateOutput = TRUE;
        }   
        else if( EQUAL(argv[i],"-of") && i < argc-1 )
        {
            pszFormat = argv[++i];
            bCreateOutput = TRUE;
        }
        else if( EQUAL(argv[i],"-t_srs") && i < argc-1 )
        {
            pszTargetSRS = SanitizeSRS(argv[++i]);
        }
        else if( EQUAL(argv[i],"-s_srs") && i < argc-1 )
        {
            pszSourceSRS = SanitizeSRS(argv[++i]);
        }
        else if( EQUAL(argv[i],"-order") && i < argc-1 )
        {
            nOrder = atoi(argv[++i]);
        }
        else if( EQUAL(argv[i],"-et") && i < argc-1 )
        {
            dfErrorThreshold = CPLAtof(argv[++i]);
        }
        else if( EQUAL(argv[i],"-tr") && i < argc-2 )
        {
            dfXRes = CPLAtof(argv[++i]);
            dfYRes = fabs(CPLAtof(argv[++i]));
            bCreateOutput = TRUE;
        }
        else if( EQUAL(argv[i],"-ts") && i < argc-2 )
        {
            nForcePixels = atoi(argv[++i]);
            nForceLines = atoi(argv[++i]);
            bCreateOutput = TRUE;
        }
        else if( EQUAL(argv[i],"-te") && i < argc-4 )
        {
            dfMinX = CPLAtof(argv[++i]);
            dfMinY = CPLAtof(argv[++i]);
            dfMaxX = CPLAtof(argv[++i]);
            dfMaxY = CPLAtof(argv[++i]);
            bCreateOutput = TRUE;
        }
        else if( argv[i][0] == '-' )
            Usage();
        else if( pszSrcFilename == NULL )
            pszSrcFilename = argv[i];
        else if( pszDstFilename == NULL )
            pszDstFilename = argv[i];
        else
            Usage();
    }

    if( pszDstFilename == NULL )
        Usage();

/* -------------------------------------------------------------------- */
/*      Open source dataset.                                            */
/* -------------------------------------------------------------------- */
    hSrcDS = GDALOpen( pszSrcFilename, GA_ReadOnly );
    
    if( hSrcDS == NULL )
        exit( 2 );

/* -------------------------------------------------------------------- */
/*      Check that there's at least one raster band                     */
/* -------------------------------------------------------------------- */
    if ( GDALGetRasterCount(hSrcDS) == 0 )
    {
        fprintf(stderr, "Input file %s has no raster bands.\n", pszSrcFilename );
        exit( 2 );
    }

    if( pszSourceSRS == NULL )
    {
        if( GDALGetProjectionRef( hSrcDS ) != NULL 
            && strlen(GDALGetProjectionRef( hSrcDS )) > 0 )
            pszSourceSRS = CPLStrdup(GDALGetProjectionRef( hSrcDS ));

        else if( GDALGetGCPProjection( hSrcDS ) != NULL
                 && strlen(GDALGetGCPProjection(hSrcDS)) > 0 
                 && GDALGetGCPCount( hSrcDS ) > 1 )
            pszSourceSRS = CPLStrdup(GDALGetGCPProjection( hSrcDS ));
        else
            pszSourceSRS = CPLStrdup("");
    }

    if( pszTargetSRS == NULL )
        pszTargetSRS = CPLStrdup(pszSourceSRS);

/* -------------------------------------------------------------------- */
/*      Does the output dataset already exist?                          */
/* -------------------------------------------------------------------- */
    CPLPushErrorHandler( CPLQuietErrorHandler );
    hDstDS = GDALOpen( pszDstFilename, GA_Update );
    CPLPopErrorHandler();

    if( hDstDS != NULL && bCreateOutput )
    {
        fprintf( stderr, 
                 "Output dataset %s exists,\n"
                 "but some commandline options were provided indicating a new dataset\n"
                 "should be created.  Please delete existing dataset and run again.",
                 pszDstFilename );
        exit( 1 );
    }

/* -------------------------------------------------------------------- */
/*      If not, we need to create it.                                   */
/* -------------------------------------------------------------------- */
    if( hDstDS == NULL )
    {
        hDstDS = GDALWarpCreateOutput( hSrcDS, pszDstFilename, pszFormat, 
                                       pszSourceSRS, pszTargetSRS, nOrder,
                                       papszCreateOptions );
        papszWarpOptions = CSLSetNameValue( papszWarpOptions, "INIT", "0" );
        CSLDestroy( papszCreateOptions );
        papszCreateOptions = NULL;
    }

    if( hDstDS == NULL )
        exit( 1 );

/* -------------------------------------------------------------------- */
/*      Create a transformation object from the source to               */
/*      destination coordinate system.                                  */
/* -------------------------------------------------------------------- */
    hTransformArg = hGenImgProjArg = 
        GDALCreateGenImgProjTransformer( hSrcDS, pszSourceSRS, 
                                         hDstDS, pszTargetSRS, 
                                         TRUE, 1000.0, nOrder );

    if( hTransformArg == NULL )
        exit( 1 );

    pfnTransformer = GDALGenImgProjTransform;

/* -------------------------------------------------------------------- */
/*      Warp the transformer with a linear approximator unless the      */
/*      acceptable error is zero.                                       */
/* -------------------------------------------------------------------- */
    if( dfErrorThreshold != 0.0 )
    {
        hTransformArg = hApproxArg = 
            GDALCreateApproxTransformer( GDALGenImgProjTransform, 
                                         hGenImgProjArg, dfErrorThreshold );
        pfnTransformer = GDALApproxTransform;
    }

/* -------------------------------------------------------------------- */
/*      Now actually invoke the warper to do the work.                  */
/* -------------------------------------------------------------------- */
    GDALSimpleImageWarp( hSrcDS, hDstDS, 0, NULL, 
                         pfnTransformer, hTransformArg,
                         GDALTermProgress, NULL, papszWarpOptions );

    CSLDestroy( papszWarpOptions );

    if( hApproxArg != NULL )
        GDALDestroyApproxTransformer( hApproxArg );

    if( hGenImgProjArg != NULL )
        GDALDestroyGenImgProjTransformer( hGenImgProjArg );

/* -------------------------------------------------------------------- */
/*      Cleanup.                                                        */
/* -------------------------------------------------------------------- */
    GDALClose( hDstDS );
    GDALClose( hSrcDS );

    GDALDumpOpenDatasets( stderr );

    GDALDestroyDriverManager();
    
    exit( 0 );
}
Exemple #9
0
static GDALDatasetH 
GDALWarpCreateOutput( GDALDatasetH hSrcDS, const char *pszFilename, 
                      const char *pszFormat, const char *pszSourceSRS, 
                      const char *pszTargetSRS, int nOrder,
                      char **papszCreateOptions )

{
    GDALDriverH hDriver;
    GDALDatasetH hDstDS;
    void *hTransformArg;
    double adfDstGeoTransform[6];
    int nPixels=0, nLines=0;
    GDALColorTableH hCT;

/* -------------------------------------------------------------------- */
/*      Find the output driver.                                         */
/* -------------------------------------------------------------------- */
    hDriver = GDALGetDriverByName( pszFormat );
    if( hDriver == NULL 
        || GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) == NULL )
    {
        int	iDr;
        
        printf( "Output driver `%s' not recognised or does not support\n", 
                pszFormat );
        printf( "direct output file creation.  The following format drivers are configured\n"
                "and support direct output:\n" );

        for( iDr = 0; iDr < GDALGetDriverCount(); iDr++ )
        {
            GDALDriverH hDriver = GDALGetDriver(iDr);

            if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL) != NULL )
            {
                printf( "  %s: %s\n",
                        GDALGetDriverShortName( hDriver  ),
                        GDALGetDriverLongName( hDriver ) );
            }
        }
        printf( "\n" );
        exit( 1 );
    }

/* -------------------------------------------------------------------- */
/*      Create a transformation object from the source to               */
/*      destination coordinate system.                                  */
/* -------------------------------------------------------------------- */
    hTransformArg = 
        GDALCreateGenImgProjTransformer( hSrcDS, pszSourceSRS, 
                                         NULL, pszTargetSRS, 
                                         TRUE, 1000.0, nOrder );

    if( hTransformArg == NULL )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Get approximate output definition.                              */
/* -------------------------------------------------------------------- */
    if( GDALSuggestedWarpOutput( hSrcDS, 
                                 GDALGenImgProjTransform, hTransformArg, 
                                 adfDstGeoTransform, &nPixels, &nLines )
        != CE_None )
        return NULL;

    GDALDestroyGenImgProjTransformer( hTransformArg );

/* -------------------------------------------------------------------- */
/*      Did the user override some parameters?                          */
/* -------------------------------------------------------------------- */
    if( dfXRes != 0.0 && dfYRes != 0.0 )
    {
        CPLAssert( nPixels == 0 && nLines == 0 );
        if( dfMinX == 0.0 && dfMinY == 0.0 && dfMaxX == 0.0 && dfMaxY == 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( nForcePixels != 0 && nForceLines != 0 )
    {
        if( dfMinX == 0.0 && dfMinY == 0.0 && dfMaxX == 0.0 && dfMaxY == 0.0 )
        {
            dfMinX = adfDstGeoTransform[0];
            dfMaxX = adfDstGeoTransform[0] + adfDstGeoTransform[1] * nPixels;
            dfMaxY = adfDstGeoTransform[3];
            dfMinY = adfDstGeoTransform[3] + adfDstGeoTransform[5] * nLines;
        }

        dfXRes = (dfMaxX - dfMinX) / nForcePixels;
        dfYRes = (dfMaxY - dfMinY) / nForceLines;

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

        nPixels = nForcePixels;
        nLines = nForceLines;
    }

    else if( dfMinX != 0.0 || dfMinY != 0.0 || dfMaxX != 0.0 || dfMaxY != 0.0 )
    {
        dfXRes = adfDstGeoTransform[1];
        dfYRes = fabs(adfDstGeoTransform[5]);

        nPixels = (int) ((dfMaxX - dfMinX + (dfXRes/2.0)) / dfXRes);
        nLines = (int) ((dfMaxY - dfMinY + (dfYRes/2.0)) / dfYRes);

        adfDstGeoTransform[0] = dfMinX;
        adfDstGeoTransform[3] = dfMaxY;
    }

/* -------------------------------------------------------------------- */
/*      Create the output file.                                         */
/* -------------------------------------------------------------------- */
    printf( "Creating output file is that %dP x %dL.\n", nPixels, nLines );

    hDstDS = GDALCreate( hDriver, pszFilename, nPixels, nLines, 
                         GDALGetRasterCount(hSrcDS),
                         GDALGetRasterDataType(GDALGetRasterBand(hSrcDS,1)),
                         papszCreateOptions );

    if( hDstDS == NULL )
        return NULL;

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

/* -------------------------------------------------------------------- */
/*      Copy the color table, if required.                              */
/* -------------------------------------------------------------------- */
    hCT = GDALGetRasterColorTable( GDALGetRasterBand(hSrcDS,1) );
    if( hCT != NULL )
        GDALSetRasterColorTable( GDALGetRasterBand(hDstDS,1), hCT );

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

	int	nx, ny, i, j, m, n, c = 0, n_pts, n_fields;
	char	*pszSrcSRS = NULL, *pszSrcWKT = NULL;
	char	*pszDstSRS = NULL, *pszDstWKT = NULL;
	double	*in_data, *ptr_d, *x, *y, *z;
	mxArray	*mx_ptr;

	int	nGCPCount = 0, nOrder = 0;
	char	**papszMetadataOptions = NULL;
	char	*tmp, *txt;
	int	bInverse = FALSE;
	int	*bSuccess;
	char	**papszTO = NULL;


	if (nrhs == 2 && mxIsStruct(prhs[1])) {

		/* -------------------------------------------------- */

		/* -------- 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, "inverse");
		if (mx_ptr != NULL)
			bInverse = TRUE;

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

	}
	else {
		mexPrintf("Usage: out = gdaltransform_mex(IN,PAR_STRUCT)\n\n");
		mexPrintf("      IN is a Mx2 or Mx3 array of doubles with X, Y (,Z)\n");
		mexPrintf("      PAR_STRUCT is a structure with at most two of the next fields:\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'inverse' reverse transformation. e.g from georef to rows-columns\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;
	}


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


	/* ----- Check that first argument contains at least a mx2 table */
	n_pts = mxGetM (prhs[0]);
	n_fields = mxGetN(prhs[0]);
	if (!mxIsNumeric(prhs[0]) || (n_fields < 2)) {
		mexPrintf("GDALTRANSFORM ERROR: first argument must contain a mx2 (or mx3) table\n");
		mexErrMsgTxt("               with the x,y (,z) positions to convert.\n");
	}

DEBUGA(1);
	/* ---------- 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("GDALTRANSFORM: Translating source SRS failed.");
	}
	if (pszSrcWKT == NULL)
		oSrcSRS.exportToWkt( &pszSrcWKT );

	/* ------------------------------------------------------------------ */


DEBUGA(2);
	/* ---------- 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("GDALTRANSFORM: Translating target SRS failed.");
	}
	if (pszDstWKT == NULL)
		oDstSRS.exportToWkt( &pszDstWKT );
	/* ------------------------------------------------------------------ */



	/* -------------------------------------------------------------------- */
	/*      Create a transformation object from the source to               */
	/*      destination coordinate system.                                  */
	/* -------------------------------------------------------------------- */
	if( nGCPCount != 0 && nOrder == -1 ) {
		pfnTransformer = GDALTPSTransform;
		hTransformArg = GDALCreateTPSTransformer( nGCPCount, pasGCPs, FALSE );
	}
	else if( nGCPCount != 0 ) {
DEBUGA(3);
		pfnTransformer = GDALGCPTransform;
		hTransformArg = GDALCreateGCPTransformer( nGCPCount, pasGCPs, nOrder, FALSE );
	}
	else {
		pfnTransformer = GDALGenImgProjTransform;
		//hTransformArg = GDALCreateGenImgProjTransformer2( hSrcDS, hDstDS, papszTO );
		hTransformArg = 
    			GDALCreateGenImgProjTransformer( NULL, pszSrcWKT, NULL, pszDstWKT, 
						 nGCPCount == 0 ? FALSE : TRUE, 0, nOrder );
	}

	//CSLDestroy( papszTO );
DEBUGA(4);

	if( hTransformArg == NULL )
		mexErrMsgTxt("GDALTRANSFORM: Generating transformer failed.");

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

	if (n_pts == 1) {
		x = &in_data[0];
		y = &in_data[1];
		bSuccess = &c;
	}
	else {
		x = (double *)mxCalloc(n_pts, sizeof(double));
		y = (double *)mxCalloc(n_pts, sizeof(double));
		bSuccess = (int *)mxCalloc(n_pts, sizeof(int));

		for (j = 0; j < n_pts; j++) {
			x[j] = in_data[j];
			y[j] = in_data[j+n_pts];
		}
	}
DEBUGA(5);

	z = (double *)mxCalloc(n_pts, sizeof(double));
	if (n_fields == 3)
		for (j = 0; j < n_pts; j++)
			z[j] = in_data[j+2*n_pts];

	if ( !pfnTransformer( hTransformArg, bInverse, n_pts, x, y, z, bSuccess ) )
		mexPrintf( "Transformation failed.\n" );


DEBUGA(6);
	if( nGCPCount != 0 && nOrder == -1 )
		GDALDestroyTPSTransformer(hTransformArg);
	else if( nGCPCount != 0 )
		GDALDestroyGCPTransformer(hTransformArg);
	else
		GDALDestroyGenImgProjTransformer(hTransformArg);


	/* -------------- Copy the result into plhs  --------------------------------- */
	plhs[0] = mxCreateDoubleMatrix (n_pts,n_fields, mxREAL);
	ptr_d = mxGetPr(plhs[0]);

	for (j = 0; j < n_pts; j++) {
		ptr_d[j] = x[j];
		ptr_d[j+n_pts] = y[j];
	}

	if (n_pts > 1) {
		mxFree((void *)x);	mxFree((void *)y);	mxFree((void *)bSuccess);
	}

	if (n_fields == 3) {
		for (j = 0; j < n_pts; j++)
			ptr_d[j+2*n_pts] = z[j];
	}
	mxFree((void *)z);


	if (pszDstWKT && strlen(pszDstWKT) > 1 ) OGRFree(pszDstWKT);	
	if (pszSrcWKT && strlen(pszSrcWKT) > 1 ) OGRFree(pszSrcWKT);
	//OGRFree(pszSrcWKT);
	//OGRFree(pszDstWKT);
	if (nGCPCount > 0) {
		GDALDeinitGCPs( nGCPCount, pasGCPs );	// makes this mex crash in the next call
		mxFree((void *) pasGCPs );
	}

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

}
Exemple #11
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);
}