Example #1
0
int GDAL_EDBFile::ReadBlock( int channel,
                             int block_index, void *buffer,
                             int win_xoff, int win_yoff,
                             int win_xsize, int win_ysize )

{
    GDALRasterBand *poBand = poDS->GetRasterBand(channel);
    int nBlockXSize, nBlockYSize;
    int nBlockX, nBlockY;
    int nWidthInBlocks;
    int nPixelOffset;
    int nLineOffset;

    if( GetType(channel) == CHN_UNKNOWN )
    {
        ThrowPCIDSKException("%s channel type not supported for PCIDSK access.",
                             GDALGetDataTypeName(poBand->GetRasterDataType()) );
    }

    poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );

    nWidthInBlocks = (poBand->GetXSize() + nBlockXSize - 1) / nBlockXSize;
    
    nBlockX = block_index % nWidthInBlocks;
    nBlockY = block_index / nWidthInBlocks;

    nPixelOffset = GDALGetDataTypeSize(poBand->GetRasterDataType()) / 8;
    nLineOffset = win_xsize * nPixelOffset;

/* -------------------------------------------------------------------- */
/*      Are we reading a partial block at the edge of the database?     */
/*      If so, ensure we don't read off the database.                   */
/* -------------------------------------------------------------------- */
    if( nBlockX * nBlockXSize + win_xoff + win_xsize > poBand->GetXSize() )
        win_xsize = poBand->GetXSize() - nBlockX * nBlockXSize - win_xoff;

    if( nBlockY * nBlockYSize + win_yoff + win_ysize > poBand->GetYSize() )
        win_ysize = poBand->GetYSize() - nBlockY * nBlockYSize - win_yoff;

    CPLErr eErr = poBand->RasterIO( GF_Read, 
                                    nBlockX * nBlockXSize + win_xoff, 
                                    nBlockY * nBlockYSize + win_yoff,
                                    win_xsize, win_ysize, 
                                    buffer, win_xsize, win_ysize, 
                                    poBand->GetRasterDataType(),
                                    nPixelOffset, nLineOffset, NULL );

    if( eErr != CE_None )
    {
        ThrowPCIDSKException( "%s", CPLGetLastErrorMsg() );
    }

    return 1;
}
Example #2
0
int GDAL_EDBFile::WriteBlock( int channel, int block_index, void *buffer)

{
    GDALRasterBand *poBand = poDS->GetRasterBand(channel);
    int nBlockXSize, nBlockYSize;
    int nBlockX, nBlockY;
    int nWinXSize, nWinYSize;
    int nWidthInBlocks;

    if( GetType(channel) == CHN_UNKNOWN )
    {
        ThrowPCIDSKException("%s channel type not supported for PCIDSK access.",
                             GDALGetDataTypeName(poBand->GetRasterDataType()) );
    }

    poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );

    nWidthInBlocks = (poBand->GetXSize() + nBlockXSize - 1) / nBlockXSize;
    
    nBlockX = block_index % nWidthInBlocks;
    nBlockY = block_index / nWidthInBlocks;

/* -------------------------------------------------------------------- */
/*      Are we reading a partial block at the edge of the database?     */
/*      If so, ensure we don't read off the database.                   */
/* -------------------------------------------------------------------- */
    if( nBlockX * nBlockXSize + nBlockXSize > poBand->GetXSize() )
        nWinXSize = poBand->GetXSize() - nBlockX * nBlockXSize;
    else
        nWinXSize = nBlockXSize;

    if( nBlockY * nBlockYSize + nBlockYSize > poBand->GetYSize() )
        nWinYSize = poBand->GetYSize() - nBlockY * nBlockYSize;
    else
        nWinYSize = nBlockYSize;

    CPLErr eErr = poBand->RasterIO( GF_Write, 
                                    nBlockX * nBlockXSize, 
                                    nBlockY * nBlockYSize,
                                    nWinXSize, nWinYSize,
                                    buffer, nWinXSize, nWinYSize,
                                    poBand->GetRasterDataType(), 0, 0, NULL );

    if( eErr != CE_None )
    {
        ThrowPCIDSKException( "%s", CPLGetLastErrorMsg() );
    }

    return 1;
}
Raster* import_raster(string raster_filename, int band_number) {
    GDALAllRegister();
    GDALDataset*  poDataset = (GDALDataset *) GDALOpen( raster_filename.c_str(), GA_ReadOnly );
    if( poDataset == NULL ) { 
        cerr << "Error: Could not open raster data file" << endl;
        exit(1); 
    }

    fprintf(stderr, "Driver: %s/%s\n", poDataset->GetDriver()->GetDescription(), poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) );
    fprintf(stderr, "Size is %dx%dx%d\n", poDataset->GetRasterXSize(), poDataset->GetRasterYSize(), poDataset->GetRasterCount() );

    if( poDataset->GetProjectionRef()  != NULL ) cerr << "Projection is `" << poDataset->GetProjectionRef() << "'" << endl;;

    
    GDALRasterBand* poBand = poDataset->GetRasterBand( band_number );
    int nBlockXSize, nBlockYSize;
    poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
    fprintf(stderr, "Block=%dx%d Type=%s, ColorInterp=%s\n",
            nBlockXSize, nBlockYSize,
            GDALGetDataTypeName(poBand->GetRasterDataType()),
            GDALGetColorInterpretationName( poBand->GetColorInterpretation()) );

    Raster* raster = extract_raster_attributes( poDataset );
    raster->band = poBand;
    return raster;
}
Example #4
0
void DemReader::MetaDataInfo(GDALDataset* gdalDataset, MapControllerPtr mapController)
{
	FileMetaData* header = mapController->GetMapModel()->GetMetaData();

	header->driverDesc = gdalDataset->GetDriver()->GetDescription();
	header->driverMetaData = gdalDataset->GetDriver()->GetMetadataItem(GDAL_DMD_LONGNAME);
	Log::Inst().Write("Driver: " + header->driverDesc + " \\ " + header->driverMetaData);

	header->xSize = gdalDataset->GetRasterXSize();
	header->ySize = gdalDataset->GetRasterYSize();
	header->bands = gdalDataset->GetRasterCount();
	Log::Inst().Write("Size (x,y): " + 
		StringTools::ToString(header->xSize) + ", " +
		StringTools::ToString(header->ySize));
	Log::Inst().Write("Bands: " + StringTools::ToString(header->bands));

	header->projection = std::string(gdalDataset->GetProjectionRef());
	Log::Inst().Write("Projection: " + header->projection);

	double adfGeoTransform[6];
	gdalDataset->GetGeoTransform( adfGeoTransform );

	header->originX = adfGeoTransform[0];
	header->originY = adfGeoTransform[3];
	Log::Inst().Write("Origin: " +
		StringTools::ToString(adfGeoTransform[0]) + ", " +
		StringTools::ToString(adfGeoTransform[3]));

	header->pixelSizeX = adfGeoTransform[1];
	header->pixelSizeY = adfGeoTransform[5];
	Log::Inst().Write("Pixel Size: " +
		StringTools::ToString(adfGeoTransform[1]) + ", " +
		StringTools::ToString(adfGeoTransform[5]));

	GDALRasterBand* gdalBand = gdalDataset->GetRasterBand(1);
	int nBlockXSize, nBlockYSize;
	gdalBand->GetBlockSize(&nBlockXSize, &nBlockYSize);

	header->dataType = std::string(GDALGetDataTypeName(gdalBand->GetRasterDataType()));
	Log::Inst().Write("Block, Type: " + StringTools::ToString(nBlockXSize) + ", " +
		StringTools::ToString(nBlockYSize) + ", " +
		std::string(header->dataType));

	header->colourInterpretation = std::string(GDALGetColorInterpretationName(gdalBand->GetColorInterpretation()));	
	Log::Inst().Write("Color Interpretation: " + header->colourInterpretation);

	header->extents.x = adfGeoTransform[0];
	header->extents.y = adfGeoTransform[3] + gdalBand->GetYSize()*adfGeoTransform[5];
	Log::Inst().Write("Lower, Left (x,y): " +
		StringTools::ToString(header->extents.x) + ", " +
		StringTools::ToString(header->extents.y));

	header->extents.dx = adfGeoTransform[0]+gdalBand->GetXSize()*adfGeoTransform[1];
	header->extents.dy = adfGeoTransform[3];
	Log::Inst().Write("Upper, Right (x,y): " +
		StringTools::ToString(header->extents.dx) + ", " +
		StringTools::ToString(header->extents.dy));

	Log::Inst().Write("");
}
Example #5
0
bool getRawValuesFromFile(string fname,vector<vector<float>>& vecs)
{
   
   //vector<float> temp = vector<float>()
   GDALDataset *poDataset;
   GDALAllRegister();
   poDataset= (GDALDataset*) GDALOpen(fname.c_str(),GA_ReadOnly);
   if(poDataset == NULL)
   {
      cout << "OUCH!" << endl;
      return false;
   }
   cout << "Data size: " << GDALGetRasterXSize(poDataset) << " " << GDALGetRasterYSize(poDataset) << endl;

   GDALRasterBand  *poBand;
   int             nBlockXSize, nBlockYSize;
   int             bGotMin, bGotMax;
   double          adfMinMax[2];
        
   poBand = poDataset->GetRasterBand( 1 );
   poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
   printf( "Block=%dx%d Type=%s, ColorInterp=%s\n",
            nBlockXSize, nBlockYSize,
            GDALGetDataTypeName(poBand->GetRasterDataType()),
            GDALGetColorInterpretationName(
            poBand->GetColorInterpretation()) );

   adfMinMax[0] = poBand->GetMinimum( &bGotMin );
   adfMinMax[1] = poBand->GetMaximum( &bGotMax );
   if( ! (bGotMin && bGotMax) )
      GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax);
   int width = poBand->GetXSize(); 
   int height = poBand->GetYSize();
   int bands = poDataset->GetRasterCount();
   float *pafScanline;
   std::cout << "Before allocation" << adfMinMax[0] << " " << adfMinMax[1] << endl;
   int dsize = 256;
   pafScanline = (float *) CPLMalloc(sizeof(float)*width*height);
   vector<vector<float>> out = vector<vector<float>>(height,vector<float> (width,0));
   poBand->RasterIO(GF_Read,0,0,width,height,pafScanline,width,height,GDT_Float32,0,0);
   cout << "After allocation" << endl;
   for(int i = 0; i < height; i++)
   {
    for(int j = 0; j < width; j++)
    {
      //cout << i << j << endl << pafS;
      out[i][j] = pafScanline[i*width+j];
    }
   }
   CPLFree(pafScanline);
   //for(auto i : out)
   //for(auto j : i)
   //		cout << j << endl;
  cout << "After allocation" << endl;
  vecs = out;
   return true;
}
Example #6
0
int main()
{
    GDALDataset  *poDataset;
    GDALAllRegister();
    poDataset = (GDALDataset *) GDALOpen( "GE01.tif", GA_ReadOnly );
    printf("Working! \n");

    if( poDataset != NULL ){
    	//Get Dataset Information
        double adfGeoTransform[6];

		printf( "Driver: %s/%s\n", poDataset->GetDriver()->GetDescription(), poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) );

		printf( "Size is %dx%dx%d\n", poDataset->GetRasterXSize(), poDataset->GetRasterYSize(), poDataset->GetRasterCount() );

		if( poDataset->GetProjectionRef()  != NULL )
    		printf( "Projection is `%s'\n", poDataset->GetProjectionRef() );

		if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None ){
    		printf( "Origin = (%.6f,%.6f)\n",
            adfGeoTransform[0], adfGeoTransform[3] );
    		printf( "Pixel Size = (%.6f,%.6f)\n",
            adfGeoTransform[1], adfGeoTransform[5] );
		}

		//Fetch Raster Band
		GDALRasterBand  *poBand;
		int             nBlockXSize, nBlockYSize;
		int             bGotMin, bGotMax;
		double          adfMinMax[2];
		poBand = poDataset->GetRasterBand( 1 );
		poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
		printf( "Block=%dx%d Type=%s, ColorInterp=%s\n",
		        nBlockXSize, nBlockYSize,
		        GDALGetDataTypeName(poBand->GetRasterDataType()),
		        GDALGetColorInterpretationName(
		            poBand->GetColorInterpretation()) );
		adfMinMax[0] = poBand->GetMinimum( &bGotMin );
		adfMinMax[1] = poBand->GetMaximum( &bGotMax );
		if( ! (bGotMin && bGotMax) )
		    GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax);
		printf( "Min=%.3fd, Max=%.3f\n", adfMinMax[0], adfMinMax[1] );
		if( poBand->GetOverviewCount() > 0 )
		    printf( "Band has %d overviews.\n", poBand->GetOverviewCount() );
		if( poBand->GetColorTable() != NULL )
		    printf( "Band has a color table with %d entries.\n", 
		             poBand->GetColorTable()->GetColorEntryCount() );

		//Close Dataset
		GDALClose(poDataset);
		//Exit      
		return 0;
	}


}
Example #7
0
void bin2ascii(char *binFile, char *asciiFile){
    GDALDataset *layer;
    GDALAllRegister();
    layer = (GDALDataset *)GDALOpen(binFile, GA_ReadOnly);
    
    int bandNumber = 1;
    GDALRasterBand *band = layer->GetRasterBand(bandNumber);
    GDALDataType type    = band->GetRasterDataType();

    double ranges[6];
    layer->GetGeoTransform(ranges);

    ofstream outFile;
    outFile.open(asciiFile);
     
    outFile<<"ncols "<<layer->GetRasterXSize()<<"\n";
    outFile<<"nrows "<<layer->GetRasterYSize()<<"\n";
    outFile<<"xllcorner "<<ranges[0]<<"\n";
    outFile<<"yllcorner "<<(ranges[3] + layer->GetRasterXSize() * ranges[4] + layer->GetRasterYSize() * ranges[5])<<"\n";
    outFile<<"cellsize " <<ranges[1]<<"\n";
    outFile<<"nodata_value "<<"-9999"<<"\n";
    //getchar(); getchar();

    int cols = layer->GetRasterXSize();
    int rows = layer->GetRasterYSize();
    double NODATA_VAL = band->GetNoDataValue();

    cout<<"NODATA_VALUE= "<<NODATA_VAL<<"\n";

    int size = GDALGetDataTypeSize(type) / 8;
    void *data = CPLMalloc(size);
    //CPLErr err = band->RasterIO(GF_Read, 0, 0, cols, rows, data, cols, rows, type, 0, 0);
	//getchar(); getchar();
    //for(int j=0; j<rows*cols; j++){
	//int col, row;
    for(int row=0; row<rows; row++){
	for(int col=0; col<cols; col++){	
	 
	CPLErr err = band->RasterIO(GF_Read, col, row, 1, 1, data, 1, 1, type, 0, 0);
	double tempVal = readValueB2A(data, type, 0);
	outFile<<( tempVal != NODATA_VAL ? tempVal : -9999)<<" "; 
	
    	    //if((j+1)%cols == 0){
	//	cout<<"\n";
		//getchar(); getchar();
	//	}
	}
	outFile<<"\n"; 
	//getchar();
    }
	cout<<"Bin2Ascii.. Done!\n";
	outFile.close();
	//getchar(); getchar();
}
GDALDataType peekGDALType(const std::string &filename) {
  GDALAllRegister();
  GDALDataset *fin = (GDALDataset*)GDALOpen(filename.c_str(), GA_ReadOnly);
  assert(fin!=NULL);

  GDALRasterBand *band   = fin->GetRasterBand(1);
  GDALDataType data_type = band->GetRasterDataType();

  GDALClose(fin);

  return data_type;
}
Example #9
0
int
NBHeightMapper::loadTiff(const std::string& file) {
#ifdef HAVE_GDAL
    GDALAllRegister();
    GDALDataset* poDataset = (GDALDataset*)GDALOpen(file.c_str(), GA_ReadOnly);
    if (poDataset == 0) {
        WRITE_ERROR("Cannot load GeoTIFF file.");
        return 0;
    }
    const int xSize = poDataset->GetRasterXSize();
    const int ySize = poDataset->GetRasterYSize();
    double adfGeoTransform[6];
    if (poDataset->GetGeoTransform(adfGeoTransform) == CE_None) {
        Position topLeft(adfGeoTransform[0], adfGeoTransform[3]);
        mySizeOfPixel.set(adfGeoTransform[1], adfGeoTransform[5]);
        const double horizontalSize = xSize * mySizeOfPixel.x();
        const double verticalSize = ySize * mySizeOfPixel.y();
        myBoundary.add(topLeft);
        myBoundary.add(topLeft.x() + horizontalSize, topLeft.y() + verticalSize);
    } else {
        WRITE_ERROR("Could not parse geo information from " + file + ".");
        return 0;
    }
    const int picSize = xSize * ySize;
    myRaster = (int16_t*)CPLMalloc(sizeof(int16_t) * picSize);
    for (int i = 1; i <= poDataset->GetRasterCount(); i++) {
        GDALRasterBand* poBand = poDataset->GetRasterBand(i);
        if (poBand->GetColorInterpretation() != GCI_GrayIndex) {
            WRITE_ERROR("Unknown color band in " + file + ".");
            clearData();
            break;
        }
        if (poBand->GetRasterDataType() != GDT_Int16) {
            WRITE_ERROR("Unknown data type in " + file + ".");
            clearData();
            break;
        }
        assert(xSize == poBand->GetXSize() && ySize == poBand->GetYSize());
        if (poBand->RasterIO(GF_Read, 0, 0, xSize, ySize, myRaster, xSize, ySize, GDT_Int16, 0, 0) == CE_Failure) {
            WRITE_ERROR("Failure in reading " + file + ".");
            clearData();
            break;
        }
    }
    GDALClose(poDataset);
    return picSize;
#else
    UNUSED_PARAMETER(file);
    WRITE_ERROR("Cannot load GeoTIFF file since SUMO was compiled without GDAL support.");
    return 0;
#endif
}
Example #10
0
/**
  @brief  Determine data type of a GDAL file's first layer
  @author Richard Barnes ([email protected])

  @param[in]  filename   Filename of file whose type should be determined
*/
GDALDataType peekGDALType(const std::string &filename) {
  GDALAllRegister();
  GDALDataset *fin = (GDALDataset*)GDALOpen(filename.c_str(), GA_ReadOnly);
  if(fin==NULL)
    throw std::runtime_error("Unable to open file '"+filename+"'!");

  GDALRasterBand *band   = fin->GetRasterBand(1);
  GDALDataType data_type = band->GetRasterDataType();

  GDALClose(fin);

  return data_type;
}
Example #11
0
SEXP
RGDAL_GetBandType(SEXP sxpRasterBand) {

  SEXP ans;

  GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand);
  PROTECT(ans = NEW_INTEGER(1));

  installErrorHandler();
  INTEGER_POINTER(ans)[0] = (int) pRasterBand->GetRasterDataType();
  uninstallErrorHandlerAndTriggerError();

  UNPROTECT(1);
  return(ans);
}
Example #12
0
void HazePerfection::invertImage(GDALDataset *pDataset, GDALDataset *dstDataset, float a)
{
	GDALRasterBand *band = pDataset->GetRasterBand(1);
	GDALDataType dataType = band->GetRasterDataType();
	float *pixelData = new float[nXSize*nYSize];
	band->RasterIO(GF_Read, 0, 0, nXSize, nYSize, pixelData, nXSize, nYSize, GDT_Float32, 0, 0);
	
	GDALRasterBand *dstBand = dstDataset->GetRasterBand(1);
	for (int j = 0; j < nYSize; j++)
	{
		for (int i = 0; i < nXSize; i++)
		{
			pixelData[j*nXSize + i] = a - pixelData[j*nXSize + i];
		}
	}
	dstBand->RasterIO(GF_Write, 0, 0, nXSize, nYSize, pixelData, nXSize, nYSize, GDT_Float32, 0, 0);
	delete[]pixelData;
}
Example #13
0
wxGISRasterLayer::wxGISRasterLayer(const wxString &sName, wxGISDataset* pwxGISDataset) : wxGISLayer(sName, pwxGISDataset)
{
    wxGISRasterDataset* pwxGISRasterDataset = wxDynamicCast(pwxGISDataset, wxGISRasterDataset);
	if(pwxGISRasterDataset)
	{
        if(m_sName.IsEmpty())
            m_sName = pwxGISRasterDataset->GetName();

        m_SpatialReference = pwxGISRasterDataset->GetSpatialReference();
		m_FullEnvelope = pwxGISRasterDataset->GetEnvelope();

        //TODO: load or get all renderers and check if i render can draw this dataset. If yes - set it as current
		if(pwxGISRasterDataset->GetBandCount() >= 3)
        {
            m_pRenderer = new wxGISRasterRGBARenderer(pwxGISDataset);
        }
        else
        {
		    GDALDataset* poGDALDataset = pwxGISRasterDataset->GetMainRaster();
		    if(!poGDALDataset)
			    poGDALDataset = pwxGISRasterDataset->GetRaster();
		    if(!poGDALDataset)
			    return;

		    GDALRasterBand* pBand = poGDALDataset->GetRasterBand(1);
            GDALColorInterp eColorInterpretation = pBand->GetColorInterpretation();
            if( eColorInterpretation == GCI_PaletteIndex )
            {
                m_pRenderer = new wxGISRasterRasterColormapRenderer(pwxGISDataset);
            }
            else if(pBand->GetRasterDataType() == GDT_Int32)
            {
                m_pRenderer = new wxGISRasterPackedRGBARenderer(pwxGISDataset);
            }
            else// if( eColorInterpretation == GCI_GrayIndex )
            {
    		    //TODO: else RasterStretchColorRampRenderer
                m_pRenderer = new wxGISRasterGreyScaleRenderer(pwxGISDataset);
            }
        }
	}
}
  void loadGDAL(const std::string &filename, int xOffset=0, int yOffset=0, int part_width=0, int part_height=0){
    assert(empty());
    assert(xOffset>=0);
    assert(yOffset>=0);

    GDALDataset *fin = (GDALDataset*)GDALOpen(filename.c_str(), GA_ReadOnly);
    assert(fin!=NULL);

    GDALRasterBand *band = fin->GetRasterBand(1);
    auto data_type       = band->GetRasterDataType();

    total_width  = band->GetXSize();
    total_height = band->GetYSize();
    no_data      = band->GetNoDataValue();

    if(xOffset+part_width>=total_width)
      part_width  = total_width-xOffset;
    if(yOffset+part_height>=total_height)
      part_height = total_height-yOffset;

    if(part_width==0)
      part_width = total_width;
    view_width = part_width;

    if(part_height==0)
      part_height = total_height;
    view_height = part_height;

    view_xoff = xOffset;
    view_yoff = yOffset;

    std::cerr<<"Allocating: "<<view_height<<" rows by "<<view_width<<" columns"<<std::endl;
    data = InternalArray(view_height, Row(view_width));
    for(int y=yOffset;y<yOffset+view_height;y++)
      band->RasterIO( GF_Read, xOffset, y, view_width, 1, data[y-yOffset].data(), view_width, 1, data_type, 0, 0 );

    GDALClose(fin);
  }
Example #15
0
GDALDatasetH CPL_STDCALL
GDALCreateWarpedVRT( GDALDatasetH hSrcDS, 
                     int nPixels, int nLines, double *padfGeoTransform,
                     GDALWarpOptions *psOptions )
    
{
    VALIDATE_POINTER1( hSrcDS, "GDALCreateWarpedVRT", NULL );

/* -------------------------------------------------------------------- */
/*      Create the VRTDataset and populate it with bands.               */
/* -------------------------------------------------------------------- */
    VRTWarpedDataset *poDS = new VRTWarpedDataset( nPixels, nLines );
    int i;

    psOptions->hDstDS = (GDALDatasetH) poDS;

    poDS->SetGeoTransform( padfGeoTransform );

    for( i = 0; i < psOptions->nBandCount; i++ )
    {
        VRTWarpedRasterBand *poBand;
        GDALRasterBand *poSrcBand = (GDALRasterBand *) 
            GDALGetRasterBand( hSrcDS, i+1 );

        poDS->AddBand( poSrcBand->GetRasterDataType(), NULL );

        poBand = (VRTWarpedRasterBand *) poDS->GetRasterBand( i+1 );
        poBand->CopyCommonInfoFrom( poSrcBand );
    }

/* -------------------------------------------------------------------- */
/*      Initialize the warp on the VRTWarpedDataset.                    */
/* -------------------------------------------------------------------- */
    poDS->Initialize( psOptions );
    
    return (GDALDatasetH) poDS;
}
Example #16
0
/**
  @brief  Retrieve height, width, data type, and geotransform from a GDAL file
  @author Richard Barnes ([email protected])

  @param[in]  filename   GDAL file to peek at
  @param[out] height     Height of the raster in cells
  @param[out] width      Width of the raster in cells
  @param[out] dtype      Data type of the file in question
  @param[out] geo_trans  Returns the SIX elements of the raster's geotransform
*/
void getGDALDimensions(
  const   std::string &filename,
  int32_t &height,
  int32_t &width,
  GDALDataType &dtype,
  double geotransform[6]
){
  GDALAllRegister();
  GDALDataset *fin = (GDALDataset*)GDALOpen(filename.c_str(), GA_ReadOnly);
  if(fin==NULL)
    throw std::runtime_error("Could not open file '"+filename+"' to get dimensions.");

  GDALRasterBand *band = fin->GetRasterBand(1);
  
  dtype = band->GetRasterDataType();

  if(geotransform!=NULL && fin->GetGeoTransform(geotransform)!=CE_None)
    throw std::runtime_error("Error getting geotransform from '"+filename+"'.");

  height  = band->GetYSize();
  width   = band->GetXSize();

  GDALClose(fin);
}
Example #17
0
void generateTexture(string fname, GLuint& tex, int bandnum)
{
   if(bandnum <= 0 )
   {
     bandnum = 1;
   }
   GDALDataset *poDataset;
   GDALAllRegister();
   poDataset= (GDALDataset*) GDALOpen(fname.c_str(),GA_ReadOnly);
   if(poDataset == NULL)
   {
      cout << "OUCH!" << endl;
      //exit(0);
      return;
   }
   cout << "Data size: " << GDALGetRasterXSize(poDataset) << " " << GDALGetRasterYSize(poDataset) << endl;

   GDALRasterBand  *poBand;
   int             nBlockXSize, nBlockYSize;
   int             bGotMin, bGotMax;
   double          adfMinMax[2];
  int bands = poDataset->GetRasterCount();
   bandnum = bandnum % bands + 1;
   if(bandnum > bands)
   {
      bandnum = 1;
   }
   poBand = poDataset->GetRasterBand( bandnum );
   poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
   printf( "Block=%dx%d Type=%s, ColorInterp=%s\n",
            nBlockXSize, nBlockYSize,
            GDALGetDataTypeName(poBand->GetRasterDataType()),
            GDALGetColorInterpretationName(
            poBand->GetColorInterpretation()) );

   float max = adfMinMax[0] = poBand->GetMinimum( &bGotMin );
   float min = adfMinMax[1] = poBand->GetMaximum( &bGotMax );
   if( ! (bGotMin && bGotMax) )
      GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax);
   int width = poBand->GetXSize(); 
   int height = poBand->GetYSize();

   float *pafScanline;
   std::cout << "Before allocation" << adfMinMax[0] << " " << adfMinMax[1] << endl;
   min = adfMinMax[0];
   max = adfMinMax[1];
   int dsize = 256;
   pafScanline = (float *) CPLMalloc(sizeof(float)*512*512);
   vector<vector<float>> out = vector<vector<float>>(height,vector<float> (width,0));
   //vector<vector<unsigned char>> texs = vector<vector<unsigned char>>(height,vector<unsigned char> (width,0));
   unsigned char texs[512*512];
   poBand->RasterIO(GF_Read,0,0,width,height,pafScanline,512,512,GDT_Float32,0,0);
   float no = poBand->GetNoDataValue();
   cout << "After allocation" << endl;
   for(int i = 0; i < 512; i++)
   {
    for(int j = 0; j < 512; j++)
    {
      //cout << i << j << endl << pafS;
      if(pafScanline[i*width+j] != no)
      {
        // set tex val
        texs[i*512+j] = (unsigned char)(255*((pafScanline[i*512+j] - min)/(max-min)));
        //if((int)texs[i*width] < 0)
        //cout << (int)texs[i*512 +j] << " " << pafScanline[i*512+j] << " " << no << " " << fname << " " << min << " " << max << endl;
      }
      else
      {
        // Set zero val
        texs[i*512+j] = 0;
        //cout << (int)texs[i*512 +j] << fname << endl;
      }
      //texs[i*512+j] = 255;

      //ut[i][j] = pafScanline[i*width+j];
    }
   }
   CPLFree(pafScanline);
   //exit(0);
   // Create a texture
   glGenTextures(1,&tex);
   glBindTexture(GL_TEXTURE_2D,tex);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 512,512, 0, GL_RED, GL_UNSIGNED_BYTE,texs);
   GDALClose( (GDALDatasetH) poDataset);
   return;
} 
Example #18
0
static GDALDataset *
GMTCreateCopy( const char * pszFilename, GDALDataset *poSrcDS,
               int bStrict, CPL_UNUSED char ** papszOptions,
               CPL_UNUSED GDALProgressFunc pfnProgress,
               CPL_UNUSED void * pProgressData )
{
/* -------------------------------------------------------------------- */
/*      Figure out general characteristics.                             */
/* -------------------------------------------------------------------- */
    nc_type nc_datatype;
    GDALRasterBand *poBand;
    int nXSize, nYSize;

    CPLMutexHolderD(&hNCMutex);

    if( poSrcDS->GetRasterCount() != 1 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Currently GMT export only supports 1 band datasets." );
        return NULL;
    }

    poBand = poSrcDS->GetRasterBand(1);

    nXSize = poSrcDS->GetRasterXSize();
    nYSize = poSrcDS->GetRasterYSize();
    
    if( poBand->GetRasterDataType() == GDT_Int16 )
        nc_datatype = NC_SHORT;
    else if( poBand->GetRasterDataType() == GDT_Int32 )
        nc_datatype = NC_INT;
    else if( poBand->GetRasterDataType() == GDT_Float32 )
        nc_datatype = NC_FLOAT;
    else if( poBand->GetRasterDataType() == GDT_Float64 )
        nc_datatype = NC_DOUBLE;
    else if( bStrict )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Band data type %s not supported in GMT, giving up.",
                  GDALGetDataTypeName( poBand->GetRasterDataType() ) );
        return NULL;
    }
    else if( poBand->GetRasterDataType() == GDT_Byte )
        nc_datatype = NC_SHORT;
    else if( poBand->GetRasterDataType() == GDT_UInt16 )
        nc_datatype = NC_INT;
    else if( poBand->GetRasterDataType() == GDT_UInt32 )
        nc_datatype = NC_INT;
    else 
        nc_datatype = NC_FLOAT;
    
/* -------------------------------------------------------------------- */
/*      Establish bounds from geotransform.                             */
/* -------------------------------------------------------------------- */
    double adfGeoTransform[6];
    double dfXMax, dfYMin;

    poSrcDS->GetGeoTransform( adfGeoTransform );
    
    if( adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0 )
    {
        CPLError( bStrict ? CE_Failure : CE_Warning, CPLE_AppDefined, 
                  "Geotransform has rotational coefficients not supported in GMT." );
        if( bStrict )
            return NULL;
    }

    dfXMax = adfGeoTransform[0] + adfGeoTransform[1] * nXSize;
    dfYMin = adfGeoTransform[3] + adfGeoTransform[5] * nYSize;
    
/* -------------------------------------------------------------------- */
/*      Create base file.                                               */
/* -------------------------------------------------------------------- */
    int cdfid, err;

    err = nc_create (pszFilename, NC_CLOBBER,&cdfid);
    if( err != NC_NOERR )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "nc_create(%s): %s", 
                  pszFilename, nc_strerror( err ) );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Define the dimensions and so forth.                             */
/* -------------------------------------------------------------------- */
    int side_dim, xysize_dim, dims[1];
    int x_range_id, y_range_id, z_range_id, inc_id, nm_id, z_id;

    nc_def_dim(cdfid, "side", 2, &side_dim);
    nc_def_dim(cdfid, "xysize", (int) (nXSize * nYSize), &xysize_dim);

    dims[0]		= side_dim;
    nc_def_var (cdfid, "x_range", NC_DOUBLE, 1, dims, &x_range_id);
    nc_def_var (cdfid, "y_range", NC_DOUBLE, 1, dims, &y_range_id);
    nc_def_var (cdfid, "z_range", NC_DOUBLE, 1, dims, &z_range_id);
    nc_def_var (cdfid, "spacing", NC_DOUBLE, 1, dims, &inc_id);
    nc_def_var (cdfid, "dimension", NC_LONG, 1, dims, &nm_id);

    dims[0]		= xysize_dim;
    nc_def_var (cdfid, "z", nc_datatype, 1, dims, &z_id);

/* -------------------------------------------------------------------- */
/*      Assign attributes.                                              */
/* -------------------------------------------------------------------- */
    double default_scale = 1.0;
    double default_offset = 0.0;
    int default_node_offset = 1; // pixel is area

    nc_put_att_text (cdfid, x_range_id, "units", 7, "meters");
    nc_put_att_text (cdfid, y_range_id, "units", 7, "meters");
    nc_put_att_text (cdfid, z_range_id, "units", 7, "meters");

    nc_put_att_double (cdfid, z_id, "scale_factor", NC_DOUBLE, 1, 
                       &default_scale );
    nc_put_att_double (cdfid, z_id, "add_offset", NC_DOUBLE, 1, 
                       &default_offset );

    nc_put_att_int (cdfid, z_id, "node_offset", NC_LONG, 1, 
                    &default_node_offset );
    nc_put_att_text (cdfid, NC_GLOBAL, "title", 1, "");
    nc_put_att_text (cdfid, NC_GLOBAL, "source", 1, "");
	
    /* leave define mode */
    nc_enddef (cdfid);

/* -------------------------------------------------------------------- */
/*      Get raster min/max.                                             */
/* -------------------------------------------------------------------- */
    double adfMinMax[2];
    GDALComputeRasterMinMax( (GDALRasterBandH) poBand, FALSE, adfMinMax );
	
/* -------------------------------------------------------------------- */
/*      Set range variables.                                            */
/* -------------------------------------------------------------------- */
    size_t start[2], edge[2];
    double dummy[2];
    int nm[2];
	
    start[0] = 0;
    edge[0] = 2;
    dummy[0] = adfGeoTransform[0];
    dummy[1] = dfXMax;
    nc_put_vara_double(cdfid, x_range_id, start, edge, dummy);

    dummy[0] = dfYMin;
    dummy[1] = adfGeoTransform[3];
    nc_put_vara_double(cdfid, y_range_id, start, edge, dummy);

    dummy[0] = adfGeoTransform[1];
    dummy[1] = -adfGeoTransform[5];
    nc_put_vara_double(cdfid, inc_id, start, edge, dummy);

    nm[0] = nXSize;
    nm[1] = nYSize;
    nc_put_vara_int(cdfid, nm_id, start, edge, nm);

    nc_put_vara_double(cdfid, z_range_id, start, edge, adfMinMax);

/* -------------------------------------------------------------------- */
/*      Write out the image one scanline at a time.                     */
/* -------------------------------------------------------------------- */
    double *padfData;
    int  iLine;

    padfData = (double *) CPLMalloc( sizeof(double) * nXSize );

    edge[0] = nXSize;
    for( iLine = 0; iLine < nYSize; iLine++ )
    {
        start[0] = iLine * nXSize;
        poBand->RasterIO( GF_Read, 0, iLine, nXSize, 1, 
                          padfData, nXSize, 1, GDT_Float64, 0, 0, NULL );
        err = nc_put_vara_double( cdfid, z_id, start, edge, padfData );
        if( err != NC_NOERR )
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                      "nc_put_vara_double(%s): %s", 
                      pszFilename, nc_strerror( err ) );
            nc_close (cdfid);
            return( NULL );
        }
    }
    
    CPLFree( padfData );

/* -------------------------------------------------------------------- */
/*      Close file, and reopen.                                         */
/* -------------------------------------------------------------------- */
    nc_close (cdfid);

/* -------------------------------------------------------------------- */
/*      Re-open dataset, and copy any auxiliary pam information.         */
/* -------------------------------------------------------------------- */
    GDALPamDataset *poDS = (GDALPamDataset *)
        GDALOpen( pszFilename, GA_ReadOnly );

    if( poDS )
        poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT );

    return poDS;
}
Example #19
0
CPLErr 
GTIFFBuildOverviews( const char * pszFilename,
                     int nBands, GDALRasterBand **papoBandList, 
                     int nOverviews, int * panOverviewList,
                     const char * pszResampling, 
                     GDALProgressFunc pfnProgress, void * pProgressData )

{
    TIFF    *hOTIFF;
    int     nBitsPerPixel=0, nCompression=COMPRESSION_NONE, nPhotometric=0;
    int     nSampleFormat=0, nPlanarConfig, iOverview, iBand;
    int     nXSize=0, nYSize=0;

    if( nBands == 0 || nOverviews == 0 )
        return CE_None;

    if (!GTiffOneTimeInit())
        return CE_Failure;

/* -------------------------------------------------------------------- */
/*      Verify that the list of bands is suitable for emitting in       */
/*      TIFF file.                                                      */
/* -------------------------------------------------------------------- */
    for( iBand = 0; iBand < nBands; iBand++ )
    {
        int     nBandBits, nBandFormat;
        GDALRasterBand *hBand = papoBandList[iBand];

        switch( hBand->GetRasterDataType() )
        {
          case GDT_Byte:
            nBandBits = 8;
            nBandFormat = SAMPLEFORMAT_UINT;
            break;

          case GDT_UInt16:
            nBandBits = 16;
            nBandFormat = SAMPLEFORMAT_UINT;
            break;

          case GDT_Int16:
            nBandBits = 16;
            nBandFormat = SAMPLEFORMAT_INT;
            break;

          case GDT_UInt32:
            nBandBits = 32;
            nBandFormat = SAMPLEFORMAT_UINT;
            break;

          case GDT_Int32:
            nBandBits = 32;
            nBandFormat = SAMPLEFORMAT_INT;
            break;

          case GDT_Float32:
            nBandBits = 32;
            nBandFormat = SAMPLEFORMAT_IEEEFP;
            break;

          case GDT_Float64:
            nBandBits = 64;
            nBandFormat = SAMPLEFORMAT_IEEEFP;
            break;

          case GDT_CInt16:
            nBandBits = 32;
            nBandFormat = SAMPLEFORMAT_COMPLEXINT;
            break;

          case GDT_CInt32:
            nBandBits = 64;
            nBandFormat = SAMPLEFORMAT_COMPLEXINT;
            break;

          case GDT_CFloat32:
            nBandBits = 64;
            nBandFormat = SAMPLEFORMAT_COMPLEXIEEEFP;
            break;

          case GDT_CFloat64:
            nBandBits = 128;
            nBandFormat = SAMPLEFORMAT_COMPLEXIEEEFP;
            break;

          default:
            CPLAssert( FALSE );
            return CE_Failure;
        }

        if( hBand->GetMetadataItem( "NBITS", "IMAGE_STRUCTURE" ) )
        {
            nBandBits = 
                atoi(hBand->GetMetadataItem("NBITS","IMAGE_STRUCTURE"));

            if( nBandBits == 1 
                && EQUALN(pszResampling,"AVERAGE_BIT2",12) )
                nBandBits = 8;
        }

        if( iBand == 0 )
        {
            nBitsPerPixel = nBandBits;
            nSampleFormat = nBandFormat;
            nXSize = hBand->GetXSize();
            nYSize = hBand->GetYSize();
        }
        else if( nBitsPerPixel != nBandBits || nSampleFormat != nBandFormat )
        {
            CPLError( CE_Failure, CPLE_NotSupported, 
                      "GTIFFBuildOverviews() doesn't support a mixture of band"
                      " data types." );
            return CE_Failure;
        }
        else if( hBand->GetColorTable() != NULL )
        {
            CPLError( CE_Failure, CPLE_NotSupported, 
                      "GTIFFBuildOverviews() doesn't support building"
                      " overviews of multiple colormapped bands." );
            return CE_Failure;
        }
        else if( hBand->GetXSize() != nXSize 
                 || hBand->GetYSize() != nYSize )
        {
            CPLError( CE_Failure, CPLE_NotSupported, 
                      "GTIFFBuildOverviews() doesn't support building"
                      " overviews of different sized bands." );
            return CE_Failure;
        }
    }

/* -------------------------------------------------------------------- */
/*      Use specified compression method.                               */
/* -------------------------------------------------------------------- */
    const char *pszCompress = CPLGetConfigOption( "COMPRESS_OVERVIEW", NULL );

    if( pszCompress != NULL && pszCompress[0] != '\0' )
    {
        nCompression = GTIFFGetCompressionMethod(pszCompress, "COMPRESS_OVERVIEW");
        if (nCompression < 0)
            return CE_Failure;
    }
    
    if( nCompression == COMPRESSION_JPEG && nBitsPerPixel > 8 )
    {  
        if( nBitsPerPixel > 16 )
        {
            CPLError( CE_Failure, CPLE_NotSupported, 
                      "GTIFFBuildOverviews() doesn't support building"
                      " JPEG compressed overviews of nBitsPerPixel > 16." );
            return CE_Failure;
        }

        nBitsPerPixel = 12;
    }

/* -------------------------------------------------------------------- */
/*      Figure out the planar configuration to use.                     */
/* -------------------------------------------------------------------- */
    if( nBands == 1 )
        nPlanarConfig = PLANARCONFIG_CONTIG;
    else
        nPlanarConfig = PLANARCONFIG_SEPARATE;

    const char* pszInterleave = CPLGetConfigOption( "INTERLEAVE_OVERVIEW", NULL );
    if (pszInterleave != NULL && pszInterleave[0] != '\0')
    {
        if( EQUAL( pszInterleave, "PIXEL" ) )
            nPlanarConfig = PLANARCONFIG_CONTIG;
        else if( EQUAL( pszInterleave, "BAND" ) )
            nPlanarConfig = PLANARCONFIG_SEPARATE;
        else
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                      "INTERLEAVE_OVERVIEW=%s unsupported, value must be PIXEL or BAND. ignoring",
                      pszInterleave );
        }
    }

/* -------------------------------------------------------------------- */
/*      Figure out the photometric interpretation to use.               */
/* -------------------------------------------------------------------- */
    if( nBands == 3 )
        nPhotometric = PHOTOMETRIC_RGB;
    else if( papoBandList[0]->GetColorTable() != NULL 
             && !EQUALN(pszResampling,"AVERAGE_BIT2",12) )
    {
        nPhotometric = PHOTOMETRIC_PALETTE;
        /* should set the colormap up at this point too! */
    }
    else
        nPhotometric = PHOTOMETRIC_MINISBLACK;

    const char* pszPhotometric = CPLGetConfigOption( "PHOTOMETRIC_OVERVIEW", NULL );
    if (pszPhotometric != NULL && pszPhotometric[0] != '\0')
    {
        if( EQUAL( pszPhotometric, "MINISBLACK" ) )
            nPhotometric = PHOTOMETRIC_MINISBLACK;
        else if( EQUAL( pszPhotometric, "MINISWHITE" ) )
            nPhotometric = PHOTOMETRIC_MINISWHITE;
        else if( EQUAL( pszPhotometric, "RGB" ))
        {
            nPhotometric = PHOTOMETRIC_RGB;
        }
        else if( EQUAL( pszPhotometric, "CMYK" ))
        {
            nPhotometric = PHOTOMETRIC_SEPARATED;
        }
        else if( EQUAL( pszPhotometric, "YCBCR" ))
        {
            nPhotometric = PHOTOMETRIC_YCBCR;

            /* Because of subsampling, setting YCBCR without JPEG compression leads */
            /* to a crash currently. Would need to make GTiffRasterBand::IWriteBlock() */
            /* aware of subsampling so that it doesn't overrun buffer size returned */
            /* by libtiff */
            if ( nCompression != COMPRESSION_JPEG )
            {
                CPLError(CE_Failure, CPLE_NotSupported,
                         "Currently, PHOTOMETRIC_OVERVIEW=YCBCR requires COMPRESS_OVERVIEW=JPEG");
                return CE_Failure;
            }

            if (pszInterleave != NULL && pszInterleave[0] != '\0' && nPlanarConfig == PLANARCONFIG_SEPARATE)
            {
                CPLError(CE_Failure, CPLE_NotSupported,
                         "PHOTOMETRIC_OVERVIEW=YCBCR requires INTERLEAVE_OVERVIEW=PIXEL");
                return CE_Failure;
            }
            else
            {
                nPlanarConfig = PLANARCONFIG_CONTIG;
            }

            /* YCBCR strictly requires 3 bands. Not less, not more */
            /* Issue an explicit error message as libtiff one is a bit cryptic : */
            /* JPEGLib:Bogus input colorspace */
            if ( nBands != 3 )
            {
                CPLError(CE_Failure, CPLE_NotSupported,
                         "PHOTOMETRIC_OVERVIEW=YCBCR requires a source raster with only 3 bands (RGB)");
                return CE_Failure;
            }
        }
        else if( EQUAL( pszPhotometric, "CIELAB" ))
        {
            nPhotometric = PHOTOMETRIC_CIELAB;
        }
        else if( EQUAL( pszPhotometric, "ICCLAB" ))
        {
            nPhotometric = PHOTOMETRIC_ICCLAB;
        }
        else if( EQUAL( pszPhotometric, "ITULAB" ))
        {
            nPhotometric = PHOTOMETRIC_ITULAB;
        }
        else
        {
            CPLError( CE_Warning, CPLE_IllegalArg, 
                      "PHOTOMETRIC_OVERVIEW=%s value not recognised, ignoring.\n",
                      pszPhotometric );
        }
    }

/* -------------------------------------------------------------------- */
/*      Figure out the predictor value to use.                          */
/* -------------------------------------------------------------------- */
    int nPredictor = PREDICTOR_NONE;
    if ( nCompression == COMPRESSION_LZW ||
         nCompression == COMPRESSION_ADOBE_DEFLATE )
    {
        const char* pszPredictor = CPLGetConfigOption( "PREDICTOR_OVERVIEW", NULL );
        if( pszPredictor  != NULL )
        {
            nPredictor =  atoi( pszPredictor );
        }
    }

/* -------------------------------------------------------------------- */
/*      Create the file, if it does not already exist.                  */
/* -------------------------------------------------------------------- */
    VSIStatBufL  sStatBuf;
    VSILFILE* fpL = NULL;

    if( VSIStatExL( pszFilename, &sStatBuf, VSI_STAT_EXISTS_FLAG ) != 0 )
    {
    /* -------------------------------------------------------------------- */
    /*      Compute the uncompressed size.                                  */
    /* -------------------------------------------------------------------- */
        double  dfUncompressedOverviewSize = 0;
        int nDataTypeSize = GDALGetDataTypeSize(papoBandList[0]->GetRasterDataType())/8;

        for( iOverview = 0; iOverview < nOverviews; iOverview++ )
        {
            int    nOXSize, nOYSize;

            nOXSize = (nXSize + panOverviewList[iOverview] - 1) 
                / panOverviewList[iOverview];
            nOYSize = (nYSize + panOverviewList[iOverview] - 1) 
                / panOverviewList[iOverview];

            dfUncompressedOverviewSize += 
                nOXSize * ((double)nOYSize) * nBands * nDataTypeSize;
        }

        if( nCompression == COMPRESSION_NONE 
            && dfUncompressedOverviewSize > 4200000000.0 )
        {
    #ifndef BIGTIFF_SUPPORT
            CPLError( CE_Failure, CPLE_NotSupported, 
                    "The overview file would be larger than 4GB\n"
                    "but this is the largest size a TIFF can be, and BigTIFF is unavailable.\n"
                    "Creation failed." );
            return CE_Failure;
    #endif
        }
    /* -------------------------------------------------------------------- */
    /*      Should the file be created as a bigtiff file?                   */
    /* -------------------------------------------------------------------- */
        const char *pszBIGTIFF = CPLGetConfigOption( "BIGTIFF_OVERVIEW", NULL );

        if( pszBIGTIFF == NULL )
            pszBIGTIFF = "IF_NEEDED";

        int bCreateBigTIFF = FALSE;
        if( EQUAL(pszBIGTIFF,"IF_NEEDED") )
        {
            if( nCompression == COMPRESSION_NONE 
                && dfUncompressedOverviewSize > 4200000000.0 )
                bCreateBigTIFF = TRUE;
        }
        else if( EQUAL(pszBIGTIFF,"IF_SAFER") )
        {
            /* Look at the size of the base image and suppose that */
            /* the added overview levels won't be more than 1/2 of */
            /* the size of the base image. The theory says 1/3 of the */
            /* base image size if the overview levels are 2, 4, 8, 16... */
            /* Thus take 1/2 as the security margin for 1/3 */
            double dfUncompressedImageSize =
                        nXSize * ((double)nYSize) * nBands * nDataTypeSize;
            if( dfUncompressedImageSize * .5 > 4200000000.0 )
                bCreateBigTIFF = TRUE;
        }
        else
        {
            bCreateBigTIFF = CSLTestBoolean( pszBIGTIFF );
            if (!bCreateBigTIFF && nCompression == COMPRESSION_NONE 
                && dfUncompressedOverviewSize > 4200000000.0 )
            {
                CPLError( CE_Failure, CPLE_NotSupported, 
                    "The overview file will be larger than 4GB, so BigTIFF is necessary.\n"
                    "Creation failed.");
                return CE_Failure;
            }
        }

    #ifndef BIGTIFF_SUPPORT
        if( bCreateBigTIFF )
        {
            CPLError( CE_Warning, CPLE_NotSupported,
                    "BigTIFF requested, but GDAL built without BigTIFF\n"
                    "enabled libtiff, request ignored." );
            bCreateBigTIFF = FALSE;
        }
    #endif

        if( bCreateBigTIFF )
            CPLDebug( "GTiff", "File being created as a BigTIFF." );

        fpL = VSIFOpenL( pszFilename, "w+" );
        if( fpL == NULL )
            hOTIFF = NULL;
        else
            hOTIFF = VSI_TIFFOpen( pszFilename, (bCreateBigTIFF) ? "w+8" : "w+", fpL );
        if( hOTIFF == NULL )
        {
            if( CPLGetLastErrorNo() == 0 )
                CPLError( CE_Failure, CPLE_OpenFailed,
                          "Attempt to create new tiff file `%s'\n"
                          "failed in VSI_TIFFOpen().\n",
                          pszFilename );
            if( fpL != NULL )
                VSIFCloseL(fpL);
            return CE_Failure;
        }
    }
/* -------------------------------------------------------------------- */
/*      Otherwise just open it for update access.                       */
/* -------------------------------------------------------------------- */
    else 
    {
        fpL = VSIFOpenL( pszFilename, "r+" );
        if( fpL == NULL )
            hOTIFF = NULL;
        else
            hOTIFF = VSI_TIFFOpen( pszFilename, "r+", fpL );
        if( hOTIFF == NULL )
        {
            if( CPLGetLastErrorNo() == 0 )
                CPLError( CE_Failure, CPLE_OpenFailed,
                          "Attempt to create new tiff file `%s'\n"
                          "failed in VSI_TIFFOpen().\n",
                          pszFilename );
            if( fpL != NULL )
                VSIFCloseL(fpL);
            return CE_Failure;
        }
    }

/* -------------------------------------------------------------------- */
/*      Do we have a palette?  If so, create a TIFF compatible version. */
/* -------------------------------------------------------------------- */
    unsigned short      *panRed=NULL, *panGreen=NULL, *panBlue=NULL;

    if( nPhotometric == PHOTOMETRIC_PALETTE )
    {
        GDALColorTable *poCT = papoBandList[0]->GetColorTable();
        int nColorCount;

        if( nBitsPerPixel <= 8 )
            nColorCount = 256;
        else
            nColorCount = 65536;

        panRed   = (unsigned short *) 
            CPLCalloc(nColorCount,sizeof(unsigned short));
        panGreen = (unsigned short *) 
            CPLCalloc(nColorCount,sizeof(unsigned short));
        panBlue  = (unsigned short *) 
            CPLCalloc(nColorCount,sizeof(unsigned short));

        for( int iColor = 0; iColor < nColorCount; iColor++ )
        {
            GDALColorEntry  sRGB;

            if( poCT->GetColorEntryAsRGB( iColor, &sRGB ) )
            {
                panRed[iColor] = (unsigned short) (257 * sRGB.c1);
                panGreen[iColor] = (unsigned short) (257 * sRGB.c2);
                panBlue[iColor] = (unsigned short) (257 * sRGB.c3);
            }
        }
    }

/* -------------------------------------------------------------------- */
/*      Do we need some metadata for the overviews?                     */
/* -------------------------------------------------------------------- */
    CPLString osMetadata;
    GDALDataset *poBaseDS = papoBandList[0]->GetDataset();

    GTIFFBuildOverviewMetadata( pszResampling, poBaseDS, osMetadata );

/* -------------------------------------------------------------------- */
/*      Loop, creating overviews.                                       */
/* -------------------------------------------------------------------- */
    int nOvrBlockXSize, nOvrBlockYSize;
    GTIFFGetOverviewBlockSize(&nOvrBlockXSize, &nOvrBlockYSize);
    for( iOverview = 0; iOverview < nOverviews; iOverview++ )
    {
        int    nOXSize, nOYSize;

        nOXSize = (nXSize + panOverviewList[iOverview] - 1) 
            / panOverviewList[iOverview];
        nOYSize = (nYSize + panOverviewList[iOverview] - 1) 
            / panOverviewList[iOverview];

        GTIFFWriteDirectory(hOTIFF, FILETYPE_REDUCEDIMAGE,
                            nOXSize, nOYSize, nBitsPerPixel, 
                            nPlanarConfig, nBands,
                            nOvrBlockXSize, nOvrBlockYSize, TRUE, nCompression,
                            nPhotometric, nSampleFormat, nPredictor,
                            panRed, panGreen, panBlue,
                            0, NULL, /* FIXME? how can we fetch extrasamples */
                            osMetadata );
    }

    if (panRed)
    {
        CPLFree(panRed);
        CPLFree(panGreen);
        CPLFree(panBlue);
        panRed = panGreen = panBlue = NULL;
    }

    XTIFFClose( hOTIFF );
    VSIFCloseL(fpL);
    fpL = NULL;

/* -------------------------------------------------------------------- */
/*      Open the overview dataset so that we can get at the overview    */
/*      bands.                                                          */
/* -------------------------------------------------------------------- */
    GDALDataset *hODS;
    CPLErr eErr = CE_None;

    hODS = (GDALDataset *) GDALOpen( pszFilename, GA_Update );
    if( hODS == NULL )
        return CE_Failure;
    
/* -------------------------------------------------------------------- */
/*      Do we need to set the jpeg quality?                             */
/* -------------------------------------------------------------------- */
    TIFF *hTIFF = (TIFF*) hODS->GetInternalHandle(NULL);

    if( nCompression == COMPRESSION_JPEG 
        && CPLGetConfigOption( "JPEG_QUALITY_OVERVIEW", NULL ) != NULL )
    {
        int nJpegQuality = atoi(CPLGetConfigOption("JPEG_QUALITY_OVERVIEW","75"));
        TIFFSetField( hTIFF, TIFFTAG_JPEGQUALITY, 
                      nJpegQuality );
        GTIFFSetJpegQuality((GDALDatasetH)hODS, nJpegQuality);
    }

/* -------------------------------------------------------------------- */
/*      Loop writing overview data.                                     */
/* -------------------------------------------------------------------- */

    if (nCompression != COMPRESSION_NONE &&
        nPlanarConfig == PLANARCONFIG_CONTIG &&
        GDALDataTypeIsComplex(papoBandList[0]->GetRasterDataType()) == FALSE &&
        papoBandList[0]->GetColorTable() == NULL &&
        (EQUALN(pszResampling, "NEAR", 4) || EQUAL(pszResampling, "AVERAGE") ||
         EQUAL(pszResampling, "GAUSS") || EQUAL(pszResampling, "CUBIC") ||
         EQUAL(pszResampling, "CUBICSPLINE") || EQUAL(pszResampling, "LANCZOS") ||
         EQUAL(pszResampling, "BILINEAR")))
    {
        /* In the case of pixel interleaved compressed overviews, we want to generate */
        /* the overviews for all the bands block by block, and not band after band, */
        /* in order to write the block once and not loose space in the TIFF file */
        GDALRasterBand ***papapoOverviewBands;

        papapoOverviewBands = (GDALRasterBand ***) CPLCalloc(sizeof(void*),nBands);
        for( iBand = 0; iBand < nBands && eErr == CE_None; iBand++ )
        {
            GDALRasterBand    *hSrcBand = papoBandList[iBand];
            GDALRasterBand    *hDstBand = hODS->GetRasterBand( iBand+1 );
            papapoOverviewBands[iBand] = (GDALRasterBand **) CPLCalloc(sizeof(void*),nOverviews);
            papapoOverviewBands[iBand][0] = hDstBand;

            int bHasNoData;
            double noDataValue = hSrcBand->GetNoDataValue(&bHasNoData);
            if (bHasNoData)
                hDstBand->SetNoDataValue(noDataValue);

            for( int i = 0; i < nOverviews-1 && eErr == CE_None; i++ )
            {
                papapoOverviewBands[iBand][i+1] = hDstBand->GetOverview(i);
                if (papapoOverviewBands[iBand][i+1] == NULL)
                    eErr = CE_Failure;
                else
                {
                    if (bHasNoData)
                        papapoOverviewBands[iBand][i+1]->SetNoDataValue(noDataValue);
                }
            }
        }

        if (eErr == CE_None)
            eErr = GDALRegenerateOverviewsMultiBand(nBands, papoBandList,
                                            nOverviews, papapoOverviewBands,
                                            pszResampling, pfnProgress, pProgressData );

        for( iBand = 0; iBand < nBands; iBand++ )
        {
            CPLFree(papapoOverviewBands[iBand]);
        }
        CPLFree(papapoOverviewBands);
    }
    else
    {
        GDALRasterBand   **papoOverviews;

        papoOverviews = (GDALRasterBand **) CPLCalloc(sizeof(void*),128);

        for( iBand = 0; iBand < nBands && eErr == CE_None; iBand++ )
        {
            GDALRasterBand    *hSrcBand = papoBandList[iBand];
            GDALRasterBand    *hDstBand;
            int               nDstOverviews;

            hDstBand = hODS->GetRasterBand( iBand+1 );

            int bHasNoData;
            double noDataValue = hSrcBand->GetNoDataValue(&bHasNoData);
            if (bHasNoData)
                hDstBand->SetNoDataValue(noDataValue);

            papoOverviews[0] = hDstBand;
            nDstOverviews = hDstBand->GetOverviewCount() + 1;
            CPLAssert( nDstOverviews < 128 );
            nDstOverviews = MIN(128,nDstOverviews);

            for( int i = 0; i < nDstOverviews-1 && eErr == CE_None; i++ )
            {
                papoOverviews[i+1] = hDstBand->GetOverview(i);
                if (papoOverviews[i+1] == NULL)
                    eErr = CE_Failure;
                else
                {
                    if (bHasNoData)
                        papoOverviews[i+1]->SetNoDataValue(noDataValue);
                }
            }

            void         *pScaledProgressData;

            pScaledProgressData = 
                GDALCreateScaledProgress( iBand / (double) nBands, 
                                        (iBand+1) / (double) nBands,
                                        pfnProgress, pProgressData );

            if (eErr == CE_None)
                eErr = 
                    GDALRegenerateOverviews( (GDALRasterBandH) hSrcBand, 
                                        nDstOverviews, 
                                        (GDALRasterBandH *) papoOverviews, 
                                        pszResampling,
                                        GDALScaledProgress, 
                                        pScaledProgressData);

            GDALDestroyScaledProgress( pScaledProgressData );
        }

        CPLFree( papoOverviews );
    }

/* -------------------------------------------------------------------- */
/*      Cleanup                                                         */
/* -------------------------------------------------------------------- */
    if (eErr == CE_None)
        hODS->FlushCache();
    delete hODS;

    pfnProgress( 1.0, NULL, pProgressData );

    return eErr;
}
Example #20
0
CPLErr HFAAuxBuildOverviews( const char *pszOvrFilename,
                             GDALDataset *poParentDS,
                             GDALDataset **ppoODS,
                             int nBands, int *panBandList,
                             int nNewOverviews, int *panNewOverviewList,
                             const char *pszResampling,
                             GDALProgressFunc pfnProgress,
                             void *pProgressData )

{
/* ==================================================================== */
/*      If the .aux file doesn't exist yet then create it now.          */
/* ==================================================================== */
    if( *ppoODS == NULL )
    {
        GDALDataType eDT = GDT_Unknown;
/* -------------------------------------------------------------------- */
/*      Determine the band datatype, and verify that all bands are      */
/*      the same.                                                       */
/* -------------------------------------------------------------------- */
        int iBand;

        for( iBand = 0; iBand < nBands; iBand++ )
        {
            GDALRasterBand *poBand =
                poParentDS->GetRasterBand( panBandList[iBand] );

            if( iBand == 0 )
                eDT = poBand->GetRasterDataType();
            else
            {
                if( eDT != poBand->GetRasterDataType() )
                {
                    CPLError( CE_Failure, CPLE_NotSupported,
                              "HFAAuxBuildOverviews() doesn't support a mixture of band"
                              " data types." );
                    return CE_Failure;
                }
            }
        }

/* -------------------------------------------------------------------- */
/*      Create the HFA (.aux) file.  We create it with                  */
/*      COMPRESSED=YES so that no space will be allocated for the       */
/*      base band.                                                      */
/* -------------------------------------------------------------------- */
        GDALDriver *poHFADriver = (GDALDriver *) GDALGetDriverByName("HFA");
        if (poHFADriver == NULL)
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "HFA driver is unavailable." );
            return CE_Failure;
        }

        const char *apszOptions[4] = { "COMPRESSED=YES", "AUX=YES",
                                       NULL, NULL };

        CPLString osDepFileOpt = "DEPENDENT_FILE=";
        osDepFileOpt += CPLGetFilename(poParentDS->GetDescription());
        apszOptions[2] = osDepFileOpt.c_str();

        *ppoODS =
            poHFADriver->Create( pszOvrFilename,
                                 poParentDS->GetRasterXSize(),
                                 poParentDS->GetRasterYSize(),
                                 poParentDS->GetRasterCount(), eDT, (char **)apszOptions );

        if( *ppoODS == NULL )
            return CE_Failure;
    }

/* ==================================================================== */
/*      Create the layers.  We depend on the normal buildoverviews      */
/*      support for HFA to do this.  But we disable the internal        */
/*      computation of the imagery for these layers.                    */
/*                                                                      */
/*      We avoid regenerating the new layers here, because if we did    */
/*      it would use the base layer from the .aux file as the source    */
/*      data, and that is fake (all invalid tiles).                     */
/* ==================================================================== */
    CPLString oAdjustedResampling = "NO_REGEN:";
    oAdjustedResampling += pszResampling;

    CPLErr eErr =
        (*ppoODS)->BuildOverviews( oAdjustedResampling,
                                   nNewOverviews, panNewOverviewList,
                                   nBands, panBandList,
                                   pfnProgress, pProgressData );

    return eErr;
}
Example #21
0
CPLErr SDEDataset::ComputeRasterInfo() {
    long nSDEErr;
    SE_RASTERINFO raster;

    nSDEErr = SE_rasterinfo_create(&raster);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rasterinfo_create" );
        return CE_Fatal;
    }

    LONG nRasterColumnId = 0;

    nSDEErr = SE_rascolinfo_get_id( hRasterColumn,
                                    &nRasterColumnId);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rascolinfo_get_id" );
        return CE_Fatal;
    }

    nSDEErr = SE_raster_get_info_by_id( hConnection,
                                        nRasterColumnId,
                                        1,
                                        raster);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rascolinfo_get_id" );
        return CE_Fatal;
    }

    LONG nBandsRet;
    nSDEErr = SE_raster_get_bands(  hConnection,
                                    raster,
                                    &paohSDERasterBands,
                                    &nBandsRet);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_raster_get_bands" );
        return CE_Fatal;
    }

    nBands = nBandsRet;

    SE_RASBANDINFO band;

    // grab our other stuff from the first band and hope for the best
    band = paohSDERasterBands[0];

    LONG nXSRet, nYSRet;
    nSDEErr = SE_rasbandinfo_get_band_size( band, &nXSRet, &nYSRet );
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rasbandinfo_get_band_size" );
        return CE_Fatal;
    }

    nRasterXSize = nXSRet;
    nRasterYSize = nYSRet;

    SE_ENVELOPE extent;
    nSDEErr = SE_rasbandinfo_get_extent(band, &extent);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rasbandinfo_get_extent" );
        return CE_Fatal;
    }
    dfMinX = extent.minx;
    dfMinY = extent.miny;
    dfMaxX = extent.maxx;
    dfMaxY = extent.maxy;

    CPLDebug("SDERASTER", "minx: %.5f, miny: %.5f, maxx: %.5f, maxy: %.5f", dfMinX, dfMinY, dfMaxX, dfMaxY);

    // x0 roughly corresponds to dfMinX
    // y0 roughly corresponds to dfMaxY
    // They can be different than the extent parameters because
    // SDE uses offsets.  The following info is from Duarte Carreira
    // in relation to bug #2063 http://trac.osgeo.org/gdal/ticket/2063 :

    // Depending on how the data was loaded, the pixel width
    // or pixel height may include a pixel offset from the nearest
    // tile boundary. An offset will be indicated by aplus sign
    // "+" followed by a value. The value indicates the number
    // of pixels the nearest tile boundary is to the left of
    // the image for the x dimension or the number of
    // pixels the nearest tile boundary is above the image for
    // the y dimension. The offset information is only useful
    // for advanced application developers who need to know
    // where the image begins in relation to the underlying tile structure

    LFLOAT x0, y0;
    nSDEErr = SE_rasbandinfo_get_tile_origin(band, &x0, &y0);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rasbandinfo_get_tile_origin" );
        return CE_Fatal;
    }
    CPLDebug("SDERASTER", "Tile origin: %.5f, %.5f", x0, y0);

    // we also need to adjust dfMaxX and dfMinY otherwise the cell size will change
    dfMaxX = (x0-dfMinX) + dfMaxX;
    dfMinY = (y0-dfMaxY) + dfMinY;

    // adjust the bbox based on the tile origin.
    dfMinX = MIN(x0, dfMinX);
    dfMaxY = MAX(y0, dfMaxY);

    nSDEErr = SE_rasterattr_create(&hAttributes, false);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rasterattr_create" );
        return CE_Fatal;
    }

    // Grab the pointer for our member variable

    nSDEErr = SE_stream_create(hConnection, &hStream);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_stream_create" );
        return CE_Fatal;
    }


    for (int i=0; i < nBands; i++) {
        SetBand( i+1, new SDERasterBand( this, i+1, -1, &(paohSDERasterBands[i]) ));
    }

    GDALRasterBand* b = GetRasterBand(1);

    eDataType = b->GetRasterDataType();

    SE_rasterinfo_free(raster);

    return CE_None;
}
Example #22
0
CC_FILE_ERROR RasterGridFilter::loadFile(QString filename, ccHObject& container, bool alwaysDisplayLoadDialog/*=true*/, bool* coordinatesShiftEnabled/*=0*/, CCVector3d* coordinatesShift/*=0*/)
{
	GDALAllRegister();
	ccLog::PrintDebug("(GDAL drivers: %i)", GetGDALDriverManager()->GetDriverCount());

	GDALDataset* poDataset = static_cast<GDALDataset*>(GDALOpen( qPrintable(filename), GA_ReadOnly ));

	if( poDataset != NULL )
	{
		ccLog::Print(QString("Raster file: '%1'").arg(filename));
		ccLog::Print( "Driver: %s/%s",
			poDataset->GetDriver()->GetDescription(), 
			poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) );

		int rasterCount = poDataset->GetRasterCount();
		int rasterX = poDataset->GetRasterXSize();
		int rasterY = poDataset->GetRasterYSize();
		ccLog::Print( "Size is %dx%dx%d", rasterX, rasterY, rasterCount );

		ccPointCloud* pc = new ccPointCloud();
		if (!pc->reserve(static_cast<unsigned>(rasterX * rasterY)))
		{
			delete pc;
			return CC_FERR_NOT_ENOUGH_MEMORY;
		}

		if( poDataset->GetProjectionRef() != NULL )
			ccLog::Print( "Projection is `%s'", poDataset->GetProjectionRef() );

		double adfGeoTransform[6] = {	 0, //top left x
										 1, //w-e pixel resolution (can be negative)
										 0, //0
										 0, //top left y
										 0, //0
										 1  //n-s pixel resolution (can be negative)
		};

		if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None )
		{
			ccLog::Print( "Origin = (%.6f,%.6f)", adfGeoTransform[0], adfGeoTransform[3] );
			ccLog::Print( "Pixel Size = (%.6f,%.6f)", adfGeoTransform[1], adfGeoTransform[5] );
		}

		if (adfGeoTransform[1] == 0 || adfGeoTransform[5] == 0)
		{
			ccLog::Warning("Invalid pixel size! Forcing it to (1,1)");
			adfGeoTransform[1] = adfGeoTransform[5] = 1;
		}

		CCVector3d origin( adfGeoTransform[0], adfGeoTransform[3], 0.0 );
		CCVector3d Pshift(0,0,0);
		//check for 'big' coordinates
		{
			bool shiftAlreadyEnabled = (coordinatesShiftEnabled && *coordinatesShiftEnabled && coordinatesShift);
			if (shiftAlreadyEnabled)
				Pshift = *coordinatesShift;
			bool applyAll = false;
			if (	sizeof(PointCoordinateType) < 8
				&&	ccCoordinatesShiftManager::Handle(origin,0,alwaysDisplayLoadDialog,shiftAlreadyEnabled,Pshift,0,&applyAll))
			{
				pc->setGlobalShift(Pshift);
				ccLog::Warning("[RasterFilter::loadFile] Raster has been recentered! Translation: (%.2f,%.2f,%.2f)",Pshift.x,Pshift.y,Pshift.z);

				//we save coordinates shift information
				if (applyAll && coordinatesShiftEnabled && coordinatesShift)
				{
					*coordinatesShiftEnabled = true;
					*coordinatesShift = Pshift;
				}
			}
		}

		//create blank raster 'grid'
		{
			double z = 0.0 /*+ Pshift.z*/;
			for (int j=0; j<rasterY; ++j)
			{
				double y = adfGeoTransform[3] + static_cast<double>(j) * adfGeoTransform[5] + Pshift.y;
				CCVector3 P(	0,
								static_cast<PointCoordinateType>(y),
								static_cast<PointCoordinateType>(z));
				for (int i=0; i<rasterX; ++i)
				{
					double x = adfGeoTransform[0] + static_cast<double>(i) * adfGeoTransform[1] + Pshift.x;

					P.x = static_cast<PointCoordinateType>(x);
					pc->addPoint(P);
				}
			}

			QVariant xVar = QVariant::fromValue<int>(rasterX);
			QVariant yVar = QVariant::fromValue<int>(rasterY);
			pc->setMetaData("raster_width",xVar);
			pc->setMetaData("raster_height",yVar);
		}

		//fetch raster bands
		bool zRasterProcessed = false;
		unsigned zInvalid = 0;
		double zMinMax[2] = {0, 0};

		for (int i=1; i<=rasterCount; ++i)
		{
			ccLog::Print( "Reading band #%i", i);
			GDALRasterBand* poBand = poDataset->GetRasterBand(i);

			GDALColorInterp colorInterp = poBand->GetColorInterpretation();
			GDALDataType bandType = poBand->GetRasterDataType();

			int nBlockXSize, nBlockYSize;
			poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
			ccLog::Print( "Block=%dx%d Type=%s, ColorInterp=%s", nBlockXSize, nBlockYSize, GDALGetDataTypeName(poBand->GetRasterDataType()), GDALGetColorInterpretationName(colorInterp) );

			//fetching raster scan-line
			int nXSize = poBand->GetXSize();
			int nYSize = poBand->GetYSize();
			assert(nXSize == rasterX);
			assert(nYSize == rasterY);
			
			int bGotMin, bGotMax;
			double adfMinMax[2] = {0, 0};
			adfMinMax[0] = poBand->GetMinimum( &bGotMin );
			adfMinMax[1] = poBand->GetMaximum( &bGotMax );
			if (!bGotMin || !bGotMax )
				//DGM FIXME: if the file is corrupted (e.g. ASCII ArcGrid with missing rows) this method will enter in a infinite loop!
				GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax);
			ccLog::Print( "Min=%.3fd, Max=%.3f", adfMinMax[0], adfMinMax[1] );

			GDALColorTable* colTable = poBand->GetColorTable();
			if( colTable != NULL )
				printf( "Band has a color table with %d entries", colTable->GetColorEntryCount() );

			if( poBand->GetOverviewCount() > 0 )
				printf( "Band has %d overviews", poBand->GetOverviewCount() );

			if (colorInterp == GCI_Undefined && !zRasterProcessed/*&& !colTable*/) //probably heights?
			{
				zRasterProcessed = true;
				zMinMax[0] = adfMinMax[0];
				zMinMax[1] = adfMinMax[1];

				double* scanline = (double*) CPLMalloc(sizeof(double)*nXSize);
				//double* scanline = new double[nXSize];
				memset(scanline,0,sizeof(double)*nXSize);

				for (int j=0; j<nYSize; ++j)
				{
					if (poBand->RasterIO( GF_Read, /*xOffset=*/0, /*yOffset=*/j, /*xSize=*/nXSize, /*ySize=*/1, /*buffer=*/scanline, /*bufferSizeX=*/nXSize, /*bufferSizeY=*/1, /*bufferType=*/GDT_Float64, /*x_offset=*/0, /*y_offset=*/0 ) != CE_None)
					{
						delete pc;
						CPLFree(scanline);
						GDALClose(poDataset);
						return CC_FERR_READING;
					}

					for (int k=0; k<nXSize; ++k)
					{
						double z = static_cast<double>(scanline[k]) + Pshift[2];
						unsigned pointIndex = static_cast<unsigned>(k + j * rasterX);
						if (pointIndex <= pc->size())
						{
							if (z < zMinMax[0] || z > zMinMax[1])
							{
								z = zMinMax[0] - 1.0;
								++zInvalid;
							}
							const_cast<CCVector3*>(pc->getPoint(pointIndex))->z = static_cast<PointCoordinateType>(z);
						}
					}
				}

				//update bounding-box
				pc->invalidateBoundingBox();

				if (scanline)
					CPLFree(scanline);
				scanline = 0;
			}
			else //colors
			{
				bool isRGB = false;
				bool isScalar = false;
				bool isPalette = false;
				
				switch(colorInterp)
				{
				case GCI_Undefined:
					isScalar = true;
					break;
				case GCI_PaletteIndex:
					isPalette = true;
					break;
				case GCI_RedBand:
				case GCI_GreenBand:
				case GCI_BlueBand:
					isRGB = true;
					break;
				case GCI_AlphaBand:
					if (adfMinMax[0] != adfMinMax[1])
						isScalar = true;
					else
						ccLog::Warning(QString("Alpha band ignored as it has a unique value (%1)").arg(adfMinMax[0]));
					break;
				default:
					isScalar = true;
					break;
				}


				if (isRGB || isPalette)
				{
					//first check that a palette exists if the band is a palette index
					if (isPalette && !colTable)
					{
						ccLog::Warning(QString("Band is declared as a '%1' but no palette is associated!").arg(GDALGetColorInterpretationName(colorInterp)));
						isPalette = false;
					}
					else
					{
						//instantiate memory for RBG colors if necessary
						if (!pc->hasColors() && !pc->setRGBColor(MAX_COLOR_COMP,MAX_COLOR_COMP,MAX_COLOR_COMP))
						{
							ccLog::Warning(QString("Failed to instantiate memory for storing color band '%1'!").arg(GDALGetColorInterpretationName(colorInterp)));
						}
						else
						{
							assert(bandType <= GDT_Int32);

							int* colIndexes = (int*) CPLMalloc(sizeof(int)*nXSize);
							//double* scanline = new double[nXSize];
							memset(colIndexes,0,sizeof(int)*nXSize);

							for (int j=0; j<nYSize; ++j)
							{
								if (poBand->RasterIO( GF_Read, /*xOffset=*/0, /*yOffset=*/j, /*xSize=*/nXSize, /*ySize=*/1, /*buffer=*/colIndexes, /*bufferSizeX=*/nXSize, /*bufferSizeY=*/1, /*bufferType=*/GDT_Int32, /*x_offset=*/0, /*y_offset=*/0 ) != CE_None)
								{
									CPLFree(colIndexes);
									delete pc;
									return CC_FERR_READING;
								}

								for (int k=0; k<nXSize; ++k)
								{
									unsigned pointIndex = static_cast<unsigned>(k + j * rasterX);
									if (pointIndex <= pc->size())
									{
										colorType* C = const_cast<colorType*>(pc->getPointColor(pointIndex));

										switch(colorInterp)
										{
										case GCI_PaletteIndex:
											assert(colTable);
											{
												GDALColorEntry col;
												colTable->GetColorEntryAsRGB(colIndexes[k],&col);
												C[0] = static_cast<colorType>(col.c1 & MAX_COLOR_COMP);
												C[1] = static_cast<colorType>(col.c2 & MAX_COLOR_COMP);
												C[2] = static_cast<colorType>(col.c3 & MAX_COLOR_COMP);
											}
											break;

										case GCI_RedBand:
											C[0] = static_cast<colorType>(colIndexes[k] & MAX_COLOR_COMP);
											break;
										case GCI_GreenBand:
											C[1] = static_cast<colorType>(colIndexes[k] & MAX_COLOR_COMP);
											break;
										case GCI_BlueBand:
											C[2] = static_cast<colorType>(colIndexes[k] & MAX_COLOR_COMP);
											break;

										default:
											assert(false);
											break;
										}
									}
								}
							}

							if (colIndexes)
								CPLFree(colIndexes);
							colIndexes = 0;

							pc->showColors(true);
						}
					}
				}
				else if (isScalar)
				{
					ccScalarField* sf = new ccScalarField(GDALGetColorInterpretationName(colorInterp));
					if (!sf->resize(pc->size(),true,NAN_VALUE))
					{
						ccLog::Warning(QString("Failed to instantiate memory for storing '%1' as a scalar field!").arg(sf->getName()));
						sf->release();
						sf = 0;
					}
					else
					{
						double* colValues = (double*) CPLMalloc(sizeof(double)*nXSize);
						//double* scanline = new double[nXSize];
						memset(colValues,0,sizeof(double)*nXSize);

						for (int j=0; j<nYSize; ++j)
						{
							if (poBand->RasterIO( GF_Read, /*xOffset=*/0, /*yOffset=*/j, /*xSize=*/nXSize, /*ySize=*/1, /*buffer=*/colValues, /*bufferSizeX=*/nXSize, /*bufferSizeY=*/1, /*bufferType=*/GDT_Float64, /*x_offset=*/0, /*y_offset=*/0 ) != CE_None)
							{
								CPLFree(colValues);
								delete pc;
								return CC_FERR_READING;
							}

							for (int k=0; k<nXSize; ++k)
							{
								unsigned pointIndex = static_cast<unsigned>(k + j * rasterX);
								if (pointIndex <= pc->size())
								{
									ScalarType s = static_cast<ScalarType>(colValues[k]);
									sf->setValue(pointIndex,s);
								}
							}
						}

						if (colValues)
							CPLFree(colValues);
						colValues = 0;

						sf->computeMinAndMax();
						pc->addScalarField(sf);
						if (pc->getNumberOfScalarFields() == 1)
							pc->setCurrentDisplayedScalarField(0);
						pc->showSF(true);
					}
				}
			}
		}

		if (pc)
		{
			if (!zRasterProcessed)
			{
				ccLog::Warning("Raster has no height (Z) information: you can convert one of its scalar fields to Z with 'Edit > Scalar Fields > Set SF as coordinate(s)'");
			}
			else if (zInvalid != 0 && zInvalid < pc->size())
			{
				//shall we remove the points with invalid heights?
				if (QMessageBox::question(0,"Remove NaN points?","This raster has pixels with invalid heights. Shall we remove them?",QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
				{
					CCLib::ReferenceCloud validPoints(pc);
					unsigned count = pc->size();
					bool error = true;
					if (validPoints.reserve(count-zInvalid))
					{
						for (unsigned i=0; i<count; ++i)
						{
							if (pc->getPoint(i)->z >= zMinMax[0])
								validPoints.addPointIndex(i);
						}

						if (validPoints.size() > 0)
						{
							validPoints.resize(validPoints.size());
							ccPointCloud* newPC = pc->partialClone(&validPoints);
							if (newPC)
							{
								delete pc;
								pc = newPC;
								error = false;
							}
						}
						else
						{
							assert(false);
						}
					}

					if (error)
					{
						ccLog::Error("Not enough memory to remove the points with invalid heights!");
					}
				}
			}
			container.addChild(pc);
		}

		GDALClose(poDataset);
	}
	else
	{
		return CC_FERR_UNKNOWN_FILE;
	}

	return CC_FERR_NO_ERROR;
}
std::tuple<boost::shared_ptr<Map_Matrix<DataFormat> >, std::string, GeoTransform>  read_in_map(fs::path file_path, GDALDataType data_type, const bool doCategorise) throw(std::runtime_error)
{

    std::string projection;
    GeoTransform transformation;
    GDALDriver driver;
    
	//Check that the file name is valid
	if (!(fs::is_regular_file(file_path)))
	{
		throw std::runtime_error("Input file is not a regular file");
	}	

	// Get GDAL to open the file - code is based on the tutorial at http://www.gdal.org/gdal_tutorial.html
	GDALDataset *poDataset;
	GDALAllRegister(); //This registers all availble raster file formats for use with this utility. How neat is that. We can input any GDAL supported rater file format.

	//Open the Raster by calling GDALOpen. http://www.gdal.org/gdal_8h.html#a6836f0f810396c5e45622c8ef94624d4
	//char pszfilename[] = file_path.c_str(); //Set this to the file name, as GDALOpen requires the standard C char pointer as function parameter.
	poDataset = (GDALDataset *) GDALOpen (file_path.string().c_str(), GA_ReadOnly);
	if (poDataset == NULL)
	{
		throw std::runtime_error("Unable to open file");
	}
	
//	Print some general information about the raster
	double        adfGeoTransform[6]; //An array of doubles that will be used to save information about the raster - where the origin is, what the raster pizel size is.
    
    
    printf( "Driver: %s/%s\n",
            poDataset->GetDriver()->GetDescription(),
            poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) );

    printf( "Size is %dx%dx%d\n", 
            poDataset->GetRasterXSize(), poDataset->GetRasterYSize(),
            poDataset->GetRasterCount() );

    if( poDataset->GetProjectionRef()  != NULL )
    {
        printf( "Projection is `%s'\n", poDataset->GetProjectionRef() );
        projection = poDataset->GetProjectionRef();
    }

    if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None )
    {
        printf( "Origin = (%.6f,%.6f)\n",
                adfGeoTransform[0], adfGeoTransform[3] );

        printf( "Pixel Size = (%.6f,%.6f)\n",
                adfGeoTransform[1], adfGeoTransform[5] );
        
        transformation.x_origin = adfGeoTransform[0];
        transformation.pixel_width = adfGeoTransform[1];
        transformation.x_line_space = adfGeoTransform[2];
        transformation.y_origin = adfGeoTransform[3];
        transformation.pixel_height = adfGeoTransform[4];
        transformation.y_line_space = adfGeoTransform[5];
        
    }


	/// Some raster file formats allow many layers of data (called a 'band', with each having the same pixel size and origin location and spatial extent). We will get the data for the first layer into a Boost Array.
	//Get the data from the first band, 
	// TODO implement method with input to specify what band.
	    GDALRasterBand  *poBand;
        int             nBlockXSize, nBlockYSize;
        int             bGotMin, bGotMax;
        double          adfMinMax[2];
        
        poBand = poDataset->GetRasterBand( 1 );
        poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
        printf( "Block=%dx%d Type=%s, ColorInterp=%s\n",
                nBlockXSize, nBlockYSize,
                GDALGetDataTypeName(poBand->GetRasterDataType()),
                GDALGetColorInterpretationName(
                    poBand->GetColorInterpretation()) );

        adfMinMax[0] = poBand->GetMinimum( &bGotMin );
        adfMinMax[1] = poBand->GetMaximum( &bGotMax );
        if( ! (bGotMin && bGotMax) )
            GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax);

        printf( "Min=%.3fd, Max=%.3f\n", adfMinMax[0], adfMinMax[1] );
        
        if( poBand->GetOverviewCount() > 0 )
            printf( "Band has %d overviews.\n", poBand->GetOverviewCount() );

        if( poBand->GetColorTable() != NULL )
            printf( "Band has a color table with %d entries.\n", 
                     poBand->GetColorTable()->GetColorEntryCount() );

		DataFormat * pafScanline;
        int   nXSize = poBand->GetXSize();
		int   nYSize = poBand->GetYSize();
		boost::shared_ptr<Map_Matrix<DataFormat> > in_map(new Map_Matrix<DataFormat>(nYSize, nXSize));
		//get a c array of this size and read into this.
		
		
		//pafScanline = new DataFormat[nXSize];
		//for (int i = 0; i < nYSize; i++) //rows
		//{
		//	poBand->RasterIO(GF_Read, 0, i, nXSize, 1,
		//		pafScanline, nXSize, 1, data_type,
		//		0, 0);
		//	for (int j = 0; j < nXSize; j++) //cols
		//	{
		//		in_map->Get(i, j) = pafScanline[j];
		//	}
		//}
    
        //get a c array of this size and read into this.
        pafScanline = new DataFormat[nXSize * nYSize];
        //pafScanline = (float *) CPLMalloc(sizeof(float)*nXSize);
        poBand->RasterIO( GF_Read, 0, 0, nXSize, nYSize, 
			pafScanline, nXSize, nYSize, data_type,
                          0, 0 );
    
        //Copy into Map_Matrix.
        int pafIterator = 0;
		// Note: Map Matrixes indexes are in opposite order to C arrays. e.g. map matrix is indexed by (row, Col) which is (y, x) and c matrices are done by (x, y) which is (Col, Row)
        
        //for (int i = 0; i < nXSize; i++)
        //{
        //    for(int j = 0; j < nYSize; j++)
        //    {
        //        in_map->Get(j, i) = pafScanline[pafIterator];
        //        pafIterator++;
        //    }
        //}		
		for (int i = 0; i < nYSize; i++) //rows
		{
			for (int j = 0; j < nXSize; j++) //cols
			{
				in_map->Get(i, j) = pafScanline[pafIterator];
				pafIterator++;
			}
		}


    
    //free the c array storage
    delete pafScanline;
    int pbsuccess; // can be used with get no data value
    in_map->SetNoDataValue(poBand->GetNoDataValue(&pbsuccess));
    //This creates a list (map?) listing all the unique values contained in the raster.
	if (doCategorise) in_map->updateCategories();

    
	//Close GDAL, freeing the memory GDAL is using
	GDALClose( (GDALDatasetH)poDataset);

    return (std::make_tuple(in_map, projection, transformation));
}
Example #24
0
static GDALDataset *
VRTCreateCopy( const char * pszFilename,
               GDALDataset *poSrcDS,
               int /* bStrict */,
               char ** /* papszOptions */,
               GDALProgressFunc /* pfnProgress */,
               void * /* pProgressData */ )
{
    CPLAssert( NULL != poSrcDS );

/* -------------------------------------------------------------------- */
/*      If the source dataset is a virtual dataset then just write      */
/*      it to disk as a special case to avoid extra layers of           */
/*      indirection.                                                    */
/* -------------------------------------------------------------------- */
    if( poSrcDS->GetDriver() != NULL &&
        EQUAL(poSrcDS->GetDriver()->GetDescription(),"VRT") )
    {

    /* -------------------------------------------------------------------- */
    /*      Convert tree to a single block of XML text.                     */
    /* -------------------------------------------------------------------- */
        char *pszVRTPath = CPLStrdup(CPLGetPath(pszFilename));
        reinterpret_cast<VRTDataset *>(
            poSrcDS )->UnsetPreservedRelativeFilenames();
        CPLXMLNode *psDSTree = reinterpret_cast<VRTDataset *>(
            poSrcDS )->SerializeToXML( pszVRTPath );

        char *pszXML = CPLSerializeXMLTree( psDSTree );

        CPLDestroyXMLNode( psDSTree );

        CPLFree( pszVRTPath );

    /* -------------------------------------------------------------------- */
    /*      Write to disk.                                                  */
    /* -------------------------------------------------------------------- */
        GDALDataset* pCopyDS = NULL;

        if( 0 != strlen( pszFilename ) )
        {
            VSILFILE *fpVRT = VSIFOpenL( pszFilename, "wb" );
            if( fpVRT == NULL )
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                         "Cannot create %s", pszFilename);
                CPLFree( pszXML );
                return NULL;
            }

            bool bRet = VSIFWriteL( pszXML, strlen(pszXML), 1, fpVRT ) > 0;
            if( VSIFCloseL( fpVRT ) != 0 )
                bRet = false;

            if( bRet )
                pCopyDS = reinterpret_cast<GDALDataset *>(
                    GDALOpen( pszFilename, GA_Update ) );
        }
        else
        {
            /* No destination file is given, so pass serialized XML directly. */
            pCopyDS = reinterpret_cast<GDALDataset *>(
                GDALOpen( pszXML, GA_Update ) );
        }

        CPLFree( pszXML );

        return pCopyDS;
    }

/* -------------------------------------------------------------------- */
/*      Create the virtual dataset.                                     */
/* -------------------------------------------------------------------- */
    VRTDataset *poVRTDS = reinterpret_cast<VRTDataset *>(
        VRTDataset::Create( pszFilename,
                            poSrcDS->GetRasterXSize(),
                            poSrcDS->GetRasterYSize(),
                            0, GDT_Byte, NULL ) );
    if( poVRTDS == NULL )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Do we have a geotransform?                                      */
/* -------------------------------------------------------------------- */
    double adfGeoTransform[6] = { 0.0 };

    if( poSrcDS->GetGeoTransform( adfGeoTransform ) == CE_None )
    {
        poVRTDS->SetGeoTransform( adfGeoTransform );
    }

/* -------------------------------------------------------------------- */
/*      Copy projection                                                 */
/* -------------------------------------------------------------------- */
    poVRTDS->SetProjection( poSrcDS->GetProjectionRef() );

/* -------------------------------------------------------------------- */
/*      Emit dataset level metadata.                                    */
/* -------------------------------------------------------------------- */
    poVRTDS->SetMetadata( poSrcDS->GetMetadata() );

/* -------------------------------------------------------------------- */
/*      Copy any special domains that should be transportable.          */
/* -------------------------------------------------------------------- */
    char **papszMD = poSrcDS->GetMetadata( "RPC" );
    if( papszMD )
        poVRTDS->SetMetadata( papszMD, "RPC" );

    papszMD = poSrcDS->GetMetadata( "IMD" );
    if( papszMD )
        poVRTDS->SetMetadata( papszMD, "IMD" );

    papszMD = poSrcDS->GetMetadata( "GEOLOCATION" );
    if( papszMD )
        poVRTDS->SetMetadata( papszMD, "GEOLOCATION" );

/* -------------------------------------------------------------------- */
/*      GCPs                                                            */
/* -------------------------------------------------------------------- */
    if( poSrcDS->GetGCPCount() > 0 )
    {
        poVRTDS->SetGCPs( poSrcDS->GetGCPCount(),
                          poSrcDS->GetGCPs(),
                          poSrcDS->GetGCPProjection() );
    }

/* -------------------------------------------------------------------- */
/*      Loop over all the bands.                                        */
/* -------------------------------------------------------------------- */
    for( int iBand = 0; iBand < poSrcDS->GetRasterCount(); iBand++ )
    {
        GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( iBand+1 );

/* -------------------------------------------------------------------- */
/*      Create the band with the appropriate band type.                 */
/* -------------------------------------------------------------------- */
        poVRTDS->AddBand( poSrcBand->GetRasterDataType(), NULL );

        VRTSourcedRasterBand *poVRTBand
            = reinterpret_cast<VRTSourcedRasterBand *>(
                poVRTDS->GetRasterBand( iBand+1 ) );

/* -------------------------------------------------------------------- */
/*      Setup source mapping.                                           */
/* -------------------------------------------------------------------- */
        poVRTBand->AddSimpleSource( poSrcBand );

/* -------------------------------------------------------------------- */
/*      Emit various band level metadata.                               */
/* -------------------------------------------------------------------- */
        poVRTBand->CopyCommonInfoFrom( poSrcBand );

/* -------------------------------------------------------------------- */
/*      Add specific mask band.                                         */
/* -------------------------------------------------------------------- */
        if( (poSrcBand->GetMaskFlags()
              & (GMF_PER_DATASET | GMF_ALL_VALID | GMF_NODATA)) == 0)
        {
            VRTSourcedRasterBand* poVRTMaskBand = new VRTSourcedRasterBand(
                poVRTDS, 0,
                poSrcBand->GetMaskBand()->GetRasterDataType(),
                poSrcDS->GetRasterXSize(), poSrcDS->GetRasterYSize());
            poVRTMaskBand->AddMaskBandSource( poSrcBand );
            poVRTBand->SetMaskBand( poVRTMaskBand );
        }
    }

/* -------------------------------------------------------------------- */
/*      Add dataset mask band                                           */
/* -------------------------------------------------------------------- */
    if( poSrcDS->GetRasterCount() != 0 &&
        poSrcDS->GetRasterBand(1) != NULL &&
        poSrcDS->GetRasterBand(1)->GetMaskFlags() == GMF_PER_DATASET )
    {
        GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand(1);
        VRTSourcedRasterBand* poVRTMaskBand = new VRTSourcedRasterBand(
            poVRTDS, 0,
            poSrcBand->GetMaskBand()->GetRasterDataType(),
            poSrcDS->GetRasterXSize(), poSrcDS->GetRasterYSize() );
        poVRTMaskBand->AddMaskBandSource( poSrcBand );
        poVRTDS->SetMaskBand( poVRTMaskBand );
    }

    poVRTDS->FlushCache();

    return poVRTDS;
}
Example #25
0
void readFrames( int argc, char* argv[] )
{
  pfs::DOMIO pfsio;

  bool verbose = false;
  
  // Parse command line parameters
  static struct option cmdLineOptions[] = {
    { "help", no_argument, NULL, 'h' },
    { "verbose", no_argument, NULL, 'v' },
    { NULL, 0, NULL, 0 }
  };
  static const char optstring[] = "hv";
    
  pfs::FrameFileIterator it( argc, argv, "rb", NULL, NULL,
    optstring, cmdLineOptions );
    
  int optionIndex = 0;
  while( 1 ) {
    int c = getopt_long (argc, argv, optstring, cmdLineOptions, &optionIndex);
    if( c == -1 ) break;
    switch( c ) {
    case 'h':
      printHelp();
      throw QuietException();
    case 'v':
      verbose = true;
      break;
    case '?':
      throw QuietException();
    case ':':
      throw QuietException();
    }
  }

  GDALAllRegister();

  GDALDataset *poDataset;
  GDALRasterBand *poBand;
  double adfGeoTransform[6];
  size_t nBlockXSize, nBlockYSize, nBands;
  int bGotMin, bGotMax;
  double adfMinMax[2];
  float *pafScanline;

  while( true ) {
    pfs::FrameFile ff = it.getNextFrameFile();
    if( ff.fh == NULL ) break; // No more frames
    it.closeFrameFile( ff );

    VERBOSE_STR << "reading file '" << ff.fileName << "'" << std::endl;
    if( !( poDataset = (GDALDataset *) GDALOpen( ff.fileName, GA_ReadOnly ) ) ) {
      std::cerr << "input does not seem to be in a format supported by GDAL" << std::endl;
      throw QuietException();
    }
    VERBOSE_STR << "GDAL driver: " << poDataset->GetDriver()->GetDescription()
	<< " / " << poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) << std::endl;
    nBlockXSize = poDataset->GetRasterXSize();
    nBlockYSize = poDataset->GetRasterYSize();
    nBands = poDataset->GetRasterCount();
    VERBOSE_STR << "Data size " << nBlockXSize << "x" << nBlockYSize << "x" << nBands << std::endl;
    if( poDataset->GetProjectionRef() ) {
      VERBOSE_STR << "Projection " << poDataset->GetProjectionRef() << std::endl;
    }
    if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None ) {
      VERBOSE_STR << "Origin = (" << adfGeoTransform[0] << ", " << adfGeoTransform[3] << ")" << std::endl;
      VERBOSE_STR << "Pixel Size = (" << adfGeoTransform[1] << ", " << adfGeoTransform[5] << ")" << std::endl;
    }

    if( nBlockXSize==0  || nBlockYSize==0 
	    || ( SIZE_MAX / nBlockYSize < nBlockXSize ) 
	    || ( SIZE_MAX / (nBlockXSize * nBlockYSize ) < 4 ) ) {
      std::cerr << "input data has invalid size" << std::endl;
      throw QuietException();
    }
    if( !(pafScanline = (float *) CPLMalloc( sizeof(float) * nBlockXSize ) ) ) {
      std::cerr << "not enough memory" << std::endl;
      throw QuietException();
    }

    pfs::Frame *frame = pfsio.createFrame( nBlockXSize, nBlockYSize );
    pfs::Channel *C[nBands];
    char channel_name[32];

    frame->getTags()->setString( "X-GDAL_DRIVER_SHORTNAME", poDataset->GetDriver()->GetDescription() );
    frame->getTags()->setString( "X-GDAL_DRIVER_LONGNAME", poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) );
    frame->getTags()->setString( "X-PROJECTION", poDataset->GetProjectionRef() );
    if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None ) {
      frame->getTags()->setString( "X-ORIGIN_X", stringify(adfGeoTransform[0]).c_str() );
      frame->getTags()->setString( "X-ORIGIN_Y", stringify(adfGeoTransform[3]).c_str() );
      frame->getTags()->setString( "X-PIXEL_WIDTH", stringify(adfGeoTransform[1]).c_str() );
      frame->getTags()->setString( "X-PIXEL_HEIGHT", stringify(adfGeoTransform[5]).c_str() );
    }

    for ( size_t band = 1; band <= nBands; band++) {
      size_t nBandXSize, nBandYSize;
      VERBOSE_STR << "Band " << band << ": " << std::endl;
      snprintf( channel_name, 32, "X-GDAL%zu", band );
      C[band - 1] = frame->createChannel( channel_name );
      poBand = poDataset->GetRasterBand( band );
      nBandXSize = poBand->GetXSize();
      nBandYSize = poBand->GetYSize();
      VERBOSE_STR << "    " << nBandXSize << "x" << nBandYSize << std::endl;
      if( nBandXSize != (int)nBlockXSize || nBandYSize != (int)nBlockYSize ) {
        std::cerr << "data in band " << band << " has different size" << std::endl;
        throw QuietException();
      }
      VERBOSE_STR << "    Type " << GDALGetDataTypeName( poBand->GetRasterDataType() ) << ", "
	  << "Color Interpretation " << GDALGetColorInterpretationName( poBand->GetColorInterpretation() ) << std::endl;
      adfMinMax[0] = poBand->GetMinimum( &bGotMin );
      adfMinMax[1] = poBand->GetMaximum( &bGotMax );
      if( ! (bGotMin && bGotMax) ) {
      	  GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax);
      }
      VERBOSE_STR << "    Min " << adfMinMax[0] << ", Max " << adfMinMax[1] << std::endl;
      C[band - 1]->getTags()->setString( "X-TYPE", 
	      GDALGetDataTypeName( poBand->GetRasterDataType() ) );
      C[band - 1]->getTags()->setString( "X-COLOR_INTERPRETATION", 
	      GDALGetColorInterpretationName( poBand->GetColorInterpretation() ) );
      C[band - 1]->getTags()->setString( "X-MIN", stringify(adfMinMax[0]).c_str() );
      C[band - 1]->getTags()->setString( "X-MAX", stringify(adfMinMax[1]).c_str() );
      for( size_t y = 0; y < nBlockYSize; y++ ) {
        if( poBand->RasterIO( GF_Read, 0, y, nBlockXSize, 1, pafScanline, 
		    nBlockXSize, 1, GDT_Float32, 0, 0) != CE_None ) {
          std::cerr << "input error" << std::endl;
          throw QuietException();
	}
	memcpy( C[band - 1]->getRawData() + y * nBlockXSize, pafScanline, nBlockXSize * sizeof(float) );
      }
    }
    CPLFree( pafScanline );
    GDALClose( poDataset );

    const char *fileNameTag = strcmp( "-", ff.fileName )==0 ? "stdin" : ff.fileName;
    frame->getTags()->setString( "FILE_NAME", fileNameTag );
        
    pfsio.writeFrame( frame, stdout );
    pfsio.freeFrame( frame );
  }
}
Example #26
0
feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
{
    feature_ptr feature = feature_factory::create(ctx_,1);
    int raster_has_nodata = 0;
    double raster_nodata = 0;
    GDALRasterBand * red = 0;
    GDALRasterBand * green = 0;
    GDALRasterBand * blue = 0;
    GDALRasterBand * alpha = 0;
    GDALRasterBand * grey = 0;
    CPLErr raster_io_error = CE_None;

    /*
#ifdef MAPNIK_LOG
      double tr[6];
      dataset_.GetGeoTransform(tr);

      const double dx = tr[1];
      const double dy = tr[5];
      MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: dx_=" << dx_ << " dx=" << dx << " dy_=" << dy_ << "dy=" << dy;
#endif
    */

    view_transform t(raster_width_, raster_height_, raster_extent_, 0, 0);
    box2d<double> intersect = raster_extent_.intersect(q.get_bbox());
    box2d<double> box = t.forward(intersect);

    //size of resized output pixel in source image domain
    double margin_x = 1.0 / (std::fabs(dx_) * std::get<0>(q.resolution()));
    double margin_y = 1.0 / (std::fabs(dy_) * std::get<1>(q.resolution()));
    if (margin_x < 1)
    {
        margin_x = 1.0;
    }
    if (margin_y < 1)
    {
        margin_y = 1.0;
    }

    //select minimum raster containing whole box
    int x_off = rint(box.minx() - margin_x);
    int y_off = rint(box.miny() - margin_y);
    int end_x = rint(box.maxx() + margin_x);
    int end_y = rint(box.maxy() + margin_y);

    //clip to available data
    if (x_off < 0)
    {
        x_off = 0;
    }
    if (y_off < 0)
    {
        y_off = 0;
    }
    if (end_x > (int)raster_width_)
    {
        end_x = raster_width_;
    }
    if (end_y > (int)raster_height_)
    {
        end_y = raster_height_;
    }
    int width = end_x - x_off;
    int height = end_y - y_off;

    // don't process almost invisible data
    if (box.width() < 0.5)
    {
        width = 0;
    }
    if (box.height() < 0.5)
    {
        height = 0;
    }

    //calculate actual box2d of returned raster
    box2d<double> feature_raster_extent(x_off, y_off, x_off + width, y_off + height);
    intersect = t.backward(feature_raster_extent);

    MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Raster extent=" << raster_extent_;
    MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: View extent=" << intersect;
    MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Query resolution=" << std::get<0>(q.resolution()) << "," << std::get<1>(q.resolution());
    MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: StartX=" << x_off << " StartY=" << y_off << " Width=" << width << " Height=" << height;

    if (width > 0 && height > 0)
    {
        double width_res = std::get<0>(q.resolution());
        double height_res = std::get<1>(q.resolution());
        int im_width = int(width_res * intersect.width() + 0.5);
        int im_height = int(height_res * intersect.height() + 0.5);

        double filter_factor = q.get_filter_factor();
        im_width = int(im_width * filter_factor + 0.5);
        im_height = int(im_height * filter_factor + 0.5);

        // case where we need to avoid upsampling so that the
        // image can be later scaled within raster_symbolizer
        if (im_width >= width || im_height >= height)
        {
            im_width = width;
            im_height = height;
        }

        if (im_width > 0 && im_height > 0)
        {
            MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Image Size=(" << im_width << "," << im_height << ")";
            MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Reading band=" << band_;
            if (band_ > 0) // we are querying a single band
            {
                GDALRasterBand * band = dataset_.GetRasterBand(band_);
                if (band_ > nbands_)
                {
                    std::ostringstream s;
                    s << "GDAL Plugin: " << band_ << " is an invalid band, dataset only has " << nbands_ << "bands";
                    throw datasource_exception(s.str());
                }
                GDALDataType band_type = band->GetRasterDataType();
                switch (band_type)
                {
                case GDT_Byte:
                {
                    mapnik::image_gray8 image(im_width, im_height);
                    image.set(std::numeric_limits<std::uint8_t>::max());
                    raster_nodata = band->GetNoDataValue(&raster_has_nodata);
                    raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
                                                     image.data(), image.width(), image.height(),
                                                     GDT_Byte, 0, 0);
                    if (raster_io_error == CE_Failure)
                    {
                        throw datasource_exception(CPLGetLastErrorMsg());
                    }
                    mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor);
                    // set nodata value to be used in raster colorizer
                    if (nodata_value_) raster->set_nodata(*nodata_value_);
                    else raster->set_nodata(raster_nodata);
                    feature->set_raster(raster);
                    break;
                }
                case GDT_Float64:
                case GDT_Float32:
                {
                    mapnik::image_gray32f image(im_width, im_height);
                    image.set(std::numeric_limits<float>::max());
                    raster_nodata = band->GetNoDataValue(&raster_has_nodata);
                    raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
                                                     image.data(), image.width(), image.height(),
                                                     GDT_Float32, 0, 0);
                    if (raster_io_error == CE_Failure)
                    {
                        throw datasource_exception(CPLGetLastErrorMsg());
                    }
                    mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor);
                    // set nodata value to be used in raster colorizer
                    if (nodata_value_) raster->set_nodata(*nodata_value_);
                    else raster->set_nodata(raster_nodata);
                    feature->set_raster(raster);
                    break;
                }
                case GDT_UInt16:
                {
                    mapnik::image_gray16 image(im_width, im_height);
                    image.set(std::numeric_limits<std::uint16_t>::max());
                    raster_nodata = band->GetNoDataValue(&raster_has_nodata);
                    raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
                                                     image.data(), image.width(), image.height(),
                                                     GDT_UInt16, 0, 0);
                    if (raster_io_error == CE_Failure)
                    {
                        throw datasource_exception(CPLGetLastErrorMsg());
                    }
                    mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor);
                    // set nodata value to be used in raster colorizer
                    if (nodata_value_) raster->set_nodata(*nodata_value_);
                    else raster->set_nodata(raster_nodata);
                    feature->set_raster(raster);
                    break;
                }
                default:
                case GDT_Int16:
                {
                    mapnik::image_gray16s image(im_width, im_height);
                    image.set(std::numeric_limits<std::int16_t>::max());
                    raster_nodata = band->GetNoDataValue(&raster_has_nodata);
                    raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
                                                     image.data(), image.width(), image.height(),
                                                     GDT_Int16, 0, 0);
                    if (raster_io_error == CE_Failure)
                    {
                        throw datasource_exception(CPLGetLastErrorMsg());
                    }
                    mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor);
                    // set nodata value to be used in raster colorizer
                    if (nodata_value_) raster->set_nodata(*nodata_value_);
                    else raster->set_nodata(raster_nodata);
                    feature->set_raster(raster);
                    break;
                }
                }
            }
            else // working with all bands
            {
                mapnik::image_rgba8 image(im_width, im_height);
                image.set(std::numeric_limits<std::uint32_t>::max());
                for (int i = 0; i < nbands_; ++i)
                {
                    GDALRasterBand * band = dataset_.GetRasterBand(i + 1);
#ifdef MAPNIK_LOG
                    get_overview_meta(band);
#endif
                    GDALColorInterp color_interp = band->GetColorInterpretation();
                    switch (color_interp)
                    {
                    case GCI_RedBand:
                        red = band;
                        MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found red band";
                        break;
                    case GCI_GreenBand:
                        green = band;
                        MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found green band";
                        break;
                    case GCI_BlueBand:
                        blue = band;
                        MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found blue band";
                        break;
                    case GCI_AlphaBand:
                        alpha = band;
                        MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found alpha band";
                        break;
                    case GCI_GrayIndex:
                        grey = band;
                        MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found gray band";
                        break;
                    case GCI_PaletteIndex:
                    {
                        grey = band;
#ifdef MAPNIK_LOG
                        MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found gray band, and colortable...";
                        GDALColorTable *color_table = band->GetColorTable();

                        if (color_table)
                        {
                            int count = color_table->GetColorEntryCount();
                            MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Color Table count=" << count;

                            for (int j = 0; j < count; j++)
                            {
                                const GDALColorEntry *ce = color_table->GetColorEntry (j);
                                if (! ce) continue;
                                MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Color entry RGB=" << ce->c1 << "," <<ce->c2 << "," << ce->c3;
                            }
                        }
#endif
                        break;
                    }
                    case GCI_Undefined:
#if GDAL_VERSION_NUM <= 1730
                        if (nbands_ == 4)
                        {
                            MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found undefined band (assumming alpha band)";
                            alpha = band;
                        }
                        else
                        {
                            MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found undefined band (assumming gray band)";
                            grey = band;
                        }
#else
                        MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found undefined band (assumming gray band)";
                        grey = band;
#endif
                        break;
                    default:
                        MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Band type unknown!";
                        break;
                    }
                }
                if (red && green && blue)
                {
                    MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Processing rgb bands...";
                    raster_nodata = red->GetNoDataValue(&raster_has_nodata);
                    GDALColorTable *color_table = red->GetColorTable();
                    bool has_nodata = nodata_value_ || raster_has_nodata;

                    // we can deduce the alpha channel from nodata in the Byte case
                    // by reusing the reading of R,G,B bands directly
                    if (has_nodata && !color_table && red->GetRasterDataType() == GDT_Byte)
                    {
                        double apply_nodata = nodata_value_ ? *nodata_value_ : raster_nodata;
                        // read the data in and create an alpha channel from the nodata values
                        // TODO - we assume here the nodata value for the red band applies to all bands
                        // more details about this at http://trac.osgeo.org/gdal/ticket/2734
                        float* imageData = (float*)image.bytes();
                        raster_io_error = red->RasterIO(GF_Read, x_off, y_off, width, height,
                                                        imageData, image.width(), image.height(),
                                                        GDT_Float32, 0, 0);
                        if (raster_io_error == CE_Failure) {
                            throw datasource_exception(CPLGetLastErrorMsg());
                        }
                        int len = image.width() * image.height();
                        for (int i = 0; i < len; ++i)
                        {
                            if (std::fabs(apply_nodata - imageData[i]) < nodata_tolerance_)
                            {
                                *reinterpret_cast<unsigned *>(&imageData[i]) = 0;
                            }
                            else
                            {
                                *reinterpret_cast<unsigned *>(&imageData[i]) = 0xFFFFFFFF;
                            }
                        }
                    }

                    /* Use dataset RasterIO in priority in 99.9% of the cases */
                    if( red->GetBand() == 1 && green->GetBand() == 2 && blue->GetBand() == 3 )
                    {
                        int nBandsToRead = 3;
                        if( alpha != NULL && alpha->GetBand() == 4 && !raster_has_nodata )
                        {
                            nBandsToRead = 4;
                            alpha = NULL; // to avoid reading it again afterwards
                        }
                        raster_io_error = dataset_.RasterIO(GF_Read, x_off, y_off, width, height,
                                                            image.bytes(),
                                                            image.width(), image.height(), GDT_Byte,
                                                            nBandsToRead, NULL,
                                                            4, 4 * image.width(), 1);
                        if (raster_io_error == CE_Failure) {
                            throw datasource_exception(CPLGetLastErrorMsg());
                        }
                    }
                    else
                    {
                        raster_io_error = red->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 0,
                                                        image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
                        if (raster_io_error == CE_Failure) {
                            throw datasource_exception(CPLGetLastErrorMsg());
                        }
                        raster_io_error = green->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 1,
                                                        image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
                        if (raster_io_error == CE_Failure) {
                            throw datasource_exception(CPLGetLastErrorMsg());
                        }
                        raster_io_error = blue->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 2,
                                                        image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
                        if (raster_io_error == CE_Failure) {
                            throw datasource_exception(CPLGetLastErrorMsg());
                        }
                    }

                    // In the case we skipped initializing the alpha channel
                    if (has_nodata && !color_table && red->GetRasterDataType() == GDT_Byte)
                    {
                        double apply_nodata = nodata_value_ ? *nodata_value_ : raster_nodata;
                        if( apply_nodata >= 0 && apply_nodata <= 255 )
                        {
                            int len = image.width() * image.height();
                            GByte* pabyBytes = (GByte*) image.bytes();
                            for (int i = 0; i < len; ++i)
                            {
                                // TODO - we assume here the nodata value for the red band applies to all bands
                                // more details about this at http://trac.osgeo.org/gdal/ticket/2734
                                if (std::fabs(apply_nodata - pabyBytes[4*i]) < nodata_tolerance_)
                                    pabyBytes[4*i + 3] = 0;
                                else
                                    pabyBytes[4*i + 3] = 255;
                            }
                        }
                    }
                }
                else if (grey)
                {
                    MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Processing gray band...";
                    raster_nodata = grey->GetNoDataValue(&raster_has_nodata);
                    GDALColorTable* color_table = grey->GetColorTable();
                    bool has_nodata = nodata_value_ || raster_has_nodata;
                    if (!color_table && has_nodata)
                    {
                        double apply_nodata = nodata_value_ ? *nodata_value_ : raster_nodata;
                        MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: applying nodata value for layer=" << apply_nodata;
                        // first read the data in and create an alpha channel from the nodata values
                        float* imageData = (float*)image.bytes();
                        raster_io_error = grey->RasterIO(GF_Read, x_off, y_off, width, height,
                                                         imageData, image.width(), image.height(),
                                                         GDT_Float32, 0, 0);
                        if (raster_io_error == CE_Failure)
                        {
                            throw datasource_exception(CPLGetLastErrorMsg());
                        }
                        int len = image.width() * image.height();
                        for (int i = 0; i < len; ++i)
                        {
                            if (std::fabs(apply_nodata - imageData[i]) < nodata_tolerance_)
                            {
                                *reinterpret_cast<unsigned *>(&imageData[i]) = 0;
                            }
                            else
                            {
                                *reinterpret_cast<unsigned *>(&imageData[i]) = 0xFFFFFFFF;
                            }
                        }
                    }

                    raster_io_error = grey->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 0,
                                                     image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
                    if (raster_io_error == CE_Failure)
                    {
                        throw datasource_exception(CPLGetLastErrorMsg());
                    }

                    raster_io_error = grey->RasterIO(GF_Read,x_off, y_off, width, height, image.bytes() + 1,
                                                     image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
                    if (raster_io_error == CE_Failure)
                    {
                        throw datasource_exception(CPLGetLastErrorMsg());
                    }

                    raster_io_error = grey->RasterIO(GF_Read,x_off, y_off, width, height, image.bytes() + 2,
                                                     image.width(), image.height(), GDT_Byte, 4, 4 * image.width());

                    if (raster_io_error == CE_Failure)
                    {
                        throw datasource_exception(CPLGetLastErrorMsg());
                    }

                    if (color_table)
                    {
                        MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Loading color table...";
                        for (unsigned y = 0; y < image.height(); ++y)
                        {
                            unsigned int* row = image.get_row(y);
                            for (unsigned x = 0; x < image.width(); ++x)
                            {
                                unsigned value = row[x] & 0xff;
                                const GDALColorEntry *ce = color_table->GetColorEntry(value);
                                if (ce)
                                {
                                    row[x] = (ce->c4 << 24)| (ce->c3 << 16) |  (ce->c2 << 8) | (ce->c1) ;
                                }
                                else
                                {
                                    // make lacking color entry fully alpha
                                    // note - gdal_translate makes black
                                    row[x] = 0;
                                }
                            }
                        }
                    }
                }
                if (alpha)
                {
                    MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: processing alpha band...";
                    if (!raster_has_nodata)
                    {
                        raster_io_error = alpha->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 3,
                                                          image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
                        if (raster_io_error == CE_Failure) {
                            throw datasource_exception(CPLGetLastErrorMsg());
                        }
                    }
                    else
                    {
                        MAPNIK_LOG_WARN(gdal) << "warning: nodata value (" << raster_nodata << ") used to set transparency instead of alpha band";
                    }
                }
                mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor);
                // set nodata value to be used in raster colorizer
                if (nodata_value_) raster->set_nodata(*nodata_value_);
                else raster->set_nodata(raster_nodata);
                feature->set_raster(raster);
            }
            // report actual/original source nodata in feature attributes
            if (raster_has_nodata)
            {
                feature->put("nodata",raster_nodata);
            }
            return feature;
        }
    }
    return feature_ptr();
}
Example #27
0
int Image::scatterImageFileGDAL(const char * filename, int xOffset, int yOffset,
                         PV::Communicator * comm, const PVLayerLoc * loc, float * buf, bool autoResizeFlag)
{
   int status = 0;

#ifdef PV_USE_GDAL
   // const int maxBands = 3;

   const int nxProcs = comm->numCommColumns();
   const int nyProcs = comm->numCommRows();

   const int icRank = comm->commRank();

   const int nx = loc->nx;
   const int ny = loc->ny;

   const int numBands = loc->nf;
   int numTotal; // will be nx*ny*bandsInFile;

   const MPI_Comm mpi_comm = comm->communicator();
   GDALDataType dataType;
   char** metadata;
   char isBinary = true;

   if (icRank > 0) {
#ifdef PV_USE_MPI
      const int src = 0;
      const int tag = 13;

      MPI_Bcast(&dataType, 1, MPI_INT, 0, mpi_comm);
      MPI_Bcast(&isBinary, 1, MPI_CHAR, 0, mpi_comm);
      MPI_Bcast(&numTotal, 1, MPI_INT, 0, mpi_comm);
#ifdef DEBUG_OUTPUT
      fprintf(stderr, "[%2d]: scatterImageFileGDAL: received from 0, total number of bytes in buffer is %d\n", numTotal);
#endif // DEBUG_OUTPUT
      MPI_Recv(buf, numTotal, MPI_FLOAT, src, tag, mpi_comm, MPI_STATUS_IGNORE);
#ifdef DEBUG_OUTPUT
      int nf=numTotal/(nx*ny);
      assert( nf*nx*ny == numTotal );
      fprintf(stderr, "[%2d]: scatterImageFileGDAL: received from 0, nx==%d ny==%d nf==%d size==%d\n",
              comm->commRank(), nx, ny, nf, numTotal);
#endif // DEBUG_OUTPUT
#endif // PV_USE_MPI
   }
   else {
      GDALAllRegister();

      GDALDataset * dataset = PV_GDALOpen(filename); // (GDALDataset *) GDALOpen(filename, GA_ReadOnly);
      GDALRasterBand * poBand = dataset->GetRasterBand(1);
      dataType = poBand->GetRasterDataType();
#ifdef PV_USE_MPI
      MPI_Bcast(&dataType, 1, MPI_INT, 0, mpi_comm);
#endif // PV_USE_MPI

      // GDAL defines whether a band is binary, not whether the image as a whole is binary.
      // Set isBinary to false if any band is not binary (metadata doesn't have NBITS=1)
      for(int iBand = 0; iBand < GDALGetRasterCount(dataset); iBand++){
         GDALRasterBandH hBand = GDALGetRasterBand(dataset, iBand+1);
         metadata = GDALGetMetadata(hBand, "Image_Structure");
         if(CSLCount(metadata) > 0){
            bool found = false;
            for(int i = 0; metadata[i] != NULL; i++){
               if(strcmp(metadata[i], "NBITS=1") == 0){
                  found = true;
                  break;
               }
            }
            if(!found){
               isBinary = false;
            }
         }
         else{
            isBinary = false;
         }
      }
#ifdef PV_USE_MPI
      MPI_Bcast(&isBinary, 1, MPI_CHAR, 0, mpi_comm);
#endif // PV_USE_MPI

      if (dataset==NULL) return 1; // PV_GDALOpen prints an error message.
      int xImageSize = dataset->GetRasterXSize();
      int yImageSize = dataset->GetRasterYSize();
      const int bandsInFile = dataset->GetRasterCount();

      numTotal = nx * ny * bandsInFile;
#ifdef PV_USE_MPI
#ifdef DEBUG_OUTPUT
      fprintf(stderr, "[%2d]: scatterImageFileGDAL: broadcast from 0, total number of bytes in buffer is %d\n", numTotal);
#endif // DEBUG_OUTPUT
      MPI_Bcast(&numTotal, 1, MPI_INT, 0, mpi_comm);
#endif // PV_USE_MPI

      int xTotalSize = nx * nxProcs;
      int yTotalSize = ny * nyProcs;

      // if nf > bands of image, it will copy the gray image to each
      //band of layer
      assert(numBands == 1 || numBands == bandsInFile || (numBands > 1 && bandsInFile == 1));

      int dest = -1;
      const int tag = 13;

      float padValue_conv;
      if(dataType == GDT_Byte){
         padValue_conv = padValue * 255.0f;
      }
      else if(dataType == GDT_UInt16){
         padValue_conv = padValue * 65535.0f;
      }
      else{
         std::cout << "Image data type " << GDALGetDataTypeName(dataType) << " not implemented for image rescaling\n";
         exit(-1);
      }

      using std::min;
      using std::max;
      for( dest = nyProcs*nxProcs-1; dest >= 0; dest-- ) {

         //Need to clear buffer before reading, since we're skipping some of the buffer
#ifdef PV_USE_OPENMP_THREADS
#pragma omp parallel for
#endif
         for(int i = 0; i < nx * ny * bandsInFile; i++){ 
            //Fill with padValue
            buf[i] = padValue_conv;
         }


         int col = columnFromRank(dest,nyProcs,nxProcs);
         int row = rowFromRank(dest,nyProcs,nxProcs);
         int kx = nx * col;
         int ky = ny * row;


         //? For the auto resize flag, PV checks which side (x or y) is the shortest, relative to the
         //? hypercolumn size specified.  Then it determines the largest chunk it can possibly take
         //? from the image with the correct aspect ratio determined by hypercolumn.  It then
         //? determines the offset needed in the long dimension to center the cropped image,
         //? and reads in that portion of the image.  The offset can optionally be translated by
         //? offset{X,Y} specified in the params file (values can be positive or negative).
         //? If the specified offset takes the cropped image outside the image file, it uses the
         //? largest-magnitude offset that stays within the image file's borders.

         if (autoResizeFlag){

            if (xImageSize/(double)xTotalSize < yImageSize/(double)yTotalSize){
               int new_y = int(round(ny*xImageSize/(double)xTotalSize));
               int y_off = int(round((yImageSize - new_y*nyProcs)/2.0));

               int jitter_y = max(min(y_off,yOffset),-y_off);

               kx = xImageSize/nxProcs * col;
               ky = new_y * row;

               //fprintf(stderr, "kx = %d, ky = %d, nx = %d, new_y = %d", kx, ky, xImageSize/nxProcs, new_y);

               dataset->RasterIO(GF_Read, kx, ky + y_off + jitter_y, xImageSize/nxProcs, new_y, buf, nx, ny,
                     GDT_Float32, bandsInFile, NULL, bandsInFile*sizeof(float),
                     bandsInFile*nx*sizeof(float), sizeof(float));
            }
            else{
               int new_x = int(round(nx*yImageSize/(double)yTotalSize));
               int x_off = int(round((xImageSize - new_x*nxProcs)/2.0));

               int jitter_x = max(min(x_off,xOffset),-x_off);

               kx = new_x * col;
               ky = yImageSize/nyProcs * row;

               //fprintf(stderr, "kx = %d, ky = %d, new_x = %d, ny = %d, x_off = %d", kx, ky, new_x, yImageSize/nyProcs, x_off);
               dataset->RasterIO(GF_Read, kx + x_off + jitter_x, ky, new_x, yImageSize/nyProcs, buf, nx, ny,
                     GDT_Float32, bandsInFile, NULL, bandsInFile*sizeof(float),
                     bandsInFile*nx*sizeof(float),sizeof(float));
            }
         }//End autoResizeFlag
         else {
            //Need to calculate corner image pixels in globalres space
            //offset is in Image space
            int img_left = -xOffset;
            int img_top = -yOffset;
            int img_right = img_left + xImageSize;
            int img_bot = img_top + yImageSize;

            //Check if in bounds
            if(img_left >= kx+nx || img_right <= kx || img_top >= ky+ny || img_bot <= ky){
               //Do mpi_send to keep number of sends correct
               if(dest > 0){
                  MPI_Send(buf, numTotal, MPI_FLOAT, dest, tag, mpi_comm);
               }
               continue;
            }


            //start of the buffer on the left/top side
            int buf_left = img_left > kx ? img_left-kx : 0;
            int buf_top = img_top > ky ? img_top-ky : 0;
            int buf_right = img_right < kx+nx ? img_right-kx : nx;
            int buf_bot = img_bot < ky+ny ? img_bot-ky : ny;

            int buf_xSize = buf_right - buf_left; 
            int buf_ySize = buf_bot - buf_top;
            assert(buf_xSize > 0 && buf_ySize > 0);

            int buf_offset = buf_top * nx * bandsInFile + buf_left * bandsInFile;

            int img_offset_x = kx+xOffset;
            int img_offset_y = ky+yOffset;
            if(img_offset_x < 0){
               img_offset_x = 0;
            }
            if(img_offset_y < 0){
               img_offset_y = 0;
            }

            float* buf_start = buf + buf_offset;

            dataset->RasterIO(GF_Read, img_offset_x, img_offset_y, buf_xSize, buf_ySize, buf_start,
                  buf_xSize,
                  buf_ySize, GDT_Float32, bandsInFile, NULL,
                  bandsInFile*sizeof(float), bandsInFile*nx*sizeof(float), sizeof(float));

         }
#ifdef DEBUG_OUTPUT
         fprintf(stderr, "[%2d]: scatterImageFileGDAL: sending to %d xSize==%d"
               " ySize==%d bandsInFile==%d size==%d total(over all procs)==%d\n",
               comm->commRank(), dest, nx, ny, bandsInFile, numTotal,
               nx*ny*comm->commSize());
#endif // DEBUG_OUTPUT

#ifdef PV_USE_MPI
         if(dest > 0){
            MPI_Send(buf, numTotal, MPI_FLOAT, dest, tag, mpi_comm);
         }
#endif // PV_USE_MPI
      }

      GDALClose(dataset);

      //Moved to above for loop
      // get local image portion

      //? same logic as before, except this time we know that the row and column are 0

      //if (autoResizeFlag){

      //   if (xImageSize/(double)xTotalSize < yImageSize/(double)yTotalSize){
      //      int new_y = int(round(ny*xImageSize/(double)xTotalSize));
      //      int y_off = int(round((yImageSize - new_y*nyProcs)/2.0));

      //      int offset_y = max(min(y_off,yOffset),-y_off);

      //      //fprintf(stderr, "kx = %d, ky = %d, nx = %d, new_y = %d", 0, 0, xImageSize/nxProcs, new_y);
      //      dataset->RasterIO(GF_Read, 0, y_off + offset_y, xImageSize/nxProcs, new_y, buf, nx, ny,
      //                        GDT_Float32, bandsInFile, NULL, bandsInFile*sizeof(float),
      //                        bandsInFile*nx*sizeof(float), sizeof(float));
      //   }
      //   else{
      //      int new_x = int(round(nx*yImageSize/(double)yTotalSize));
      //      int x_off = int(round((xImageSize - new_x*nxProcs)/2.0));

      //      int offset_x = max(min(x_off,xOffset),-x_off);

      //      //fprintf(stderr, "xImageSize = %d, xTotalSize = %d, yImageSize = %d, yTotalSize = %d", xImageSize, xTotalSize, yImageSize, yTotalSize);
      //      //fprintf(stderr, "kx = %d, ky = %d, new_x = %d, ny = %d",
      //      //0, 0, new_x, yImageSize/nyProcs);
      //      dataset->RasterIO(GF_Read, x_off + offset_x, 0, new_x, yImageSize/nyProcs, buf, nx, ny,
      //                        GDT_Float32, bandsInFile, NULL, bandsInFile*sizeof(float),
      //                        bandsInFile*nx*sizeof(float),sizeof(float));
      //   }
      //}
      //else {

      //   //fprintf(stderr,"just checking");
      //    dataset->RasterIO(GF_Read, xOffset, yOffset, nx, ny, buf, nx, ny,
      //                      GDT_Float32, bandsInFile, NULL, bandsInFile*sizeof(float), bandsInFile*nx*sizeof(float), sizeof(float));
      //}

      //GDALClose(dataset);
   }
#else
   fprintf(stderr, GDAL_CONFIG_ERR_STR);
   exit(1);
#endif // PV_USE_GDAL

   if (status == 0) {
      if(!isBinary){
         float fac;
         if(dataType == GDT_Byte){
            fac = 1.0f / 255.0f;  // normalize to 1.0
         }
         else if(dataType == GDT_UInt16){
            fac = 1.0f / 65535.0f;  // normalize to 1.0
         }
         else{
            std::cout << "Image data type " << GDALGetDataTypeName(dataType) << " not implemented for image rescaling\n";
            exit(-1);
         }
         for( int n=0; n<numTotal; n++ ) {
            buf[n] *= fac;
         }
      }
   }
   return status;
}
Example #28
0
int main(int argc, char *argv[]){
    GDALDataset  *poDataset;
    GDALAllRegister();
	
	if(argc != 3){
		std::cout << "usage:\n" << argv[0] << " src_file dest_file\n";
		exit(0);  
	}
	
	const std::string name = argv[1]; 
	const std::string destName = argv[2]; 

    poDataset = (GDALDataset *) GDALOpen(name.c_str(), GA_ReadOnly );
    if( poDataset == NULL ){
	   std::cout << "Failed to open " << name << "\n"; 
	}else{
		
		const char *pszFormat = "GTiff";
		GDALDriver *poDriver;
		char **papszMetadata;

		poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat);

		if( poDriver == NULL ){
			std::cout << "Cant open driver\n"; 
			exit(1);       
		}
		
		papszMetadata = GDALGetMetadata( poDriver, NULL );
		if( !CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATE, FALSE ) ){
			std::cout << "Create Method not suported!\n";
		}
		
		if( !CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATECOPY, FALSE ) ){
			std::cout << "CreateCopy() method not suported.\n";
		}  
		

		
		char **papszOptions = NULL;


		GDALDataset *dest = poDriver->Create(destName.c_str() , poDataset->GetRasterXSize(), 
					poDataset->GetRasterYSize(), 3, GDT_Byte, papszOptions );
		
		
		
				
	   std::cout << "Reading file " << name << "\n"; 
	   std::cout << 
		"x= " << poDataset->GetRasterXSize() << 
		", h=" << poDataset->GetRasterYSize() << 
        ", bands= " <<   poDataset->GetRasterCount() << "\n";
	
	   
	   
	   GDALRasterBand *data; 
       data = poDataset->GetRasterBand(1);   
	    
       
       GDALDataType type = data->GetRasterDataType(); 
       printDataType(type); 
       
       int size = data->GetXSize()*data->GetYSize();
		
	   std::cout << "size=" << size << " , w*h = " << poDataset->GetRasterXSize()*poDataset->GetRasterYSize() << "\n";

       float *buffer;
       buffer = (float *) CPLMalloc(sizeof(float)*size);
       data->RasterIO(GF_Read, 0, 0, data->GetXSize(), data->GetYSize(), buffer, data->GetXSize(), data->GetYSize(), GDT_Float32, 0, 0 );

	   GDALRasterBand *destBand1 = dest->GetRasterBand(1);   
	   GDALRasterBand *destBand2 = dest->GetRasterBand(2);   
	   GDALRasterBand *destBand3 = dest->GetRasterBand(3);   
	   // GDALRasterBand *destBand4 = dest->GetRasterBand(4);   


	   
       
       // Metadata, 
       double geot[6]; 
       poDataset->GetGeoTransform(geot); 
	   dest->SetGeoTransform(geot);// adfGeoTransform );
	   dest->SetProjection( poDataset->GetProjectionRef() );
       
       
       
       
       GByte destWrite1[size]; //  = (GUInt32 *) CPLMalloc(sizeof(GUInt32)*size); 
       GByte destWrite2[size];
       GByte destWrite3[size];
      //  GByte destWrite4[size];
       
       
       unsigned int i;
       float max=0, min=0; 
       
       for(i=0; i<size; i++){
			if(max < buffer[i]){
				max = buffer[i];
			}
			
			if(min > buffer[i]){
				min = buffer[i]; 
			}
	   }
       
       float range = max - min; 
       std::cout << "range=" << range << ", max=" << max << ", min=" << min << "\n";  
       std::map<float, unsigned int> counter;  
       for(i=0; i<size; i++){
			 counter[buffer[i]]++;
			 unsigned int v = buffer[i] * 100;
	  	 destWrite1[i] = (v & (0xff << 0)) >> 0;
	  	 destWrite2[i] = (v & (0xff << 8)) >> 8;
	  	 destWrite3[i] = (v & (0xff << 16)) >> 16;
	  	   //  destWrite4[i] =  0x00; // (v & (0xff << 24)) >> 24;
	   }

       destBand1->RasterIO( GF_Write, 0, 0, data->GetXSize(), data->GetYSize(), 
							destWrite1, data->GetXSize(), data->GetYSize(), GDT_Byte, 0, 0 );    

       destBand2->RasterIO( GF_Write, 0, 0, data->GetXSize(), data->GetYSize(), 
							destWrite2, data->GetXSize(), data->GetYSize(), GDT_Byte, 0, 0 );    

       destBand3->RasterIO( GF_Write, 0, 0, data->GetXSize(), data->GetYSize(), 
							destWrite3, data->GetXSize(), data->GetYSize(), GDT_Byte, 0, 0 );    

      // destBand4->RasterIO( GF_Write, 0, 0, data->GetXSize(), data->GetYSize(), 
		//					destWrite4, data->GetXSize(), data->GetYSize(), GDT_Byte, 0, 0 );    


       
       

		/*std::map<float, unsigned int>::iterator it; 
		std::cout << "Counter: \n"; 
	   for(it=counter.begin(); it!=counter.end(); it++){
		 std::cout << (it->first*1000) << " = " << it->second << "\n"; 
	   }*/
       
       /* Once we're done, close properly the dataset */
		if( dest != NULL ){
		
		 	GDALClose(dest );
			GDALClose(poDataset );
		}
	
       /*
       unsigned int *buffer; 
       buffer = (unsigned int *) CPLMalloc(sizeof(unsigned int)*size);
       data->RasterIO(GF_Read, 0, 0, size, 1, buffer, size, 1, GDT_UInt32, 0, 0 );
       
       unsigned int i;
       std::map<unsigned int, unsigned int> counter;  
       for(i=0; i<size; i++){
			counter[buffer[i]]++; 
	   }

		std::map<unsigned int, unsigned int>::iterator it; 
		std::cout << "Counter: \n"; 
	   for(it=counter.begin(); it!=counter.end(); it++){
		 std::cout << it->first << " = " << it->second << "\n"; 
		    
	   }*/
              
    }
    
    exit(0); 
}
Example #29
0
GDALDataset * AAIGDataset::CreateCopy(
    const char *pszFilename, GDALDataset *poSrcDS,
    int /* bStrict */,
    char **papszOptions,
    GDALProgressFunc pfnProgress, void *pProgressData )
{
    const int nBands = poSrcDS->GetRasterCount();
    const int nXSize = poSrcDS->GetRasterXSize();
    const int nYSize = poSrcDS->GetRasterYSize();

    // Some rudimentary checks.
    if( nBands != 1 )
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                 "AAIG driver doesn't support %d bands.  Must be 1 band.",
                 nBands);

        return nullptr;
    }

    if( !pfnProgress(0.0, nullptr, pProgressData) )
        return nullptr;

    // Create the dataset.
    VSILFILE *fpImage = VSIFOpenL(pszFilename, "wt");
    if( fpImage == nullptr )
    {
        CPLError(CE_Failure, CPLE_OpenFailed,
                 "Unable to create file %s.",
                 pszFilename);
        return nullptr;
    }

    // Write ASCII Grid file header.
    double adfGeoTransform[6] = {};
    char szHeader[2000] = {};
    const char *pszForceCellsize =
        CSLFetchNameValue(papszOptions, "FORCE_CELLSIZE");

    poSrcDS->GetGeoTransform(adfGeoTransform);

    if( std::abs(adfGeoTransform[1] + adfGeoTransform[5]) < 0.0000001 ||
        std::abs(adfGeoTransform[1]-adfGeoTransform[5]) < 0.0000001 ||
        (pszForceCellsize && CPLTestBool(pszForceCellsize)) )
    {
        CPLsnprintf(
            szHeader, sizeof(szHeader),
            "ncols        %d\n"
            "nrows        %d\n"
            "xllcorner    %.12f\n"
            "yllcorner    %.12f\n"
            "cellsize     %.12f\n",
            nXSize, nYSize,
            adfGeoTransform[0],
            adfGeoTransform[3] - nYSize * adfGeoTransform[1],
            adfGeoTransform[1]);
    }
    else
    {
        if( pszForceCellsize == nullptr )
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Producing a Golden Surfer style file with DX and DY "
                     "instead of CELLSIZE since the input pixels are "
                     "non-square.  Use the FORCE_CELLSIZE=TRUE creation "
                     "option to force use of DX for even though this will "
                     "be distorted.  Most ASCII Grid readers (ArcGIS "
                     "included) do not support the DX and DY parameters.");
        CPLsnprintf(
            szHeader, sizeof(szHeader),
            "ncols        %d\n"
            "nrows        %d\n"
            "xllcorner    %.12f\n"
            "yllcorner    %.12f\n"
            "dx           %.12f\n"
            "dy           %.12f\n",
            nXSize, nYSize,
            adfGeoTransform[0],
            adfGeoTransform[3] + nYSize * adfGeoTransform[5],
            adfGeoTransform[1],
            fabs(adfGeoTransform[5]));
    }

    // Builds the format string used for printing float values.
    char szFormatFloat[32] = { '\0' };
    strcpy(szFormatFloat, " %.20g");
    const char *pszDecimalPrecision =
        CSLFetchNameValue(papszOptions, "DECIMAL_PRECISION");
    const char *pszSignificantDigits =
        CSLFetchNameValue(papszOptions, "SIGNIFICANT_DIGITS");
    bool bIgnoreSigDigits = false;
    if( pszDecimalPrecision && pszSignificantDigits )
    {
        CPLError(CE_Warning, CPLE_AppDefined,
                 "Conflicting precision arguments, using DECIMAL_PRECISION");
        bIgnoreSigDigits = true;
    }
    int nPrecision;
    if ( pszSignificantDigits && !bIgnoreSigDigits )
    {
        nPrecision = atoi(pszSignificantDigits);
        if (nPrecision >= 0)
            snprintf(szFormatFloat, sizeof(szFormatFloat), " %%.%dg",
                     nPrecision);
        CPLDebug("AAIGrid", "Setting precision format: %s", szFormatFloat);
    }
    else if( pszDecimalPrecision )
    {
        nPrecision = atoi(pszDecimalPrecision);
        if ( nPrecision >= 0 )
            snprintf(szFormatFloat, sizeof(szFormatFloat), " %%.%df",
                     nPrecision);
        CPLDebug("AAIGrid", "Setting precision format: %s", szFormatFloat);
    }

    // Handle nodata (optionally).
    GDALRasterBand *poBand = poSrcDS->GetRasterBand(1);
    const bool bReadAsInt =
        poBand->GetRasterDataType() == GDT_Byte ||
        poBand->GetRasterDataType() == GDT_Int16 ||
        poBand->GetRasterDataType() == GDT_UInt16 ||
        poBand->GetRasterDataType() == GDT_Int32;

    // Write `nodata' value to header if it is exists in source dataset
    int bSuccess = FALSE;
    const double dfNoData = poBand->GetNoDataValue(&bSuccess);
    if ( bSuccess )
    {
        snprintf(szHeader + strlen(szHeader),
                 sizeof(szHeader) - strlen(szHeader), "%s", "NODATA_value ");
        if( bReadAsInt )
            snprintf(szHeader + strlen(szHeader),
                     sizeof(szHeader) - strlen(szHeader), "%d",
                     static_cast<int>(dfNoData));
        else
            CPLsnprintf(szHeader + strlen(szHeader),
                        sizeof(szHeader) - strlen(szHeader),
                        szFormatFloat, dfNoData);
        snprintf(szHeader + strlen(szHeader),
                 sizeof(szHeader) - strlen(szHeader), "%s", "\n");
    }

    if( VSIFWriteL(szHeader, strlen(szHeader), 1, fpImage) != 1)
    {
        CPL_IGNORE_RET_VAL(VSIFCloseL(fpImage));
        return nullptr;
    }

    // Loop over image, copying image data.

    // Write scanlines to output file
    int *panScanline = bReadAsInt
                           ? static_cast<int *>(CPLMalloc(
                                 nXSize * GDALGetDataTypeSizeBytes(GDT_Int32)))
                           : nullptr;

    double *padfScanline =
        bReadAsInt ? nullptr
                   : static_cast<double *>(CPLMalloc(
                         nXSize * GDALGetDataTypeSizeBytes(GDT_Float64)));

    CPLErr eErr = CE_None;

    bool bHasOutputDecimalDot = false;
    for( int iLine = 0; eErr == CE_None && iLine < nYSize; iLine++ )
    {
        CPLString osBuf;
        eErr = poBand->RasterIO(
            GF_Read, 0, iLine, nXSize, 1,
            bReadAsInt ? reinterpret_cast<void *>(panScanline) :
            reinterpret_cast<void *>(padfScanline),
            nXSize, 1, bReadAsInt ? GDT_Int32 : GDT_Float64,
            0, 0, nullptr);

        if( bReadAsInt )
        {
            for ( int iPixel = 0; iPixel < nXSize; iPixel++ )
            {
                snprintf(szHeader, sizeof(szHeader),
                         " %d", panScanline[iPixel]);
                osBuf += szHeader;
                if( (iPixel & 1023) == 0 || iPixel == nXSize - 1 )
                {
                    if ( VSIFWriteL(osBuf, static_cast<int>(osBuf.size()), 1,
                                    fpImage) != 1 )
                    {
                        eErr = CE_Failure;
                        CPLError(CE_Failure, CPLE_AppDefined,
                                 "Write failed, disk full?");
                        break;
                    }
                    osBuf = "";
                }
            }
        }
        else
        {
            for ( int iPixel = 0; iPixel < nXSize; iPixel++ )
            {
                CPLsnprintf(szHeader, sizeof(szHeader),
                            szFormatFloat, padfScanline[iPixel]);

                // Make sure that as least one value has a decimal point (#6060)
                if( !bHasOutputDecimalDot )
                {
                    if( strchr(szHeader, '.') || strchr(szHeader, 'e') ||
                        strchr(szHeader, 'E') )
                    {
                        bHasOutputDecimalDot = true;
                    }
                    else if( !CPLIsInf(padfScanline[iPixel]) &&
                             !CPLIsNan(padfScanline[iPixel]) )
                    {
                        strcat(szHeader, ".0");
                        bHasOutputDecimalDot = true;
                    }
                }

                osBuf += szHeader;
                if( (iPixel & 1023) == 0 || iPixel == nXSize - 1 )
                {
                  if ( VSIFWriteL(osBuf, static_cast<int>(osBuf.size()), 1,
                                  fpImage) != 1 )
                    {
                        eErr = CE_Failure;
                        CPLError(CE_Failure, CPLE_AppDefined,
                                 "Write failed, disk full?");
                        break;
                    }
                    osBuf = "";
                }
            }
        }
        if( VSIFWriteL("\n", 1, 1, fpImage) != 1 )
            eErr = CE_Failure;

        if( eErr == CE_None &&
            !pfnProgress((iLine + 1) / static_cast<double>(nYSize), nullptr,
                         pProgressData) )
        {
            eErr = CE_Failure;
            CPLError(CE_Failure, CPLE_UserInterrupt,
                     "User terminated CreateCopy()");
        }
    }

    CPLFree(panScanline);
    CPLFree(padfScanline);
    if( VSIFCloseL(fpImage) != 0 )
        eErr = CE_Failure;

    if( eErr != CE_None )
        return nullptr;

    // Try to write projection file.
    const char *pszOriginalProjection = poSrcDS->GetProjectionRef();
    if( !EQUAL(pszOriginalProjection, "") )
    {
        char *pszDirname = CPLStrdup(CPLGetPath(pszFilename));
        char *pszBasename = CPLStrdup(CPLGetBasename(pszFilename));
        char *pszPrjFilename =
            CPLStrdup(CPLFormFilename(pszDirname, pszBasename, "prj"));
        VSILFILE *fp = VSIFOpenL(pszPrjFilename, "wt");
        if (fp != nullptr)
        {
            OGRSpatialReference oSRS;
            oSRS.importFromWkt(pszOriginalProjection);
            oSRS.morphToESRI();
            char *pszESRIProjection = nullptr;
            oSRS.exportToWkt(&pszESRIProjection);
            CPL_IGNORE_RET_VAL(VSIFWriteL(pszESRIProjection, 1,
                                          strlen(pszESRIProjection), fp));

            CPL_IGNORE_RET_VAL(VSIFCloseL(fp));
            CPLFree(pszESRIProjection);
        }
        else
        {
            CPLError(CE_Failure, CPLE_FileIO, "Unable to create file %s.",
                     pszPrjFilename);
        }
        CPLFree(pszDirname);
        CPLFree(pszBasename);
        CPLFree(pszPrjFilename);
    }

    // Re-open dataset, and copy any auxiliary pam information.

    // If writing to stdout, we can't reopen it, so return
    // a fake dataset to make the caller happy.
    CPLPushErrorHandler(CPLQuietErrorHandler);
    GDALPamDataset *poDS =
        reinterpret_cast<GDALPamDataset *>(GDALOpen(pszFilename, GA_ReadOnly));
    CPLPopErrorHandler();
    if (poDS)
    {
        poDS->CloneInfo(poSrcDS, GCIF_PAM_DEFAULT);
        return poDS;
    }

    CPLErrorReset();

    AAIGDataset *poAAIG_DS = new AAIGDataset();
    poAAIG_DS->nRasterXSize = nXSize;
    poAAIG_DS->nRasterYSize = nYSize;
    poAAIG_DS->nBands = 1;
    poAAIG_DS->SetBand(1, new AAIGRasterBand(poAAIG_DS, 1));
    return poAAIG_DS;
}
Example #30
0
GDALDataset *SAGADataset::CreateCopy( const char *pszFilename,
				      GDALDataset *poSrcDS,
				      int bStrict, char **papszOptions,
				      GDALProgressFunc pfnProgress,
				      void *pProgressData )
{
    if( pfnProgress == NULL )
        pfnProgress = GDALDummyProgress;

    int nBands = poSrcDS->GetRasterCount();
    if (nBands == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "SAGA driver does not support source dataset with zero band.\n");
        return NULL;
    }
    else if (nBands > 1)
    {
        if( bStrict )
        {
            CPLError( CE_Failure, CPLE_NotSupported,
                      "Unable to create copy, SAGA Binary Grid "
                      "format only supports one raster band.\n" );
            return NULL;
        }
        else
            CPLError( CE_Warning, CPLE_NotSupported,
                      "SAGA Binary Grid format only supports one "
                      "raster band, first band will be copied.\n" );
    }

    GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 );
    
    char** papszCreateOptions = NULL;
    papszCreateOptions = CSLSetNameValue(papszCreateOptions, "FILL_NODATA", "NO");

    int bHasNoDataValue = FALSE;
    double dfNoDataValue = poSrcBand->GetNoDataValue(&bHasNoDataValue);
    if (bHasNoDataValue)
        papszCreateOptions = CSLSetNameValue(papszCreateOptions, "NODATA_VALUE",
                                             CPLSPrintf("%.16g", dfNoDataValue));
    
    GDALDataset* poDstDS =
        Create(pszFilename, poSrcBand->GetXSize(), poSrcBand->GetYSize(),
               1, poSrcBand->GetRasterDataType(), papszCreateOptions);
    CSLDestroy(papszCreateOptions);
    
    if (poDstDS == NULL)
        return NULL;

    /* -------------------------------------------------------------------- */
    /*      Copy band data.	                                                */
    /* -------------------------------------------------------------------- */

    CPLErr	eErr;
    
    eErr = GDALDatasetCopyWholeRaster( (GDALDatasetH) poSrcDS, 
                                       (GDALDatasetH) poDstDS,
                                       NULL,
                                       pfnProgress, pProgressData );
                                       
    if (eErr == CE_Failure)
    {
        delete poDstDS;
        return NULL;
    }

    double  adfGeoTransform[6];

    poSrcDS->GetGeoTransform( adfGeoTransform );
    poDstDS->SetGeoTransform( adfGeoTransform );
    
    poDstDS->SetProjection( poSrcDS->GetProjectionRef() );

    return poDstDS;
}