Exemplo n.º 1
0
int sat_save_ch(s_sat * sat, const char * fname, unsigned ch)
{
	try;

		int ret = 0;
		unsigned height = sat->height, width = sat->width;
		GDALDatasetH ds = NULL;

		throw_null((ds = GDALCreate(drv_tiff, fname, width, height, 1, GDT_Byte, NULL)));

		throw((GDALSetProjection(ds, sat->proj_ref) == CE_Failure));
		throw((GDALSetGeoTransform(ds, sat->gt_coef) == CE_Failure));

		throw(GDALDatasetRasterIO(ds, GF_Write, 0, 0, width, height, sat->pixel[ch], width, height, GDT_Byte, 1, NULL, 0, 0, 0) == CE_Failure);

	catch;

		ret = -1;

	finally;

		if(ds != NULL)
			GDALClose(ds);

	return ret;
}
/* Makes a copy of a dataset, and opens it for writing.. */
GDALDatasetH
make_me_a_sandwitch (GDALDatasetH * in_dataset, const char *copy_file_name)
{
  char **papszOptions = NULL;
  const char *pszFormat = "GTiff";
  double adfGeoTransform[6];
  GDALDriverH hDriver;
  GDALDatasetH out_gdalfile;
  hDriver = GDALGetDriverByName (pszFormat);
  papszOptions = CSLSetNameValue (papszOptions, "TILED", "YES");
  papszOptions = CSLSetNameValue (papszOptions, "COMPRESS", "DEFLATE");

  /*Perhaps controversal - default to bigtiff... */
  /*papszOptions = CSLSetNameValue( papszOptions, "BIGTIFF", "YES" ); */

  /*return GDALCreateCopy( hDriver, copy_file_name, *in_dataset, FALSE, papszOptions, NULL, NULL ); */
  out_gdalfile = GDALCreate (hDriver, copy_file_name,
			     GDALGetRasterXSize (*in_dataset),
			     GDALGetRasterYSize (*in_dataset),
			     GDALGetRasterCount (*in_dataset),
			     GDT_Byte, papszOptions);

  /* Set geotransform */
  GDALGetGeoTransform (*in_dataset, adfGeoTransform);
  GDALSetGeoTransform (out_gdalfile, adfGeoTransform);

  /* Set projection */
  GDALSetProjection (out_gdalfile, GDALGetProjectionRef (*in_dataset));
  return out_gdalfile;
}
Exemplo n.º 3
0
//void CUtils::createNewByteGeoTIFF(const char* fileName, int bands, int rows, int cols, double adfGeoTransform[6], char szProjection[512], byte fillData, byte noDataValue)
void CUtils::createNewByteGeoTIFF(const char* fileName, int bands, int rows, int cols, double adfGeoTransform[6], const char * szProjection, byte fillData, byte noDataValue)
{
	char **papszOptions = NULL;
    GDALDriverH hDriver;
    GDALRasterBandH hDataset;
//	GDALRasterBandH hBand;
	if( (hDriver = GDALGetDriverByName("GTiff")) != NULL)
	{
		fprintf(stderr, "Create image %s...\n", fileName);
        if( (hDataset = GDALCreate( hDriver, fileName, cols, rows, bands, GDT_Byte, papszOptions )) !=NULL )
		{
			GDALSetGeoTransform(hDataset, adfGeoTransform );
			GDALSetProjection(hDataset, szProjection );
			/*
			int pr = CUtils::progress_ln_ex(stderr, 0, 0, START_PROGRESS);
			for(int band = 1; band<=bands; band++)
			{
				if( (hBand = GDALGetRasterBand(hDataset, band)) != NULL )
				{
					byte *pline = (byte *)CPLMalloc(sizeof(byte)*cols);
					for(int i=0; i<cols; i++) pline[i] = fillData;

					for(int i=0; i<rows; i++) GDALRasterIO(hBand, GF_Write, 0, i, cols, 1, pline, cols, 1, GDT_Byte, 0, 0 );
					CPLFree(pline);

					GDALSetRasterNoDataValue(hBand, noDataValue);
				}
				pr = CUtils::progress_ln_ex(stderr, band-1, bands, pr);
			}
			CUtils::progress_ln_ex(stderr, 0, 0, END_PROGRESS);
			*/
			GDALClose(hDataset);
		}
	}
}
Exemplo n.º 4
0
GDALDatasetH QgsRelief::openOutputFile( GDALDatasetH inputDataset, GDALDriverH outputDriver )
{
  if ( !inputDataset )
  {
    return nullptr;
  }

  int xSize = GDALGetRasterXSize( inputDataset );
  int ySize = GDALGetRasterYSize( inputDataset );

  //open output file
  char **papszOptions = nullptr;

  //use PACKBITS compression for tiffs by default
  papszOptions = CSLSetNameValue( papszOptions, "COMPRESS", "PACKBITS" );

  //create three band raster (reg, green, blue)
  GDALDatasetH outputDataset = GDALCreate( outputDriver, mOutputFile.toUtf8().constData(), xSize, ySize, 3, GDT_Byte, papszOptions );
  if ( !outputDataset )
  {
    return outputDataset;
  }

  //get geotransform from inputDataset
  double geotransform[6];
  if ( GDALGetGeoTransform( inputDataset, geotransform ) != CE_None )
  {
    GDALClose( outputDataset );
    return nullptr;
  }
  GDALSetGeoTransform( outputDataset, geotransform );

  //make sure mCellSizeX and mCellSizeY are always > 0
  mCellSizeX = geotransform[1];
  if ( mCellSizeX < 0 )
  {
    mCellSizeX = -mCellSizeX;
  }
  mCellSizeY = geotransform[5];
  if ( mCellSizeY < 0 )
  {
    mCellSizeY = -mCellSizeY;
  }

  const char *projection = GDALGetProjectionRef( inputDataset );
  GDALSetProjection( outputDataset, projection );

  return outputDataset;
}
Exemplo n.º 5
0
bool QgsGdalLayerItem::setCrs( const QgsCoordinateReferenceSystem &crs )
{
    GDALDatasetH hDS = GDALOpen( mPath.toUtf8().constData(), GA_Update );
    if ( !hDS )
        return false;

    QString wkt = crs.toWkt();
    if ( GDALSetProjection( hDS, wkt.toLocal8Bit().data() ) != CE_None )
    {
        GDALClose( hDS );
        QgsDebugMsg( "Could not set CRS" );
        return false;
    }

    GDALClose( hDS );
    return true;
}
Exemplo n.º 6
0
static dErr JakoGDALDatasetCreateMem(OGRSpatialReferenceH ref,const double geo[6],dInt n,dInt nlines,GDALDataType dtype,GDALDatasetH *dset,void *bandmem)
{
  char *wkt;
  GDALDriverH memdriver;
  CPLErr cplerr;
  OGRErr oerr;
  dErr err;

  dFunctionBegin;
  oerr = OSRExportToWkt(ref,&wkt);dOGRCHK(oerr);
  memdriver = GDALGetDriverByName("MEM");
  *dset = GDALCreate(memdriver,"MEM:::",n,nlines,0,dtype,NULL);
  cplerr = GDALSetProjection(*dset,wkt);dCPLCHK(cplerr);
  cplerr = GDALSetGeoTransform(*dset,(double*)geo);dCPLCHK(cplerr); /* const-incorrect interface */
  OGRFree(wkt);
  if (bandmem) {err = JakoGDALMemAddBand(*dset,GDT_Float64,&bandmem);dCHK(err);}
  dFunctionReturn(0);
}
Exemplo n.º 7
0
bool QgsGdalLayerItem::setCrs( QgsCoordinateReferenceSystem crs )
{
  QgsDebugMsg( "mPath = " + mPath );
  GDALAllRegister();
  GDALDatasetH hDS = GDALOpen( TO8F( mPath ), GA_Update );

  if ( !hDS )
    return false;

  QString wkt = crs.toWkt();
  if ( GDALSetProjection( hDS, wkt.toLocal8Bit().data() ) != CE_None )
  {
    QgsDebugMsg( "Could not set CRS" );
    return false;
  }
  GDALClose( hDS );
  return true;
}
Exemplo n.º 8
0
GDALDatasetH QgsNineCellFilter::openOutputFile( GDALDatasetH inputDataset, GDALDriverH outputDriver )
{
  if ( inputDataset == NULL )
  {
    return NULL;
  }

  int xSize = GDALGetRasterXSize( inputDataset );
  int ySize = GDALGetRasterYSize( inputDataset );;

  //open output file
  char **papszOptions = NULL;
  GDALDatasetH outputDataset = GDALCreate( outputDriver, mOutputFile.toLocal8Bit().data(), xSize, ySize, 1, GDT_Float32, papszOptions );
  if ( outputDataset == NULL )
  {
    return outputDataset;
  }

  //get geotransform from inputDataset
  double geotransform[6];
  if ( GDALGetGeoTransform( inputDataset, geotransform ) != CE_None )
  {
    GDALClose( outputDataset );
    return NULL;
  }
  GDALSetGeoTransform( outputDataset, geotransform );

  //make sure mCellSizeX and mCellSizeY are always > 0
  mCellSizeX = geotransform[1];
  if ( mCellSizeX < 0 )
  {
    mCellSizeX = -mCellSizeX;
  }
  mCellSizeY = geotransform[5];
  if ( mCellSizeY < 0 )
  {
    mCellSizeY = -mCellSizeY;
  }

  const char* projection = GDALGetProjectionRef( inputDataset );
  GDALSetProjection( outputDataset, projection );

  return outputDataset;
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
0
s_sat * sat_rasterize_copy(s_sat * c_sat, OGRGeometryH geometry)
{
	try;

		int band = 1;
		unsigned height, width, height_width;
		double burn_value = 255;
		GDALDatasetH ds = NULL;
		s_sat * sat = NULL;

		throw_null((sat = sat_init(1)));

		height = sat->height = c_sat->height;
		width = sat->width = c_sat->width;
		height_width = height * width;
		sat->proj_ref = strdup(c_sat->proj_ref);
		sat->ch_num = 0;

		memcpy(sat->gt_coef, c_sat->gt_coef, sizeof(double) * 6);
		throw_null((sat->pixel[0] = sfire_alloc(sizeof(uint8_t), 1, height_width)));

		sat->ch_num = 1;

		throw_null((ds = GDALCreate(drv_r_mem, "", width, height, 1, GDT_Byte, NULL)));
		throw((GDALSetProjection(ds, sat->proj_ref) == CE_Failure));
		throw((GDALSetGeoTransform(ds, sat->gt_coef) == CE_Failure));

		throw((GDALRasterizeGeometries(ds, 1, & band, 1, & geometry, NULL, NULL, & burn_value, NULL, NULL, NULL) == CE_Failure));

		throw(GDALDatasetRasterIO(ds, GF_Read, 0, 0, width, height, sat->pixel[0], width, height, GDT_Byte, 1, NULL, 0, 0, 0) == CE_Failure);

	catch;

		sat_destroy(sat);

		sat = NULL;

	finally;

		if(ds != NULL)
			GDALClose(ds);

	return sat;
}
Exemplo n.º 11
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;
}
int main( int argc, char ** argv )
{
    GDALDriverH     hDriver;
    const char      *pszSource=NULL, *pszDest=NULL, *pszFormat = "GTiff";
    int             bFormatExplicitelySet = 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;

    /* 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];
            bFormatExplicitelySet = 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 = atof(argv[++i]);
            dfXMax = atof(argv[++i]);
            bIsXExtentSet = TRUE;
        }   

        else if( EQUAL(argv[i],"-tye") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2);
            dfYMin = atof(argv[++i]);
            dfYMax = atof(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 = atof(argv[++i]);
        }

        else if( EQUAL(argv[i],"-z_multiply") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            dfMultiplyBurnValue = atof(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( atof(argv[i+1]), atof(argv[i+2]) );
            oRing.addPoint( atof(argv[i+1]), atof(argv[i+4]) );
            oRing.addPoint( atof(argv[i+3]), atof(argv[i+4]) );
            oRing.addPoint( atof(argv[i+3]), atof(argv[i+2]) );
            oRing.addPoint( atof(argv[i+1]), atof(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( atof(argv[i + 1]), atof(argv[i + 2]) );
                oRing.addPoint( atof(argv[i + 1]), atof(argv[i + 4]) );
                oRing.addPoint( atof(argv[i + 3]), atof(argv[i + 4]) );
                oRing.addPoint( atof(argv[i + 3]), atof(argv[i + 2]) );
                oRing.addPoint( atof(argv[i + 1]), atof(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);
            if ( ParseAlgorithmAndOptions( argv[++i], &eAlgorithm, &pOptions )
                 != CE_None )
            {
                fprintf( stderr,
                         "Failed to process algorithm name and parameters.\n" );
                exit( 1 );
            }
        }

        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_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 && !bFormatExplicitelySet)
        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 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;
}
Exemplo n.º 13
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( TO8( it->raster->source() ), GA_ReadOnly );
    if ( inputDataset == NULL )
    {
      return 2;
    }

    //check if the input dataset is south up or rotated. If yes, use GDALAutoCreateWarpedVRT to create a north up raster
    double inputGeoTransform[6];
    if ( GDALGetGeoTransform( inputDataset, inputGeoTransform ) == CE_None
         && ( inputGeoTransform[1] < 0.0
              || inputGeoTransform[2] != 0.0
              || inputGeoTransform[4] != 0.0
              || inputGeoTransform[5] > 0.0 ) )
    {
      GDALDatasetH vDataset = GDALAutoCreateWarpedVRT( inputDataset, NULL, NULL, GRA_NearestNeighbour, 0.2, NULL );
      mInputDatasets.push_back( vDataset );
      mInputDatasets.push_back( inputDataset );
      inputDataset = vDataset;
    }
    else
    {
      mInputDatasets.push_back( inputDataset );
    }


    GDALRasterBandH inputRasterBand = GDALGetRasterBand( inputDataset, it->bandNumber );
    if ( inputRasterBand == NULL )
    {
      return 2;
    }

    int nodataSuccess;
    double nodataValue = GDALGetRasterNoDataValue( inputRasterBand, &nodataSuccess );

    mInputRasterBands.insert( it->ref, inputRasterBand );
    inputScanLineData.insert( it->ref, new QgsRasterMatrix( mNumOutputColumns, 1, new float[mNumOutputColumns], nodataValue ) );
  }

  //open output dataset for writing
  GDALDriverH outputDriver = openOutputDriver();
  if ( outputDriver == NULL )
  {
    return 1;
  }
  GDALDatasetH outputDataset = openOutputFile( outputDriver );

  //copy the projection info from the first input raster
  if ( mRasterEntries.size() > 0 )
  {
    QgsRasterLayer* rl = mRasterEntries.at( 0 ).raster;
    if ( rl )
    {
      char* crsWKT = 0;
      OGRSpatialReferenceH ogrSRS = OSRNewSpatialReference( NULL );
      if ( OSRSetFromUserInput( ogrSRS, rl->crs().authid().toUtf8().constData() ) == OGRERR_NONE )
      {
        OSRExportToWkt( ogrSRS, &crsWKT );
        GDALSetProjection( outputDataset, crsWKT );
      }
      else
      {
        GDALSetProjection( outputDataset, TO8( rl->crs().toWkt() ) );
      }
      OSRDestroySpatialReference( ogrSRS );
      CPLFree( crsWKT );
    }
  }


  GDALRasterBandH outputRasterBand = GDALGetRasterBand( outputDataset, 1 );

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

  float* resultScanLine = ( float * ) CPLMalloc( sizeof( float ) * mNumOutputColumns );

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

  QgsRasterMatrix resultMatrix;

  //read / write line by line
  for ( int i = 0; i < mNumOutputRows; ++i )
  {
    if ( p )
    {
      p->setValue( i );
    }

    if ( p && p->wasCanceled() )
    {
      break;
    }

    //fill buffers
    QMap< QString, QgsRasterMatrix* >::iterator bufferIt = inputScanLineData.begin();
    for ( ; bufferIt != inputScanLineData.end(); ++bufferIt )
    {
      double sourceTransformation[6];
      GDALRasterBandH sourceRasterBand = mInputRasterBands[bufferIt.key()];
      GDALGetGeoTransform( GDALGetBandDataset( sourceRasterBand ), sourceTransformation );
      //the function readRasterPart calls GDALRasterIO (and ev. does some conversion if raster transformations are not the same)
      readRasterPart( targetGeoTransform, 0, i, mNumOutputColumns, 1, sourceTransformation, sourceRasterBand, bufferIt.value()->data() );
    }

    if ( calcNode->calculate( inputScanLineData, resultMatrix ) )
    {
      bool resultIsNumber = resultMatrix.isNumber();
      float* calcData;

      if ( resultIsNumber ) //scalar result. Insert number for every pixel
      {
        calcData = new float[mNumOutputColumns];
        for ( int j = 0; j < mNumOutputColumns; ++j )
        {
          calcData[j] = resultMatrix.number();
        }
      }
      else //result is real matrix
      {
        calcData = resultMatrix.data();
      }

      //replace all matrix nodata values with output nodatas
      for ( int j = 0; j < mNumOutputColumns; ++j )
      {
        if ( calcData[j] == resultMatrix.nodataValue() )
        {
          calcData[j] = outputNodataValue;
        }
      }

      //write scanline to the dataset
      if ( GDALRasterIO( outputRasterBand, GF_Write, 0, i, mNumOutputColumns, 1, calcData, mNumOutputColumns, 1, GDT_Float32, 0, 0 ) != CE_None )
      {
        qWarning( "RasterIO error!" );
      }

      if ( resultIsNumber )
      {
        delete[] calcData;
      }
    }

  }

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

  //close datasets and release memory
  delete calcNode;
  QMap< QString, QgsRasterMatrix* >::iterator bufferIt = inputScanLineData.begin();
  for ( ; bufferIt != inputScanLineData.end(); ++bufferIt )
  {
    delete bufferIt.value();
  }
  inputScanLineData.clear();

  QVector< GDALDatasetH >::iterator datasetIt = mInputDatasets.begin();
  for ( ; datasetIt != mInputDatasets.end(); ++ datasetIt )
  {
    GDALClose( *datasetIt );
  }

  if ( p && p->wasCanceled() )
  {
    //delete the dataset without closing (because it is faster)
    GDALDeleteDataset( outputDriver, mOutputFile.toLocal8Bit().data() );
    return 3;
  }
  GDALClose( outputDataset );
  CPLFree( resultScanLine );
  return 0;
}
Exemplo n.º 14
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);
}
Exemplo n.º 15
0
int main( int argc, char ** argv )

{
    /* Check that we are running against at least GDAL 1.4 (probably older in fact !) */
    /* Note to developers : if we use newer API, please change the requirement */
    if (atoi(GDALVersionInfo("VERSION_NUM")) < 1400)
    {
        fprintf(stderr, "At least, GDAL >= 1.4.0 is required for this version of %s, "
                "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME);
        exit(1);
    }

/* -------------------------------------------------------------------- */
/*      Generic arg processing.                                         */
/* -------------------------------------------------------------------- */
    GDALAllRegister();
    GDALSetCacheMax( 100000000 );
    argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
    if( argc < 1 )
        exit( -argc );
    
/* -------------------------------------------------------------------- */
/*      Parse arguments.                                                */
/* -------------------------------------------------------------------- */
    int i;
    const char *pszOutFile = NULL;
    const char *pszInFile = NULL;
    int nMaxNonBlack = 2;
    int nNearDist = 15;
    int bNearWhite = FALSE;
    int bSetAlpha = FALSE;
    int bSetMask = FALSE;
    const char* pszDriverName = "HFA";
    int bFormatExplicitelySet = FALSE;
    char** papszCreationOptions = NULL;
    int bQuiet = FALSE;

    Colors oColors;
    
    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], "-o") && i < argc-1 )
            pszOutFile = argv[++i];
        else if( EQUAL(argv[i], "-of") && i < argc-1 )
        {
            pszDriverName = argv[++i];
            bFormatExplicitelySet = TRUE;
        }
        else if( EQUAL(argv[i], "-white") ) {
            bNearWhite = TRUE;
        }

        /***** -color c1,c2,c3...cn *****/
        
        else if( EQUAL(argv[i], "-color") && i < argc-1 ) {
            Color oColor;
            
            /***** tokenize the arg on , *****/
            
            char **papszTokens;
            papszTokens = CSLTokenizeString2( argv[++i], ",", 0 );

            /***** loop over the tokens *****/
            
            int iToken;
            for( iToken = 0; papszTokens && papszTokens[iToken]; iToken++ )
            {

                /***** ensure the token is an int and add it to the color *****/
                
                if ( IsInt( papszTokens[iToken] ) )
                    oColor.push_back( atoi( papszTokens[iToken] ) );
                else {
                    CPLError(CE_Failure, CPLE_AppDefined,
                             "Colors must be valid integers." );
                    CSLDestroy( papszTokens );
                    exit(1);
                }
            }
            
            CSLDestroy( papszTokens );

            /***** check if the number of bands is consistant *****/

            if ( oColors.size() > 0 &&
                 oColors.front().size() != oColor.size() )
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                         "ERROR: all -color args must have the same number of values.\n" );
                exit(1);
            }

            /***** add the color to the colors *****/
            
            oColors.push_back( oColor );
            
        }
        
        else if( EQUAL(argv[i], "-nb") && i < argc-1 )
            nMaxNonBlack = atoi(argv[++i]);
        else if( EQUAL(argv[i], "-near") && i < argc-1 )
            nNearDist = atoi(argv[++i]);
        else if( EQUAL(argv[i], "-setalpha") )
            bSetAlpha = TRUE;
        else if( EQUAL(argv[i], "-setmask") )
            bSetMask = TRUE;
        else if( EQUAL(argv[i], "-q") || EQUAL(argv[i], "-quiet") )
            bQuiet = TRUE;
        else if( EQUAL(argv[i], "-co") && i < argc-1 )
            papszCreationOptions = CSLAddString(papszCreationOptions, argv[++i]);
        else if( argv[i][0] == '-' )
            Usage();
        else if( pszInFile == NULL )
            pszInFile = argv[i];
        else
            Usage();
    }

    if( pszInFile == NULL )
        Usage();

    if( pszOutFile == NULL )
        pszOutFile = pszInFile;

/* -------------------------------------------------------------------- */
/*      Open input file.                                                */
/* -------------------------------------------------------------------- */
    GDALDatasetH hInDS, hOutDS = NULL;
    int nXSize, nYSize, nBands;

    if( pszOutFile == pszInFile )
        hInDS = hOutDS = GDALOpen( pszInFile, GA_Update );
    else
        hInDS = GDALOpen( pszInFile, GA_ReadOnly );

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

    nXSize = GDALGetRasterXSize( hInDS );
    nYSize = GDALGetRasterYSize( hInDS );
    nBands = GDALGetRasterCount( hInDS );
    int nDstBands = nBands;

    if( hOutDS != NULL && papszCreationOptions != NULL)
    {
        CPLError(CE_Warning, CPLE_AppDefined,
                  "Warning: creation options are ignored when writing to an existing file.");
    }

/* -------------------------------------------------------------------- */
/*      Do we need to create output file?                               */
/* -------------------------------------------------------------------- */
    if( hOutDS == NULL )
    {
        GDALDriverH hDriver = GDALGetDriverByName( pszDriverName );
        if (hDriver == NULL)
            exit(1);

        if (!bQuiet && !bFormatExplicitelySet)
            CheckExtensionConsistency(pszOutFile, pszDriverName);

        if (bSetAlpha)
        {
            /***** fixme there should be a way to preserve alpha band data not in the collar *****/
            if (nBands == 4)
                nBands --;
            else
                nDstBands ++;
        }

        if (bSetMask)
        {
            if (nBands == 4)
                nDstBands = nBands = 3;
        }

        hOutDS = GDALCreate( hDriver, pszOutFile, 
                             nXSize, nYSize, nDstBands, GDT_Byte, 
                             papszCreationOptions );
        if( hOutDS == NULL )
            exit( 1 );

        double adfGeoTransform[6];

        if( GDALGetGeoTransform( hInDS, adfGeoTransform ) == CE_None )
        {
            GDALSetGeoTransform( hOutDS, adfGeoTransform );
            GDALSetProjection( hOutDS, GDALGetProjectionRef( hInDS ) );
        }
    }
    else
    {
        if (bSetAlpha)
        {
            if (nBands != 4 &&
                (nBands < 2 ||
                 GDALGetRasterColorInterpretation(GDALGetRasterBand(hOutDS, nBands)) != GCI_AlphaBand))
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                        "Last band is not an alpha band.");
                exit(1);
            }

            nBands --;
        }

        if (bSetMask)
        {
            if (nBands == 4)
                nDstBands = nBands = 3;
        }
    }

    /***** set a color if there are no colors set? *****/

    if ( oColors.size() == 0) {
        Color oColor;

        /***** loop over the bands to get the right number of values *****/

        int iBand;
        for (iBand = 0; iBand < nBands ; iBand++) {

            /***** black or white? *****/

            if (bNearWhite) 
                oColor.push_back(255);
            else
                oColor.push_back(0);
        }

        /***** add the color to the colors *****/

        oColors.push_back(oColor);
            
    }

    /***** does the number of bands match the number of color values? *****/

    if ( (int)oColors.front().size() != nBands ) {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "-color args must have the same number of values as the non alpha input band count.\n" );
        exit(1); 
    }

    /***** check the input and output datasets are the same size *****/
    
    if (GDALGetRasterXSize(hOutDS) != nXSize ||
        GDALGetRasterYSize(hOutDS) != nYSize)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "The dimensions of the output dataset don't match "
                 "the dimensions of the input dataset.");
        exit(1);
    }


    int iBand;
    for( iBand = 0; iBand < nBands; iBand++ )
    {
        GDALRasterBandH hBand = GDALGetRasterBand(hInDS, iBand+1);
        if (GDALGetRasterDataType(hBand) != GDT_Byte)
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Band %d is not of type GDT_Byte. It can lead to unexpected results.", iBand+1);
        }
        if (GDALGetRasterColorTable(hBand) != NULL)
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Band %d has a color table, which is ignored by nearblack. "
                     "It can lead to unexpected results.", iBand+1);
        }
    }

    GDALRasterBandH hMaskBand = NULL;
    
    if (bSetMask) {

        /***** if there isn't already a mask band on the output file create one *****/
        
        if ( GMF_PER_DATASET != GDALGetMaskFlags( GDALGetRasterBand(hOutDS, 1) ) )
        {

            if ( CE_None != GDALCreateDatasetMaskBand(hOutDS, GMF_PER_DATASET) ) {
                CPLError(CE_Failure, CPLE_AppDefined,
                         "Failed to create mask band on output DS");
                bSetMask = FALSE;
            }
        }

        if (bSetMask) {
            hMaskBand = GDALGetMaskBand(GDALGetRasterBand(hOutDS, 1));
        }
    }

/* -------------------------------------------------------------------- */
/*      Allocate a line buffer.                                         */
/* -------------------------------------------------------------------- */
    GByte *pabyLine;
    GByte *pabyMask=NULL;
    
    int   *panLastLineCounts;

    pabyLine = (GByte *) CPLMalloc(nXSize * nDstBands);
    
    if (bSetMask)
        pabyMask = (GByte *) CPLMalloc(nXSize);
    
    panLastLineCounts = (int *) CPLCalloc(sizeof(int),nXSize);

/* -------------------------------------------------------------------- */
/*      Processing data one line at a time.                             */
/* -------------------------------------------------------------------- */
    int iLine;

    for( iLine = 0; iLine < nYSize; iLine++ )
    {
        CPLErr eErr;

        eErr = GDALDatasetRasterIO( hInDS, GF_Read, 0, iLine, nXSize, 1, 
                                    pabyLine, nXSize, 1, GDT_Byte, 
                                    nBands, NULL, nDstBands, nXSize * nDstBands, 1 );
        if( eErr != CE_None )
            break;
        
        if (bSetAlpha)
        {
            int iCol;
            for(iCol = 0; iCol < nXSize; iCol ++)
            {
                pabyLine[iCol * nDstBands + nDstBands - 1] = 255;
            }
        }
        
        if (bSetMask)
        {
            int iCol;
            for(iCol = 0; iCol < nXSize; iCol ++)
            {
                pabyMask[iCol] = 255;
            }
        }
        
        ProcessLine( pabyLine, pabyMask, 0, nXSize-1, nBands, nDstBands,
                     nNearDist, nMaxNonBlack, bNearWhite, &oColors,
                     panLastLineCounts,
                     TRUE, // bDoHorizontalCheck
                     TRUE, // bDoVerticalCheck
                     FALSE // bBottomUp
                    );
        ProcessLine( pabyLine, pabyMask, nXSize-1, 0, nBands, nDstBands,
                     nNearDist, nMaxNonBlack, bNearWhite, &oColors,
                     panLastLineCounts,
                     TRUE,  // bDoHorizontalCheck
                     FALSE, // bDoVerticalCheck
                     FALSE  // bBottomUp
                    );
        
        eErr = GDALDatasetRasterIO( hOutDS, GF_Write, 0, iLine, nXSize, 1, 
                                    pabyLine, nXSize, 1, GDT_Byte, 
                                    nDstBands, NULL, nDstBands, nXSize * nDstBands, 1 );

        if( eErr != CE_None )
            break;
    
        /***** write out the mask band line *****/

        if (bSetMask) {

            eErr = GDALRasterIO ( hMaskBand, GF_Write, 0, iLine, nXSize, 1,
                                  pabyMask, nXSize, 1, GDT_Byte,
                                  0, 0 );
                             
            if( eErr != CE_None ) {
                CPLError(CE_Warning, CPLE_AppDefined,
                         "ERROR writeing out line to mask band.");
               break;
            }
        }
        
        if (!bQuiet)
            GDALTermProgress( 0.5 * ((iLine+1) / (double) nYSize), NULL, NULL );
    }

/* -------------------------------------------------------------------- */
/*      Now process from the bottom back up                            .*/
/* -------------------------------------------------------------------- */
    memset( panLastLineCounts, 0, sizeof(int) * nXSize);
    
    for( iLine = nYSize-1; iLine >= 0; iLine-- )
    {
        CPLErr eErr;

        eErr = GDALDatasetRasterIO( hOutDS, GF_Read, 0, iLine, nXSize, 1, 
                                    pabyLine, nXSize, 1, GDT_Byte, 
                                    nDstBands, NULL, nDstBands, nXSize * nDstBands, 1 );
        if( eErr != CE_None )
            break;

        /***** read the mask band line back in *****/

        if (bSetMask) {

            eErr = GDALRasterIO ( hMaskBand, GF_Read, 0, iLine, nXSize, 1,
                                  pabyMask, nXSize, 1, GDT_Byte,
                                  0, 0 );
                             
                                
            if( eErr != CE_None )
                break;
        }

        
        ProcessLine( pabyLine, pabyMask, 0, nXSize-1, nBands, nDstBands,
                     nNearDist, nMaxNonBlack, bNearWhite, &oColors,
                     panLastLineCounts,
                     TRUE, // bDoHorizontalCheck
                     TRUE, // bDoVerticalCheck
                     TRUE  // bBottomUp
                   );
        ProcessLine( pabyLine, pabyMask, nXSize-1, 0, nBands, nDstBands,
                     nNearDist, nMaxNonBlack, bNearWhite, &oColors,
                     panLastLineCounts,
                     TRUE,  // bDoHorizontalCheck
                     FALSE, // bDoVerticalCheck
                     TRUE   // bBottomUp
                    );
        
        eErr = GDALDatasetRasterIO( hOutDS, GF_Write, 0, iLine, nXSize, 1, 
                                    pabyLine, nXSize, 1, GDT_Byte, 
                                    nDstBands, NULL, nDstBands, nXSize * nDstBands, 1 );
        if( eErr != CE_None )
            break;

        /***** write out the mask band line *****/

        if (bSetMask) {

            eErr = GDALRasterIO ( hMaskBand, GF_Write, 0, iLine, nXSize, 1,
                                  pabyMask, nXSize, 1, GDT_Byte,
                                  0, 0 );
                             
                                
            if( eErr != CE_None )
                break;
        }

        
        if (!bQuiet)
            GDALTermProgress( 0.5 + 0.5 * (nYSize-iLine) / (double) nYSize, 
                            NULL, NULL );
    }

    CPLFree(pabyLine);
    if (bSetMask)
        CPLFree(pabyMask);
    
    CPLFree( panLastLineCounts );

    GDALClose( hOutDS );
    if( hInDS != hOutDS )
        GDALClose( hInDS );
    GDALDumpOpenDatasets( stderr );
    CSLDestroy( argv );
    CSLDestroy( papszCreationOptions );
    GDALDestroyDriverManager();
    
    return 0;
}
Exemplo n.º 16
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;
}
Exemplo n.º 17
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);
}
Exemplo n.º 18
0
QgsRasterCalculator::Result QgsRasterCalculator::processCalculationGPU( std::unique_ptr< QgsRasterCalcNode > calcNode, QgsFeedback *feedback )
{

  QString cExpression( calcNode->toString( true ) );

  QList<const QgsRasterCalcNode *> nodeList( calcNode->findNodes( QgsRasterCalcNode::Type::tRasterRef ) );
  QSet<QString> capturedTexts;
  for ( const auto &r : qgis::as_const( nodeList ) )
  {
    QString s( r->toString().remove( 0, 1 ) );
    s.chop( 1 );
    capturedTexts.insert( s );
  }

  // Extract all references
  struct LayerRef
  {
    QString name;
    int band;
    QgsRasterLayer *layer = nullptr;
    QString varName;
    QString typeName;
    size_t index;
    size_t bufferSize;
    size_t dataSize;
  };

  // Collects all layers, band, name, varName and size information
  std::vector<LayerRef> inputRefs;
  size_t refCounter = 0;
  for ( const auto &r : capturedTexts )
  {
    if ( r.startsWith( '"' ) )
      continue;
    QStringList parts( r.split( '@' ) );
    if ( parts.count() != 2 )
      continue;
    bool ok = false;
    LayerRef entry;
    entry.name = r;
    entry.band = parts[1].toInt( &ok );
    for ( const auto &ref : mRasterEntries )
    {
      if ( ref.ref == entry.name )
        entry.layer = ref.raster;
    }
    if ( !( entry.layer && entry.layer->dataProvider() && ok ) )
      continue;
    entry.dataSize = entry.layer->dataProvider()->dataTypeSize( entry.band );
    switch ( entry.layer->dataProvider()->dataType( entry.band ) )
    {
      case Qgis::DataType::Byte:
        entry.typeName = QStringLiteral( "unsigned char" );
        break;
      case Qgis::DataType::UInt16:
        entry.typeName = QStringLiteral( "unsigned int" );
        break;
      case Qgis::DataType::Int16:
        entry.typeName = QStringLiteral( "short" );
        break;
      case Qgis::DataType::UInt32:
        entry.typeName = QStringLiteral( "unsigned int" );
        break;
      case Qgis::DataType::Int32:
        entry.typeName = QStringLiteral( "int" );
        break;
      case Qgis::DataType::Float32:
        entry.typeName = QStringLiteral( "float" );
        break;
      // FIXME: not sure all OpenCL implementations support double
      //        maybe safer to fall back to the CPU implementation
      //        after a compatibility check
      case Qgis::DataType::Float64:
        entry.typeName = QStringLiteral( "double" );
        break;
      default:
        return BandError;
    }
    entry.bufferSize = entry.dataSize * mNumOutputColumns;
    entry.index = refCounter;
    entry.varName = QStringLiteral( "input_raster_%1_band_%2" )
                    .arg( refCounter++ )
                    .arg( entry.band );
    inputRefs.push_back( entry );
  }

  // Prepare context and queue
  cl::Context ctx( QgsOpenClUtils::context() );
  cl::CommandQueue queue( QgsOpenClUtils::commandQueue() );

  // Create the C expression
  std::vector<cl::Buffer> inputBuffers;
  inputBuffers.reserve( inputRefs.size() );
  QStringList inputArgs;
  for ( const auto &ref : inputRefs )
  {
    cExpression.replace( QStringLiteral( "\"%1\"" ).arg( ref.name ), QStringLiteral( "%1[i]" ).arg( ref.varName ) );
    inputArgs.append( QStringLiteral( "__global %1 *%2" )
                      .arg( ref.typeName )
                      .arg( ref.varName ) );
    inputBuffers.push_back( cl::Buffer( ctx, CL_MEM_READ_ONLY, ref.bufferSize, nullptr, nullptr ) );
  }

  //qDebug() << cExpression;

  // Create the program
  QString programTemplate( R"CL(
  // Inputs:
  ##INPUT_DESC##
  // Expression: ##EXPRESSION_ORIGINAL##
  __kernel void rasterCalculator( ##INPUT##
                            __global float *resultLine
                          )
  {
    // Get the index of the current element
    const int i = get_global_id(0);
    // Expression
    resultLine[i] = ##EXPRESSION##;
  }
  )CL" );

  QStringList inputDesc;
  for ( const auto &ref : inputRefs )
  {
    inputDesc.append( QStringLiteral( "  // %1 = %2" ).arg( ref.varName ).arg( ref.name ) );
  }
  programTemplate = programTemplate.replace( QStringLiteral( "##INPUT_DESC##" ), inputDesc.join( '\n' ) );
  programTemplate = programTemplate.replace( QStringLiteral( "##INPUT##" ), inputArgs.length() ? ( inputArgs.join( ',' ).append( ',' ) ) : QChar( ' ' ) );
  programTemplate = programTemplate.replace( QStringLiteral( "##EXPRESSION##" ), cExpression );
  programTemplate = programTemplate.replace( QStringLiteral( "##EXPRESSION_ORIGINAL##" ), calcNode->toString( ) );

  // qDebug() << programTemplate;

  // Create a program from the kernel source
  cl::Program program( QgsOpenClUtils::buildProgram( programTemplate, QgsOpenClUtils::ExceptionBehavior::Throw ) );

  // Create the buffers, output is float32 (4 bytes)
  // We assume size of float = 4 because that's the size used by OpenCL and IEEE 754
  Q_ASSERT( sizeof( float ) == 4 );
  std::size_t resultBufferSize( 4 * static_cast<size_t>( mNumOutputColumns ) );
  cl::Buffer resultLineBuffer( ctx, CL_MEM_WRITE_ONLY,
                               resultBufferSize, nullptr, nullptr );

  auto kernel = cl::Kernel( program, "rasterCalculator" );

  for ( unsigned int i = 0; i < inputBuffers.size() ; i++ )
  {
    kernel.setArg( i, inputBuffers.at( i ) );
  }
  kernel.setArg( static_cast<unsigned int>( inputBuffers.size() ), resultLineBuffer );

  QgsOpenClUtils::CPLAllocator<float> resultLine( static_cast<size_t>( mNumOutputColumns ) );

  //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 );
  if ( !outputRasterBand )
    return BandError;

  // Input block (buffer)
  std::unique_ptr<QgsRasterBlock> block;

  // Run kernel on all scanlines
  auto rowHeight = mOutputRectangle.height() / mNumOutputRows;
  for ( int line = 0; line < mNumOutputRows; line++ )
  {
    if ( feedback && feedback->isCanceled() )
    {
      break;
    }

    if ( feedback )
    {
      feedback->setProgress( 100.0 * static_cast< double >( line ) / mNumOutputRows );
    }

    // Read lines from rasters into the buffers
    for ( const auto &ref : inputRefs )
    {
      // Read one row
      QgsRectangle rect( mOutputRectangle );
      rect.setYMaximum( rect.yMaximum() - rowHeight * line );
      rect.setYMinimum( rect.yMaximum() - rowHeight );

      // TODO: check if this is too slow
      // if crs transform needed
      if ( ref.layer->crs() != mOutputCrs )
      {
        QgsRasterProjector proj;
        proj.setCrs( ref.layer->crs(), mOutputCrs );
        proj.setInput( ref.layer->dataProvider() );
        proj.setPrecision( QgsRasterProjector::Exact );
        block.reset( proj.block( ref.band, rect, mNumOutputColumns, 1 ) );
      }
      else
      {
        block.reset( ref.layer->dataProvider()->block( ref.band, rect, mNumOutputColumns, 1 ) );
      }

      //for ( int i = 0; i < mNumOutputColumns; i++ )
      //  qDebug() << "Input: " << line << i << ref.varName << " = " << block->value( 0, i );
      //qDebug() << "Writing buffer " << ref.index;

      Q_ASSERT( ref.bufferSize == static_cast<size_t>( block->data().size( ) ) );
      queue.enqueueWriteBuffer( inputBuffers[ref.index], CL_TRUE, 0,
                                ref.bufferSize, block->bits() );

    }
    // Run the kernel
    queue.enqueueNDRangeKernel(
      kernel,
      0,
      cl::NDRange( mNumOutputColumns )
    );

    // Write the result
    queue.enqueueReadBuffer( resultLineBuffer, CL_TRUE, 0,
                             resultBufferSize, resultLine.get() );

    //for ( int i = 0; i < mNumOutputColumns; i++ )
    //  qDebug() << "Output: " << line << i << " = " << resultLine[i];

    if ( GDALRasterIO( outputRasterBand, GF_Write, 0, line, mNumOutputColumns, 1, resultLine.get(), mNumOutputColumns, 1, GDT_Float32, 0, 0 ) != CE_None )
    {
      return CreateOutputError;
    }
  }

  if ( feedback && feedback->isCanceled() )
  {
    //delete the dataset without closing (because it is faster)
    gdal::fast_delete_and_close( outputDataset, outputDriver, mOutputFile );
    return Canceled;
  }

  inputBuffers.clear();

  return Success;
}
Exemplo n.º 19
0
static void DumpBand( GDALDatasetH hBaseDS, GDALRasterBandH hSrcOver,
                      const char *pszName )

{
/* -------------------------------------------------------------------- */
/*      Get base ds info.                                               */
/* -------------------------------------------------------------------- */
    double adfGeoTransform[6];
    bool bHaveGT = GDALGetGeoTransform( hBaseDS, adfGeoTransform ) == CE_None;

    int nOrigXSize = GDALGetRasterXSize( hBaseDS );
    int nOrigYSize = GDALGetRasterYSize( hBaseDS );

/* -------------------------------------------------------------------- */
/*      Create matching output file.                                    */
/* -------------------------------------------------------------------- */
    int nXSize = GDALGetRasterBandXSize( hSrcOver );
    int nYSize = GDALGetRasterBandYSize( hSrcOver );
    GDALDataType eDT = GDALGetRasterDataType( hSrcOver );
    GDALDriverH hDriver = GDALGetDriverByName( "GTiff" );

    GDALDatasetH hDstDS = GDALCreate( hDriver, pszName, nXSize, nYSize,
                                      1, eDT, NULL );

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

/* -------------------------------------------------------------------- */
/*      Apply corresponding georeferencing, scaled to size.             */
/* -------------------------------------------------------------------- */
    if( bHaveGT )
    {
        double adfOvGeoTransform[6];

        memcpy( adfOvGeoTransform, adfGeoTransform,
                sizeof(double) * 6 );

        adfOvGeoTransform[1] *= (nOrigXSize / (double) nXSize);
        adfOvGeoTransform[2] *= (nOrigXSize / (double) nXSize);
        adfOvGeoTransform[4] *= (nOrigYSize / (double) nYSize);
        adfOvGeoTransform[5] *= (nOrigYSize / (double) nYSize);

        GDALSetGeoTransform( hDstDS, adfOvGeoTransform );

        GDALSetProjection( hDstDS, GDALGetProjectionRef( hBaseDS ) );
    }

/* -------------------------------------------------------------------- */
/*      Copy over all the image data.                                   */
/* -------------------------------------------------------------------- */
    void *pData = CPLMalloc(64 * nXSize);

    for( int iLine = 0; iLine < nYSize; iLine++ )
    {
        GDALRasterIO( hSrcOver, GF_Read, 0, iLine, nXSize, 1,
                      pData, nXSize, 1, eDT, 0, 0 );
        GDALRasterIO( GDALGetRasterBand( hDstDS, 1 ), GF_Write,
                      0, iLine, nXSize, 1,
                      pData, nXSize, 1, eDT, 0, 0 );
    }
    CPLFree( pData );

    GDALClose( hDstDS );
}
Exemplo n.º 20
0
int main(int argc, char* argv[])
{
	fprintf(stderr, "TASSELED CAP TRANSFORMATION\nVersion %s.%s. Free software. GNU General Public License, version 3\n", PROG_VERSION, DATE_VERSION);
	fprintf(stderr, "Copyright (C) 2016 Igor Garkusha.\nUkraine, Dnipro\n\n");
	
	if(argc!=5)
	{
		fputs("Input parameters not found!\n", stderr);
		printHelp();

		fputs("\n", stderr);
		
		return 1;
	}
	
    GDALDatasetH  pSrcDataset = NULL;
    GDALDatasetH  pDstDataset = NULL;
    
    GDALRasterBandH pSrcBand = NULL;
    GDALRasterBandH pDstBand = NULL;
    
    GDALDriverH pDriver = NULL;

    GDALAllRegister();
	
	bool flagNoData = (atoi(argv[argc-1]) == 1)?true:false;
	int sensorIndexFlag = OLI;
	
	if( strcmp(argv[argc-2], "oli") == 0) 	sensorIndexFlag = OLI;
	else
	if( strcmp(argv[argc-2], "etm") == 0) 	sensorIndexFlag = ETM;
	else
	if( strcmp(argv[argc-2], "tm4") == 0) 	sensorIndexFlag = TM4;
	else
	if( strcmp(argv[argc-2], "tm5") == 0) 	sensorIndexFlag = TM5;
	else
	//if( strcmp(argv[argc-2], "msi10") == 0) sensorIndexFlag = S2AMSI10;
	//else
	if( strcmp(argv[argc-2], "msi") == 0) 	sensorIndexFlag = S2AMSI;
		    
    pSrcDataset = GDALOpen( argv[1], GA_ReadOnly );
    
    int bands = 0;
    
    if(pSrcDataset!=NULL)
    {
		if(CUtils::isFloat32DataType(pSrcDataset))
		{
			bands = GDALGetRasterCount(pSrcDataset);
			if( ((bands == 6)||(bands == 4)) )
			{
					pSrcBand = GDALGetRasterBand(pSrcDataset, 1);
					if(pSrcBand != NULL)
					{
							int cols  = GDALGetRasterBandXSize(pSrcBand);
							int rows  = GDALGetRasterBandYSize(pSrcBand);

							float NoDataValue = 0;

							pDriver = GDALGetDriverByName("GTiff");
							char **papszOptions = NULL;
							pDstDataset = GDALCreate(pDriver, argv[2], cols, rows, COUNT_OUT_BANDS, GDT_Float32, papszOptions);
							double adfGeoTransform[6]={0};
							GDALGetGeoTransform(pSrcDataset, adfGeoTransform );
							const char *szProjection = GDALGetProjectionRef(pSrcDataset);
							GDALSetGeoTransform(pDstDataset, adfGeoTransform );
							GDALSetProjection(pDstDataset, szProjection );
						
							pDstBand = GDALGetRasterBand(pDstDataset, 1);
						
							float *pSrcLine = NULL;
							float *pDstLine = NULL;
					
							pSrcLine = (float*)CPLMalloc(sizeof(GDALGetRasterDataType(pSrcBand))*cols);
							pDstLine = (float*)CPLMalloc(sizeof(GDALGetRasterDataType(pDstBand))*cols);
							
							
							if(flagNoData == false)
							{
								for(int resultBandNumber=1; resultBandNumber <= COUNT_OUT_BANDS; resultBandNumber++)
								{
									fprintf(stderr, "Processing for band %d...\n", resultBandNumber);
									
									pDstBand = GDALGetRasterBand(pDstDataset, resultBandNumber);

									int pr = CUtils::progress_ln_ex(stderr, 0, 0, START_PROGRESS);
									for(int i=0; i<rows; i++)
									{
										for(int j=0; j<cols; j++) pDstLine[j] = 0;
								
										for(int currentBandNumber=1; currentBandNumber <= bands; currentBandNumber++)
										{
											pSrcBand = GDALGetRasterBand(pSrcDataset, currentBandNumber);		

											GDALRasterIO(pSrcBand, GF_Read, 0, i, cols, 1, pSrcLine, cols, 1, GDALGetRasterDataType(pSrcBand), 0, 0 );
										
											for(int j=0; j<cols; j++) pDstLine[j] += getTasseledCapValue(pSrcLine[j], sensorIndexFlag, resultBandNumber, currentBandNumber);
										}
										
										if(sensorIndexFlag == TM5) for(int j=0; j<cols; j++) pDstLine[j] += TM5_TCCoeff[resultBandNumber][6];
										
										GDALRasterIO(pDstBand, GF_Write, 0, i, cols, 1, pDstLine, cols, 1, GDT_Float32, 0, 0 );
										
										pr = CUtils::progress_ln_ex(stderr, i, rows, pr);
									}
									CUtils::progress_ln_ex(stderr, 0, 0, END_PROGRESS);
								}
							}
							else // WITH NODATA VALUE - pixel(1,1)
							{
								for(int resultBandNumber=1; resultBandNumber <= COUNT_OUT_BANDS; resultBandNumber++)
								{
									fprintf(stderr, "Processing for band %d...\n", resultBandNumber);
									
									pDstBand = GDALGetRasterBand(pDstDataset, resultBandNumber);
									
									int pr = CUtils::progress_ln_ex(stderr, 0, 0, START_PROGRESS);
									for(int i=0; i<rows; i++)
									{
										for(int j=0; j<cols; j++) pDstLine[j] = 0;
								
										for(int currentBandNumber=1; currentBandNumber <= bands; currentBandNumber++)
										{
											pSrcBand = GDALGetRasterBand(pSrcDataset, currentBandNumber);		
											NoDataValue = CUtils::getFloatNoDataValueAsBackground(pSrcBand);
											
											GDALRasterIO(pSrcBand, GF_Read, 0, i, cols, 1, pSrcLine, cols, 1, GDALGetRasterDataType(pSrcBand), 0, 0 );
										
											for(int j=0; j<cols; j++) 
											{
												if(NoDataValue == pSrcLine[j]) pDstLine[j] = NoDataValue;
												else pDstLine[j] += getTasseledCapValue(pSrcLine[j], sensorIndexFlag, resultBandNumber, currentBandNumber);
											}
										}
										
										if(sensorIndexFlag == TM5)
										{
											for(int j=0; j<cols; j++) if(NoDataValue != pDstLine[j]) pDstLine[j] += TM5_TCCoeff[resultBandNumber][6];
										}
										
										GDALRasterIO(pDstBand, GF_Write, 0, i, cols, 1, pDstLine, cols, 1, GDT_Float32, 0, 0 );
										
										pr = CUtils::progress_ln_ex(stderr, i, rows, pr);
									}
									CUtils::progress_ln_ex(stderr, 0, 0, END_PROGRESS);
								}
							}
							
							CPLFree(pSrcLine); pSrcLine = NULL;
							CPLFree(pDstLine); pDstLine = NULL;
							
							if(flagNoData) CUtils::calculateFloatGeoTIFFStatistics(pDstDataset, -1, true);
							else CUtils::calculateFloatGeoTIFFStatistics(pDstDataset, -1, false);
							
							fputs("Output band:\n\tband1: Brightness, band2: Greenness (Vegetation), band3: Wetness, band4: Haze\n\n", stderr);
							fputs("\nEnd Processing.\n\n", stderr);
					}
			}
			else
			{
				fputs("\nERROR: Source Band Number is Invalid!!!\n", stderr);
				fprintf(stderr, "Source Bands Number: %d!\n\n", bands);
				printHelp();
			}
		}
		
		if(pSrcDataset!=NULL) { GDALClose(pSrcDataset); }
		if(pDstDataset!=NULL) { GDALClose(pDstDataset); }
	}

    return 0;
}
Exemplo n.º 21
0
int main(int argc, char *argv[])
{
    const char *pszInputfile = NULL;
    const char *pszOutputfile = NULL;
    const char *pszFormat = "GTiff";
    int bProgress = FALSE;
    int bMaskNoData = FALSE;
    GDALDatasetH hSrcDS;
    GDALDatasetH hMaskDS;
    GDALDriverH hDriver;
    double adfGeoTransform[6];
    const char *pszWkt;
    int nXSize, nYSize;
    int nMaskCount = 0;
    int nPixelsMasked = 0;
    double adfMaskValues[1024];
    int anMaskFound[1024];
    int bMaskProvided = FALSE;
    double dfNoData;
    int i, j, k;
    GDALRasterBandH hSrcBand, hMaskBand;
    double *padfScanline;
    unsigned char *pabyScanline;
    int nHasNoData;
    char** papszCreationOptions = NULL;

    i = 1;
    while( i < argc )
    {
        if( EQUAL( argv[i], "-p" ) )
        {
            bProgress = TRUE;
        }
        else if( EQUAL( argv[i], "-mask_nodata" ) )
        {
            bMaskNoData = TRUE;
            bMaskProvided = TRUE;
        }
        else if( EQUAL( argv[i], "-of" ) )
        {
            pszFormat = argv[++i];
        }
        else if( EQUAL( argv[i], "-co" ) )
        {
            papszCreationOptions = CSLAddString(papszCreationOptions,
                                                argv[++i]);
        }
        else if( EQUAL( argv[i], "-h" ) )
        {
            Usage();
        }
        else if( pszInputfile == NULL )
        {
            pszInputfile = argv[i];
        }
        else if( pszOutputfile == NULL )
        {
            pszOutputfile = argv[i];
        }
        else
        {
            adfMaskValues[nMaskCount++] = atof(argv[i]);
            bMaskProvided = TRUE;
        }
        //else
        //{
        //    Usage();
        //}
        i++;
    }

    if( pszInputfile == NULL )
    {
        fprintf( stderr, "No input file provided\n");
        Usage();
    }
    if( pszOutputfile == NULL )
    {
        fprintf( stderr, "No output file provided\n" );
        Usage();
    }
    GDALAllRegister();

    hSrcDS = GDALOpen(pszInputfile, GA_ReadOnly);
    if(hSrcDS == NULL)
    {
        CPLError(CE_Fatal, CPLE_OpenFailed, "Failed to open source dataset");
    }

    hDriver = GDALGetDriverByName(pszFormat);
    if(hDriver == NULL)
    {
        CPLError(CE_Fatal, CPLE_NotSupported, "Failed to load output driver");
    }

    nXSize = GDALGetRasterXSize(hSrcDS);
    nYSize = GDALGetRasterYSize(hSrcDS);
    hMaskDS = GDALCreate(hDriver, pszOutputfile, nXSize, nYSize, 1, GDT_Byte,
                         papszCreationOptions);
    pszWkt = GDALGetProjectionRef(hSrcDS);
    if(pszWkt != NULL)
    {
        GDALSetProjection(hMaskDS, pszWkt);
    }
    if(GDALGetGeoTransform(hSrcDS, adfGeoTransform) == CE_None)
    {
        GDALSetGeoTransform(hMaskDS, adfGeoTransform);
    }
    hSrcBand = GDALGetRasterBand(hSrcDS, 1);
    hMaskBand = GDALGetRasterBand(hMaskDS, 1);

    nHasNoData = FALSE;
    if(bMaskNoData)
    {
        dfNoData = GDALGetRasterNoDataValue(hSrcBand, &nHasNoData);
        if(nHasNoData)
        {
            adfMaskValues[nMaskCount++] = dfNoData;
        }
    }
    for(i = 0;i < nMaskCount;i++)
    {
        anMaskFound[i] = 0;
    }

    padfScanline = (double*)CPLMalloc(nXSize * sizeof(double));
    pabyScanline = (unsigned char*)CPLMalloc(nXSize * sizeof(unsigned char));

    if(bProgress)
    {
        GDALTermProgress(0.0, NULL, NULL);
    }

    for(i = 0;i < nYSize;i++)
    {
        GDALRasterIO(hSrcBand, GF_Read, 0, i, nXSize, 1, padfScanline, nXSize,
                     1, GDT_Float64, 0, 0);
        for(j = 0; j < nXSize;j++)
        {
            pabyScanline[j] = 255;
            for(k = 0; k < nMaskCount; k++)
            {
                if(CPLIsEqual(padfScanline[j], adfMaskValues[k]))
                {
                    pabyScanline[j] = 0;
                    anMaskFound[k]++;
                    nPixelsMasked++;
                    break;
                }
            }
        }
        GDALRasterIO(hMaskBand, GF_Write, 0, i, nXSize, 1, pabyScanline, 
                     nXSize, 1, GDT_Byte, 0, 0);
        if(bProgress)
        {
            GDALTermProgress((double)i / (double)nYSize, NULL, NULL);
        }
    }
    if(bProgress)
    {
        GDALTermProgress(1.0, NULL, NULL);
    }

    for(i = 0; i < nMaskCount;i++)
    {
        CPLDebug("addmask", "%d pixels were masked for value: %lf",
                 anMaskFound[i], adfMaskValues[i]);
    }
    CPLDebug("addmask", "%d pixels were masked total", nPixelsMasked);

    CPLFree(padfScanline);
    CPLFree(pabyScanline);

    GDALClose(hSrcDS);
    GDALClose(hMaskDS);
}
Exemplo n.º 22
0
int main( int argc, char ** argv )

{
    /* Check that we are running against at least GDAL 1.4 (probably older in fact !) */
    /* Note to developers : if we use newer API, please change the requirement */
    if (atoi(GDALVersionInfo("VERSION_NUM")) < 1400)
    {
        fprintf(stderr, "At least, GDAL >= 1.4.0 is required for this version of %s, "
                "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME);
        exit(1);
    }

/* -------------------------------------------------------------------- */
/*      Generic arg processing.                                         */
/* -------------------------------------------------------------------- */
    GDALAllRegister();
    GDALSetCacheMax( 100000000 );
    argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
    if( argc < 1 )
        exit( -argc );
    
/* -------------------------------------------------------------------- */
/*      Parse arguments.                                                */
/* -------------------------------------------------------------------- */
    int i;
    const char *pszOutFile = NULL;
    const char *pszInFile = NULL;
    int nMaxNonBlack = 2;
    int nNearDist = 15;
    int bNearWhite = FALSE;
    
    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], "-o") && i < argc-1 )
            pszOutFile = argv[++i];
        else if( EQUAL(argv[i], "-white") )
            bNearWhite = TRUE;
        else if( EQUAL(argv[i], "-nb") && i < argc-1 )
            nMaxNonBlack = atoi(argv[++i]);
        else if( EQUAL(argv[i], "-near") && i < argc-1 )
            nNearDist = atoi(argv[++i]);
        else if( argv[i][0] == '-' )
            Usage();
        else if( pszInFile == NULL )
            pszInFile = argv[i];
        else
            Usage();
    }

    if( pszInFile == NULL )
        Usage();

    if( pszOutFile == NULL )
        pszOutFile = pszInFile;

/* -------------------------------------------------------------------- */
/*      Open input file.                                                */
/* -------------------------------------------------------------------- */
    GDALDatasetH hInDS, hOutDS = NULL;
    int nXSize, nYSize, nBands;

    if( pszOutFile == pszInFile )
        hInDS = hOutDS = GDALOpen( pszInFile, GA_Update );
    else
        hInDS = GDALOpen( pszInFile, GA_ReadOnly );

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

    nXSize = GDALGetRasterXSize( hInDS );
    nYSize = GDALGetRasterYSize( hInDS );
    nBands = GDALGetRasterCount( hInDS );

/* -------------------------------------------------------------------- */
/*      Do we need to create output file?                               */
/* -------------------------------------------------------------------- */
    if( hOutDS == NULL )
    {
        GDALDriverH hDriver = GDALGetDriverByName( "HFA" );
        
        hOutDS = GDALCreate( hDriver, pszOutFile, 
                             nXSize, nYSize, nBands, GDT_Byte, 
                             NULL );
        if( hOutDS == NULL )
            exit( 1 );

        double adfGeoTransform[6];

        if( GDALGetGeoTransform( hInDS, adfGeoTransform ) == CE_None )
        {
            GDALSetGeoTransform( hOutDS, adfGeoTransform );
            GDALSetProjection( hOutDS, GDALGetProjectionRef( hInDS ) );
        }
    }

    int iBand;
    for( iBand = 0; iBand < nBands; iBand++ )
    {
        GDALRasterBandH hBand = GDALGetRasterBand(hInDS, iBand+1);
        if (GDALGetRasterDataType(hBand) != GDT_Byte)
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Band %d is not of type GDT_Byte. It can lead to unexpected results.", iBand+1);
        }
        if (GDALGetRasterColorTable(hBand) != NULL)
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Band %d has a color table, which is ignored by nearblack. "
                     "It can lead to unexpected results.", iBand+1);
        }
    }

/* -------------------------------------------------------------------- */
/*      Allocate a line buffer.                                         */
/* -------------------------------------------------------------------- */
    GByte *pabyLine;
    int   *panLastLineCounts;

    pabyLine = (GByte *) CPLMalloc(nXSize * nBands);

    panLastLineCounts = (int *) CPLCalloc(sizeof(int),nXSize);

/* -------------------------------------------------------------------- */
/*      Processing data one line at a time.                             */
/* -------------------------------------------------------------------- */
    int iLine;

    for( iLine = 0; iLine < nYSize; iLine++ )
    {
        CPLErr eErr;

        eErr = GDALDatasetRasterIO( hInDS, GF_Read, 0, iLine, nXSize, 1, 
                                    pabyLine, nXSize, 1, GDT_Byte, 
                                    nBands, NULL, nBands, nXSize * nBands, 1 );
        if( eErr != CE_None )
            break;
        
        ProcessLine( pabyLine, 0, nXSize-1, nBands, nNearDist, nMaxNonBlack,
                     bNearWhite, panLastLineCounts, TRUE, TRUE );
        ProcessLine( pabyLine, nXSize-1, 0, nBands, nNearDist, nMaxNonBlack,
                     bNearWhite, NULL, TRUE, FALSE );
        
        eErr = GDALDatasetRasterIO( hOutDS, GF_Write, 0, iLine, nXSize, 1, 
                                    pabyLine, nXSize, 1, GDT_Byte, 
                                    nBands, NULL, nBands, nXSize * nBands, 1 );
        if( eErr != CE_None )
            break;
        
        GDALTermProgress( 0.5 * ((iLine+1) / (double) nYSize), NULL, NULL );
    }

/* -------------------------------------------------------------------- */
/*      Now process from the bottom back up, doing only the vertical pass.*/
/* -------------------------------------------------------------------- */
    memset( panLastLineCounts, 0, sizeof(int) * nXSize);
    
    for( iLine = nYSize-1; iLine >= 0; iLine-- )
    {
        CPLErr eErr;

        eErr = GDALDatasetRasterIO( hOutDS, GF_Read, 0, iLine, nXSize, 1, 
                                    pabyLine, nXSize, 1, GDT_Byte, 
                                    nBands, NULL, nBands, nXSize * nBands, 1 );
        if( eErr != CE_None )
            break;
        
        ProcessLine( pabyLine, 0, nXSize-1, nBands, nNearDist, nMaxNonBlack,
                     bNearWhite, panLastLineCounts, FALSE, TRUE );
        
        eErr = GDALDatasetRasterIO( hOutDS, GF_Write, 0, iLine, nXSize, 1, 
                                    pabyLine, nXSize, 1, GDT_Byte, 
                                    nBands, NULL, nBands, nXSize * nBands, 1 );
        if( eErr != CE_None )
            break;
        
        GDALTermProgress( 0.5 + 0.5 * (nYSize-iLine) / (double) nYSize, 
                          NULL, NULL );
    }

    CPLFree(pabyLine);
    CPLFree( panLastLineCounts );

    GDALClose( hOutDS );
    if( hInDS != hOutDS )
        GDALClose( hInDS );
    GDALDumpOpenDatasets( stderr );
    GDALDestroyDriverManager();
    
    return 0;
}
Exemplo n.º 23
0
static void msTransformToGeospatialPDF(imageObj *img, mapObj *map, cairo_renderer *r)
{
  /* We need a GDAL 1.10 PDF driver at runtime, but as far as the C API is concerned, GDAL 1.9 is */
  /* largely sufficient. */
#if defined(USE_GDAL) && defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1900
  GDALDatasetH hDS = NULL;
  const char* pszGEO_ENCODING = NULL;
  GDALDriverH hPDFDriver = NULL;
  const char* pszVirtualIO = NULL;
  int bVirtualIO = FALSE;
  char* pszTmpFilename = NULL;
  VSILFILE* fp = NULL;

  if (map == NULL)
    return;

  pszGEO_ENCODING = msGetOutputFormatOption(img->format, "GEO_ENCODING", NULL);
  if (pszGEO_ENCODING == NULL)
    return;

  msGDALInitialize();

  hPDFDriver = GDALGetDriverByName("PDF");
  if (hPDFDriver == NULL)
    return;

  /* When compiled against libpoppler, the PDF driver is VirtualIO capable */
  /* but not, when it is compiled against libpodofo. */
  pszVirtualIO = GDALGetMetadataItem( hPDFDriver, GDAL_DCAP_VIRTUALIO, NULL );
  if (pszVirtualIO)
    bVirtualIO = CSLTestBoolean(pszVirtualIO);

  if (bVirtualIO)
    pszTmpFilename = msTmpFile(map, NULL, "/vsimem/mscairopdf/", "pdf");
  else
    pszTmpFilename = msTmpFile(map, map->mappath, NULL, "pdf");

  /* Copy content of outputStream buffer into file */
  fp = VSIFOpenL(pszTmpFilename, "wb");
  if (fp == NULL) {
    msFree(pszTmpFilename);
    return;
  }
  VSIFWriteL(r->outputStream->data, 1, r->outputStream->size, fp);
  VSIFCloseL(fp);
  fp = NULL;

  hDS = GDALOpen(pszTmpFilename, GA_Update);
  if ( hDS != NULL ) {
    char* pszWKT = msProjectionObj2OGCWKT( &(map->projection) );
    if( pszWKT != NULL ) {
      double adfGeoTransform[6];
      int i;

      /* Add user-specified options */
      for( i = 0; i < img->format->numformatoptions; i++ ) {
        const char* pszOption = img->format->formatoptions[i];
        if( strncasecmp(pszOption,"METADATA_ITEM:",14) == 0 ) {
          char* pszKey = NULL;
          const char* pszValue = CPLParseNameValue(pszOption + 14,
                                 &pszKey);
          if( pszKey != NULL ) {
            GDALSetMetadataItem(hDS, pszKey, pszValue, NULL);
            CPLFree(pszKey);
          }
        }
      }

      /* We need to rescale the geotransform because GDAL will not necessary */
      /* open the PDF with the DPI that was used to generate it */
      memcpy(adfGeoTransform, map->gt.geotransform, 6 * sizeof(double));
      adfGeoTransform[1] = adfGeoTransform[1] * map->width / GDALGetRasterXSize(hDS);
      adfGeoTransform[5] = adfGeoTransform[5] * map->height / GDALGetRasterYSize(hDS);
      GDALSetGeoTransform(hDS, adfGeoTransform);
      GDALSetProjection(hDS, pszWKT);

      msFree( pszWKT );
      pszWKT = NULL;

      CPLSetThreadLocalConfigOption("GDAL_PDF_GEO_ENCODING", pszGEO_ENCODING);

      GDALClose(hDS);
      hDS = NULL;

      CPLSetThreadLocalConfigOption("GDAL_PDF_GEO_ENCODING", NULL);

      /* We need to replace the buffer with the content of the GDAL file */
      fp = VSIFOpenL(pszTmpFilename, "rb");
      if( fp != NULL ) {
        int nFileSize;

        VSIFSeekL(fp, 0, SEEK_END);
        nFileSize = (int)VSIFTellL(fp);

        msBufferResize(r->outputStream, nFileSize);

        VSIFSeekL(fp, 0, SEEK_SET);
        r->outputStream->size = VSIFReadL(r->outputStream->data, 1, nFileSize, fp);

        VSIFCloseL(fp);
        fp = NULL;
      }
    }
  }

  if ( hDS != NULL )
    GDALClose(hDS);

  VSIUnlink(pszTmpFilename);

  msFree(pszTmpFilename);
#endif
}
Exemplo n.º 24
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;
}
Exemplo n.º 25
0
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;
}
Exemplo n.º 26
0
int QgsRasterCalculator::processCalculation( QProgressDialog* p )
{
  //prepare search string / tree
  QString errorString;
  QgsRasterCalcNode* calcNode = QgsRasterCalcNode::parseRasterCalcString( mFormulaString, errorString );
  if ( !calcNode )
  {
    //error
    return static_cast<int>( ParserError );
  }

  QMap< QString, QgsRasterBlock* > inputBlocks;
  QVector<QgsRasterCalculatorEntry>::const_iterator it = mRasterEntries.constBegin();
  for ( ; it != mRasterEntries.constEnd(); ++it )
  {
    if ( !it->raster ) // no raster layer in entry
    {
      delete calcNode;
      qDeleteAll( inputBlocks );
      return static_cast< int >( InputLayerError );
    }

    QgsRasterBlock* block = nullptr;
    // if crs transform needed
    if ( it->raster->crs() != mOutputCrs )
    {
      QgsRasterProjector proj;
      proj.setCRS( it->raster->crs(), mOutputCrs );
      proj.setInput( it->raster->dataProvider() );
      proj.setPrecision( QgsRasterProjector::Exact );

      block = proj.block( it->bandNumber, mOutputRectangle, mNumOutputColumns, mNumOutputRows );
    }
    else
    {
      block = it->raster->dataProvider()->block( it->bandNumber, mOutputRectangle, mNumOutputColumns, mNumOutputRows );
    }
    if ( block->isEmpty() )
    {
      delete block;
      delete calcNode;
      qDeleteAll( inputBlocks );
      return static_cast<int>( MemoryError );
    }
    inputBlocks.insert( it->ref, block );
  }

  //open output dataset for writing
  GDALDriverH outputDriver = openOutputDriver();
  if ( !outputDriver )
  {
    return static_cast< int >( CreateOutputError );
  }

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

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

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

  QgsRasterMatrix resultMatrix;
  resultMatrix.setNodataValue( outputNodataValue );

  //read / write line by line
  for ( int i = 0; i < mNumOutputRows; ++i )
  {
    if ( p )
    {
      p->setValue( i );
    }

    if ( p && p->wasCanceled() )
    {
      break;
    }

    if ( calcNode->calculate( inputBlocks, resultMatrix, i ) )
    {
      bool resultIsNumber = resultMatrix.isNumber();
      float* calcData = new float[mNumOutputColumns];

      for ( int j = 0; j < mNumOutputColumns; ++j )
      {
        calcData[j] = ( float )( resultIsNumber ? resultMatrix.number() : resultMatrix.data()[j] );
      }

      //write scanline to the dataset
      if ( GDALRasterIO( outputRasterBand, GF_Write, 0, i, mNumOutputColumns, 1, calcData, mNumOutputColumns, 1, GDT_Float32, 0, 0 ) != CE_None )
      {
        qWarning( "RasterIO error!" );
      }

      delete[] calcData;
    }

  }

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

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

  if ( p && p->wasCanceled() )
  {
    //delete the dataset without closing (because it is faster)
    GDALDeleteDataset( outputDriver, TO8F( mOutputFile ) );
    return static_cast< int >( Cancelled );
  }
  GDALClose( outputDataset );

  return static_cast< int >( Success );
}
Exemplo n.º 27
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;
}
Exemplo n.º 28
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;
}
Exemplo n.º 29
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;
}
Exemplo n.º 30
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() );
  }

}