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

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

    if( pfnProgress == NULL )
        pfnProgress = GDALDummyProgress;

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

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

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

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

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

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

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

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

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

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

    pfnProgress( 0.0, NULL, pProgressArg );

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

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

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

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

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

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

    return eErr;
}
Example #2
0
OGRErr PDFWritableVectorDataset::SyncToDisk()
{
    if (nLayers == 0 || !bModified)
        return OGRERR_NONE;

    bModified = FALSE;

    OGREnvelope sGlobalExtent;
    int bHasExtent = FALSE;
    for(int i=0;i<nLayers;i++)
    {
        OGREnvelope sExtent;
        if (papoLayers[i]->GetExtent(&sExtent) == OGRERR_NONE)
        {
            bHasExtent = TRUE;
            sGlobalExtent.Merge(sExtent);
        }
    }
    if (!bHasExtent ||
        sGlobalExtent.MinX == sGlobalExtent.MaxX ||
        sGlobalExtent.MinY == sGlobalExtent.MaxY)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Cannot compute spatial extent of features");
        return OGRERR_FAILURE;
    }

    PDFCompressMethod eStreamCompressMethod = COMPRESS_DEFLATE;
    const char* pszStreamCompressMethod = CSLFetchNameValue(papszOptions, "STREAM_COMPRESS");
    if (pszStreamCompressMethod)
    {
        if( EQUAL(pszStreamCompressMethod, "NONE") )
            eStreamCompressMethod = COMPRESS_NONE;
        else if( EQUAL(pszStreamCompressMethod, "DEFLATE") )
            eStreamCompressMethod = COMPRESS_DEFLATE;
        else
        {
            CPLError( CE_Warning, CPLE_NotSupported,
                    "Unsupported value for STREAM_COMPRESS.");
        }
    }

    const char* pszGEO_ENCODING =
        CSLFetchNameValueDef(papszOptions, "GEO_ENCODING", "ISO32000");

    const char* pszDPI = CSLFetchNameValue(papszOptions, "DPI");
    double dfDPI = DEFAULT_DPI;
    if( pszDPI != nullptr )
    {
        dfDPI = CPLAtof(pszDPI);
        if (dfDPI < DEFAULT_DPI)
            dfDPI = DEFAULT_DPI;
    }
    else
    {
        dfDPI = DEFAULT_DPI;
    }

    const char* pszWriteUserUnit = CSLFetchNameValue(papszOptions, "WRITE_USERUNIT");
    bool bWriteUserUnit;
    if( pszWriteUserUnit != nullptr )
        bWriteUserUnit = CPLTestBool( pszWriteUserUnit );
    else
        bWriteUserUnit = ( pszDPI == nullptr );

    const char* pszNEATLINE = CSLFetchNameValue(papszOptions, "NEATLINE");

    int nMargin = atoi(CSLFetchNameValueDef(papszOptions, "MARGIN", "0"));

    PDFMargins sMargins;
    sMargins.nLeft = nMargin;
    sMargins.nRight = nMargin;
    sMargins.nTop = nMargin;
    sMargins.nBottom = nMargin;

    const char* pszLeftMargin = CSLFetchNameValue(papszOptions, "LEFT_MARGIN");
    if (pszLeftMargin) sMargins.nLeft = atoi(pszLeftMargin);

    const char* pszRightMargin = CSLFetchNameValue(papszOptions, "RIGHT_MARGIN");
    if (pszRightMargin) sMargins.nRight = atoi(pszRightMargin);

    const char* pszTopMargin = CSLFetchNameValue(papszOptions, "TOP_MARGIN");
    if (pszTopMargin) sMargins.nTop = atoi(pszTopMargin);

    const char* pszBottomMargin = CSLFetchNameValue(papszOptions, "BOTTOM_MARGIN");
    if (pszBottomMargin) sMargins.nBottom = atoi(pszBottomMargin);

    const char* pszExtraImages = CSLFetchNameValue(papszOptions, "EXTRA_IMAGES");
    const char* pszExtraStream = CSLFetchNameValue(papszOptions, "EXTRA_STREAM");
    const char* pszExtraLayerName = CSLFetchNameValue(papszOptions, "EXTRA_LAYER_NAME");

    const char* pszOGRDisplayField = CSLFetchNameValue(papszOptions, "OGR_DISPLAY_FIELD");
    const char* pszOGRDisplayLayerNames = CSLFetchNameValue(papszOptions, "OGR_DISPLAY_LAYER_NAMES");
    const bool bWriteOGRAttributes =
        CPLFetchBool(papszOptions, "OGR_WRITE_ATTRIBUTES", true);
    const char* pszOGRLinkField = CSLFetchNameValue(papszOptions, "OGR_LINK_FIELD");

    const char* pszOffLayers = CSLFetchNameValue(papszOptions, "OFF_LAYERS");
    const char* pszExclusiveLayers = CSLFetchNameValue(papszOptions, "EXCLUSIVE_LAYERS");

    const char* pszJavascript = CSLFetchNameValue(papszOptions, "JAVASCRIPT");
    const char* pszJavascriptFile = CSLFetchNameValue(papszOptions, "JAVASCRIPT_FILE");

/* -------------------------------------------------------------------- */
/*      Create file.                                                    */
/* -------------------------------------------------------------------- */
    VSILFILE* fp = VSIFOpenL(GetDescription(), "wb");
    if( fp == nullptr )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Unable to create PDF file %s.\n",
                  GetDescription() );
        return OGRERR_FAILURE;
    }

    GDALPDFWriter oWriter(fp);

    double dfRatio = (sGlobalExtent.MaxY - sGlobalExtent.MinY) / (sGlobalExtent.MaxX - sGlobalExtent.MinX);

    int nWidth, nHeight;

    if (dfRatio < 1)
    {
        nWidth = 1024;
        nHeight = static_cast<int>(nWidth * dfRatio);
    }
    else
    {
        nHeight = 1024;
        nWidth = static_cast<int>(nHeight / dfRatio);
    }

    GDALDataset* poSrcDS = MEMDataset::Create( "MEM:::", nWidth, nHeight, 0, GDT_Byte, nullptr );

    double adfGeoTransform[6];
    adfGeoTransform[0] = sGlobalExtent.MinX;
    adfGeoTransform[1] = (sGlobalExtent.MaxX - sGlobalExtent.MinX) / nWidth;
    adfGeoTransform[2] = 0;
    adfGeoTransform[3] = sGlobalExtent.MaxY;
    adfGeoTransform[4] = 0;
    adfGeoTransform[5] = - (sGlobalExtent.MaxY - sGlobalExtent.MinY) / nHeight;

    poSrcDS->SetGeoTransform(adfGeoTransform);

    OGRSpatialReference* poSRS = papoLayers[0]->GetSpatialRef();
    if (poSRS)
    {
        char* pszWKT = nullptr;
        poSRS->exportToWkt(&pszWKT);
        poSrcDS->SetProjection(pszWKT);
        CPLFree(pszWKT);
    }

    oWriter.SetInfo(poSrcDS, papszOptions);

    oWriter.StartPage(poSrcDS,
                      dfDPI,
                      bWriteUserUnit,
                      pszGEO_ENCODING,
                      pszNEATLINE,
                      &sMargins,
                      eStreamCompressMethod,
                      bWriteOGRAttributes);

    int iObj = 0;

    char** papszLayerNames = CSLTokenizeString2(pszOGRDisplayLayerNames,",",0);

    for(int i=0;i<nLayers;i++)
    {
        CPLString osLayerName;
        if (CSLCount(papszLayerNames) < nLayers)
            osLayerName = papoLayers[i]->GetName();
        else
            osLayerName = papszLayerNames[i];

        oWriter.WriteOGRLayer((OGRDataSourceH)this,
                              i,
                              pszOGRDisplayField,
                              pszOGRLinkField,
                              osLayerName,
                              bWriteOGRAttributes,
                              iObj);
    }

    CSLDestroy(papszLayerNames);

    oWriter.EndPage(pszExtraImages,
                    pszExtraStream,
                    pszExtraLayerName,
                    pszOffLayers,
                    pszExclusiveLayers);

    if (pszJavascript)
        oWriter.WriteJavascript(pszJavascript);
    else if (pszJavascriptFile)
        oWriter.WriteJavascriptFile(pszJavascriptFile);

    oWriter.Close();

    delete poSrcDS;

    return OGRERR_NONE;
}
Example #3
0
bool CreateSubRaster( wxGISRasterDatasetSPtr pSrcRasterDataSet, OGREnvelope &Env, const OGRGeometry *pGeom, GDALDriver* pDriver, CPLString &szDstPath, GDALDataType eOutputType, int nBandCount, int *panBandList, double dfOutResX, double dfOutResY, bool bCopyNodata, bool bSkipSourceMetadata, char** papszOptions, ITrackCancel* pTrackCancel )
{
	GDALDataset* pDset = pSrcRasterDataSet->GetRaster();
	if(!pDset)
	{
		if(pTrackCancel)
			pTrackCancel->PutMessage(_("Get raster failed"), -1, enumGISMessageErr);
		return false;
	}

    double adfGeoTransform[6] = { 0, 0, 0, 0, 0, 0 };
	CPLErr err = pDset->GetGeoTransform(adfGeoTransform);
	if(err == CE_Fatal)
	{
		if(pTrackCancel)
			pTrackCancel->PutMessage(_("Get raster failed"), -1, enumGISMessageErr);
		return false;
	}
	if( adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0 )
	{
		if(pTrackCancel)
			pTrackCancel->PutMessage(_("The geotransform is rotated. This configuration is not supported."), -1, enumGISMessageErr);
		return false;
    }
	int anSrcWin[4] = {0, 0, 0, 0};

    anSrcWin[0] = floor ((Env.MinX - adfGeoTransform[0]) / adfGeoTransform[1] + 0.001);
    anSrcWin[1] = floor ((Env.MaxY - adfGeoTransform[3]) / adfGeoTransform[5] + 0.001);
	anSrcWin[2] = ceil ((Env.MaxX - Env.MinX) / adfGeoTransform[1]);
	anSrcWin[3] = ceil ((Env.MinY - Env.MaxY) / adfGeoTransform[5]);
	if(pTrackCancel)
		pTrackCancel->PutMessage(wxString::Format(_("Computed source pixel window %d %d %d %d from geographic window."), anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3] ), -1, enumGISMessageInfo);

	if( anSrcWin[0] < 0 || anSrcWin[1] < 0 || anSrcWin[0] + anSrcWin[2] > pSrcRasterDataSet->GetWidth() || anSrcWin[1] + anSrcWin[3] > pSrcRasterDataSet->GetHeight() )
    {
		if(pTrackCancel)
			pTrackCancel->PutMessage(wxString::Format(_("Computed source pixel window falls outside raster size of %dx%d."), pSrcRasterDataSet->GetWidth(), pSrcRasterDataSet->GetHeight()), -1, enumGISMessageErr);
		return false;
    }

	int nOXSize = 0, nOYSize = 0;

    if(IsDoubleEquil(dfOutResX, -1) && IsDoubleEquil(dfOutResY, -1))
    {
        nOXSize = anSrcWin[2];
        nOYSize = anSrcWin[3];
    }
    else
    {
        nOXSize = ceil ((Env.MaxX - Env.MinX) / dfOutResX);
        nOYSize = ceil ((Env.MinY - Env.MaxY) / (adfGeoTransform[5] < 0 ? dfOutResY * -1 : dfOutResY));
    }

/* ==================================================================== */
/*      Create a virtual dataset.                                       */
/* ==================================================================== */
    VRTDataset *poVDS;
/* -------------------------------------------------------------------- */
/*      Make a virtual clone.                                           */
/* -------------------------------------------------------------------- */
    poVDS = (VRTDataset *) VRTCreate( nOXSize, nOYSize );

    if( pSrcRasterDataSet->GetSpatialReference() != NULL )
    {
		poVDS->SetProjection( pDset->GetProjectionRef() );
    }

	adfGeoTransform[0] += anSrcWin[0] * adfGeoTransform[1] + anSrcWin[1] * adfGeoTransform[2];
    adfGeoTransform[3] += anSrcWin[0] * adfGeoTransform[4] + anSrcWin[1] * adfGeoTransform[5];

    adfGeoTransform[1] *= anSrcWin[2] / (double) nOXSize;
    adfGeoTransform[2] *= anSrcWin[3] / (double) nOYSize;
    adfGeoTransform[4] *= anSrcWin[2] / (double) nOXSize;
    adfGeoTransform[5] *= anSrcWin[3] / (double) nOYSize;

    poVDS->SetGeoTransform( adfGeoTransform );

    int nGCPs = pDset->GetGCPCount();
    if( nGCPs > 0 )
    {
        GDAL_GCP *pasGCPs = GDALDuplicateGCPs( nGCPs, pDset->GetGCPs() );

        for(size_t i = 0; i < nGCPs; ++i )
        {
            pasGCPs[i].dfGCPPixel -= anSrcWin[0];
            pasGCPs[i].dfGCPLine  -= anSrcWin[1];
            pasGCPs[i].dfGCPPixel *= (nOXSize / (double) anSrcWin[2] );
            pasGCPs[i].dfGCPLine  *= (nOYSize / (double) anSrcWin[3] );
        }

        poVDS->SetGCPs( nGCPs, pasGCPs, pDset->GetGCPProjection() );
        GDALDeinitGCPs( nGCPs, pasGCPs );
        CPLFree( pasGCPs );
    }

/* -------------------------------------------------------------------- */
/*      Transfer generally applicable metadata.                         */
/* -------------------------------------------------------------------- */
    if(!bSkipSourceMetadata)
        poVDS->SetMetadata( pDset->GetMetadata() );

/* ==================================================================== */
/*      Process all bands.                                              */
/* ==================================================================== */
    for(size_t i = 0; i < nBandCount; ++i )
    {
        VRTSourcedRasterBand *poVRTBand;
        GDALRasterBand *poSrcBand;
        GDALDataType eBandType;
        int nComponent = 0;

        poSrcBand = pDset->GetRasterBand(panBandList[i]);

/* -------------------------------------------------------------------- */
/*      Select output data type to match source.                        */
/* -------------------------------------------------------------------- */
        if( eOutputType == GDT_Unknown )
            eBandType = poSrcBand->GetRasterDataType();
        else
            eBandType = eOutputType;
/* -------------------------------------------------------------------- */
/*      Create this band.                                               */
/* -------------------------------------------------------------------- */
        poVDS->AddBand( eBandType, NULL );
        poVRTBand = (VRTSourcedRasterBand *) poVDS->GetRasterBand( i + 1 );
/* -------------------------------------------------------------------- */
/*      Create a simple data source depending on the                    */
/*      translation type required.                                      */
/* -------------------------------------------------------------------- */
        //if( bUnscale || bScale || (nRGBExpand != 0 && i < nRGBExpand) )
        //{
        //    poVRTBand->AddComplexSource( poSrcBand,
        //                                 anSrcWin[0], anSrcWin[1],
        //                                 anSrcWin[2], anSrcWin[3],
        //                                 0, 0, nOXSize, nOYSize,
        //                                 dfOffset, dfScale,
        //                                 VRT_NODATA_UNSET,
        //                                 nComponent );
        //}
        //else
        CPLString pszResampling = CSLFetchNameValueDef(papszOptions, "DEST_RESAMPLING", "near");
        poVRTBand->AddSimpleSource( poSrcBand, anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize, pszResampling );

/* -------------------------------------------------------------------- */
/*      copy some other information of interest.                        */
/* -------------------------------------------------------------------- */
		CopyBandInfo( poSrcBand, poVRTBand, bCopyNodata );
/* -------------------------------------------------------------------- */
/*      Set a forcable nodata value?                                    */
/* -------------------------------------------------------------------- */
//        if( bSetNoData )
//        {
//            double dfVal = dfNoDataReal;
//            int bClamped = FALSE, bRounded = FALSE;
//
//#define CLAMP(val,type,minval,maxval) \
//    do { if (val < minval) { bClamped = TRUE; val = minval; } \
//    else if (val > maxval) { bClamped = TRUE; val = maxval; } \
//    else if (val != (type)val) { bRounded = TRUE; val = (type)(val + 0.5); } } \
//    while(0)
//
//            switch(eBandType)
//            {
//                case GDT_Byte:
//                    CLAMP(dfVal, GByte, 0.0, 255.0);
//                    break;
//                case GDT_Int16:
//                    CLAMP(dfVal, GInt16, -32768.0, 32767.0);
//                    break;
//                case GDT_UInt16:
//                    CLAMP(dfVal, GUInt16, 0.0, 65535.0);
//                    break;
//                case GDT_Int32:
//                    CLAMP(dfVal, GInt32, -2147483648.0, 2147483647.0);
//                    break;
//                case GDT_UInt32:
//                    CLAMP(dfVal, GUInt32, 0.0, 4294967295.0);
//                    break;
//                default:
//                    break;
//            }
//
//            if (bClamped)
//            {
//                printf( "for band %d, nodata value has been clamped "
//                       "to %.0f, the original value being out of range.\n",
//                       i + 1, dfVal);
//            }
//            else if(bRounded)
//            {
//                printf("for band %d, nodata value has been rounded "
//                       "to %.0f, %s being an integer datatype.\n",
//                       i + 1, dfVal,
//                       GDALGetDataTypeName(eBandType));
//            }
//
//            poVRTBand->SetNoDataValue( dfVal );
//        }

        //if (eMaskMode == MASK_AUTO &&
        //    (GDALGetMaskFlags(GDALGetRasterBand(hDataset, 1)) & GMF_PER_DATASET) == 0 &&
        //    (poSrcBand->GetMaskFlags() & (GMF_ALL_VALID | GMF_NODATA)) == 0)
        //{
        //    if (poVRTBand->CreateMaskBand(poSrcBand->GetMaskFlags()) == CE_None)
        //    {
        //        VRTSourcedRasterBand* hMaskVRTBand =
        //            (VRTSourcedRasterBand*)poVRTBand->GetMaskBand();
        //        hMaskVRTBand->AddMaskBandSource(poSrcBand,
        //                                anSrcWin[0], anSrcWin[1],
        //                                anSrcWin[2], anSrcWin[3],
        //                                0, 0, nOXSize, nOYSize );
        //    }
        //}
    }

    //if (eMaskMode == MASK_USER)
    //{
    //    GDALRasterBand *poSrcBand =
    //        (GDALRasterBand*)GDALGetRasterBand(hDataset, ABS(nMaskBand));
    //    if (poSrcBand && poVDS->CreateMaskBand(GMF_PER_DATASET) == CE_None)
    //    {
    //        VRTSourcedRasterBand* hMaskVRTBand = (VRTSourcedRasterBand*)
    //            GDALGetMaskBand(GDALGetRasterBand((GDALDatasetH)poVDS, 1));
    //        if (nMaskBand > 0)
    //            hMaskVRTBand->AddSimpleSource(poSrcBand,
    //                                    anSrcWin[0], anSrcWin[1],
    //                                    anSrcWin[2], anSrcWin[3],
    //                                    0, 0, nOXSize, nOYSize );
    //        else
    //            hMaskVRTBand->AddMaskBandSource(poSrcBand,
    //                                    anSrcWin[0], anSrcWin[1],
    //                                    anSrcWin[2], anSrcWin[3],
    //                                    0, 0, nOXSize, nOYSize );
    //    }
    //}
    //else
    //if (eMaskMode == MASK_AUTO && nSrcBandCount > 0 &&
    //    GDALGetMaskFlags(GDALGetRasterBand(hDataset, 1)) == GMF_PER_DATASET)
    //{
    //    if (poVDS->CreateMaskBand(GMF_PER_DATASET) == CE_None)
    //    {
    //        VRTSourcedRasterBand* hMaskVRTBand = (VRTSourcedRasterBand*)
    //            GDALGetMaskBand(GDALGetRasterBand((GDALDatasetH)poVDS, 1));
    //        hMaskVRTBand->AddMaskBandSource((GDALRasterBand*)GDALGetRasterBand(hDataset, 1),
    //                                    anSrcWin[0], anSrcWin[1],
    //                                    anSrcWin[2], anSrcWin[3],
    //                                    0, 0, nOXSize, nOYSize );
    //    }
    //}

/* -------------------------------------------------------------------- */
/*      Write to the output file using CopyCreate().                    */
/* -------------------------------------------------------------------- */
    GDALDataset* pOutDS = pDriver->CreateCopy(szDstPath, poVDS, false, papszOptions, GDALDummyProgress, NULL);

    //hOutDS = GDALCreateCopy( hDriver, pszDest, (GDALDatasetH) poVDS, bStrict, papszCreateOptions, pfnProgress, NULL );
    if( pOutDS )
    {
        CPLErrorReset();
        GDALFlushCache( pOutDS );
        if (CPLGetLastErrorType() != CE_None)
        {
		    if(pTrackCancel)
			    pTrackCancel->PutMessage(_("GDALFlushCache failed!"), -1, enumGISMessageErr);
        }
        GDALClose( pOutDS );

        GDALClose( poVDS );
        return true;
    }
    else
    {
        GDALClose( poVDS );
        return false;
    }


    //CPLFree( panBandList );
    //
    //CPLFree( pszOutputSRS );

    //if( !bSubCall )
    //{
    //    GDALDumpOpenDatasets( stderr );
    //    GDALDestroyDriverManager();
    //}
    //CSLDestroy( papszCreateOptions );

	return true;
}
/**
* Checks the downloaded data to see if it is all valid.
*/
void ncepNamSurfInitialization::checkForValidData()
{
    //just make up a "dummy" timezone for use here
    boost::local_time::time_zone_ptr zone(new boost::local_time::posix_time_zone("MST-07"));

    //get time list
    std::vector<boost::local_time::local_date_time> timeList( getTimeList(zone) );

    boost::posix_time::ptime pt_low(boost::gregorian::date(1900,boost::gregorian::Jan,1), boost::posix_time::hours(12));
    boost::posix_time::ptime pt_high(boost::gregorian::date(2100,boost::gregorian::Jan,1), boost::posix_time::hours(12));
    boost::local_time::local_date_time low_time(pt_low, zone);
    boost::local_time::local_date_time high_time(pt_high, zone);

    //check times
    for(unsigned int i = 0; i < timeList.size(); i++)
    {
        if(timeList[i].is_special())    //if time is any special value (not_a_date_time, infinity, etc.)
            throw badForecastFile("Bad time in forecast file.");
        if(timeList[i] < low_time || timeList[i] > high_time)
            throw badForecastFile("Bad time in forecast file.");
    }

    // open ds variable by variable
    GDALDataset *srcDS;
    std::string temp;
    std::string srcWkt;
    int nBands = 0;
    bool noDataValueExists;
    bool noDataIsNan;

    std::vector<std::string> varList = getVariableList();

    //Acquire a lock to protect the non-thread safe netCDF library
#ifdef _OPENMP
    omp_guard netCDF_guard(netCDF_lock);
#endif

    for( unsigned int i = 0;i < varList.size();i++ ) {

        temp = "NETCDF:" + wxModelFileName + ":" + varList[i];

        srcDS = (GDALDataset*)GDALOpen( temp.c_str(), GA_ReadOnly );
        if( srcDS == NULL )
            throw badForecastFile("Cannot open forecast file.");

        srcWkt = srcDS->GetProjectionRef();

        if( srcWkt.empty() )
            throw badForecastFile("Forecast file doesn't have projection information.");

        //Get total bands (time steps)
        nBands = srcDS->GetRasterCount();
        int nXSize, nYSize;
        GDALRasterBand *poBand;
        int pbSuccess;
        double dfNoData;
        double *padfScanline;

        nXSize = srcDS->GetRasterXSize();
        nYSize = srcDS->GetRasterYSize();

        //loop over all bands for this variable (bands are time steps)
        for(int j = 1; j <= nBands; j++)
        {
            poBand = srcDS->GetRasterBand( j );

            pbSuccess = 0;
            dfNoData = poBand->GetNoDataValue( &pbSuccess );
            if( pbSuccess == false )
                noDataValueExists = false;
            else
            {
                noDataValueExists = true;
                noDataIsNan = CPLIsNan(dfNoData);
            }

            //set the data
            padfScanline = new double[nXSize*nYSize];
            poBand->RasterIO(GF_Read, 0, 0, nXSize, nYSize, padfScanline, nXSize, nYSize,
                    GDT_Float64, 0, 0);
            for(int k = 0;k < nXSize*nYSize; k++)
            {
                //Check if value is no data (if no data value was defined in file)
                if(noDataValueExists)
                {
                    if(noDataIsNan)
                    {
                        if(CPLIsNan(padfScanline[k]))
                            throw badForecastFile("Forecast file contains no_data values.");
                    }else
                    {
                        if(padfScanline[k] == dfNoData)
                            throw badForecastFile("Forecast file contains no_data values.");
                    }
                }

                if( varList[i] == "Temperature_height_above_ground" )   //units are Kelvin
                {
                    if(padfScanline[k] < 180.0 || padfScanline[k] > 340.0)  //these are near the most extreme temperatures ever recored on earth
                        throw badForecastFile("Temperature is out of range in forecast file.");
                }
                else if( varList[i] == "v-component_of_wind_height_above_ground" )  //units are m/s
                {
                    if(std::abs(padfScanline[k]) > 220.0)
                        throw badForecastFile("V-velocity is out of range in forecast file.");
                }
                else if( varList[i] == "u-component_of_wind_height_above_ground" )  //units are m/s
                {
                    if(std::abs(padfScanline[k]) > 220.0)
                        throw badForecastFile("U-velocity is out of range in forecast file.");
                }
                else if( varList[i] == "Total_cloud_cover_entire_atmosphere" )  //units are percent
                {
                    if(padfScanline[k] < 0.0 || padfScanline[k] > 100.0)
                        throw badForecastFile("Total cloud cover is out of range in forecast file.");
                }
            }

            delete [] padfScanline;
        }

        GDALClose((GDALDatasetH) srcDS );
    }
}
/**
* Sets the surface grids based on a ncepNam (surface only!) forecast.
* @param input The WindNinjaInputs for misc. info.
* @param airGrid The air temperature grid to be filled.
* @param cloudGrid The cloud cover grid to be filled.
* @param uGrid The u velocity grid to be filled.
* @param vGrid The v velocity grid to be filled.
* @param wGrid The w velocity grid to be filled (filled with zeros here?).
*/
void ncepNamSurfInitialization::setSurfaceGrids( WindNinjaInputs &input,
        AsciiGrid<double> &airGrid,
        AsciiGrid<double> &cloudGrid,
        AsciiGrid<double> &uGrid,
        AsciiGrid<double> &vGrid,
        AsciiGrid<double> &wGrid )
{
    int bandNum = -1;
    //get time list
    std::vector<boost::local_time::local_date_time> timeList( getTimeList(input.ninjaTimeZone) );
    //Search time list for our time to identify our band number for cloud/speed/dir
    for(unsigned int i = 0; i < timeList.size(); i++)
    {
        if(input.ninjaTime == timeList[i])
        {
            bandNum = i + 1;
            break;
        }
    }
    if(bandNum < 0)
        throw std::runtime_error("Could not match ninjaTime with a band number in the forecast file.");

    //get some info from the nam file in input

    //Acquire a lock to protect the non-thread safe netCDF library
#ifdef _OPENMP
    omp_guard netCDF_guard(netCDF_lock);
#endif

    GDALDataset* poDS;

    //attempt to grab the projection from the dem?
    //check for member prjString first
    std::string dstWkt;
    dstWkt = input.dem.prjString;
    if ( dstWkt.empty() ) {
        //try to open original
        poDS = (GDALDataset*)GDALOpen( input.dem.fileName.c_str(), GA_ReadOnly );
        if( poDS == NULL ) {
            CPLDebug( "ncepNamSurfInitialization::setSurfaceGrids()",
                    "Bad projection reference" );
            //throw();
        }
        dstWkt = poDS->GetProjectionRef();
        if( dstWkt.empty() ) {
            CPLDebug( "ncepNamSurfInitialization::setSurfaceGrids()",
                    "Bad projection reference" );
            //throw()
        }
        GDALClose((GDALDatasetH) poDS );
    }

    poDS = (GDALDataset*)GDALOpen( input.forecastFilename.c_str(), GA_ReadOnly );

    if( poDS == NULL ) {
        CPLDebug( "ncepNamSurfInitialization::setSurfaceGrids()",
                "Bad forecast file" );
    }
    else
        GDALClose((GDALDatasetH) poDS );

    // open ds one by one and warp, then write to grid
    GDALDataset *srcDS, *wrpDS;
    std::string temp;
    std::string srcWkt;

    std::vector<std::string> varList = getVariableList();

    /*
     * Set the initial values in the warped dataset to no data
     */
    GDALWarpOptions* psWarpOptions;

    for( unsigned int i = 0;i < varList.size();i++ ) {

        temp = "NETCDF:" + input.forecastFilename + ":" + varList[i];

        srcDS = (GDALDataset*)GDALOpenShared( temp.c_str(), GA_ReadOnly );
        if( srcDS == NULL ) {
            CPLDebug( "ncepNamSurfInitialization::setSurfaceGrids()",
                    "Bad forecast file" );
        }

        srcWkt = srcDS->GetProjectionRef();

        if( srcWkt.empty() ) {
            CPLDebug( "ncepNamSurfInitialization::setSurfaceGrids()",
                    "Bad forecast file" );
            //throw
        }

        /*
         * Grab the first band to get the nodata value for the variable,
         * assume all bands have the same ndv
         */
        GDALRasterBand *poBand = srcDS->GetRasterBand( 1 );
        int pbSuccess;
        double dfNoData = poBand->GetNoDataValue( &pbSuccess );

        psWarpOptions = GDALCreateWarpOptions();

        int nBandCount = srcDS->GetRasterCount();
        psWarpOptions->nBandCount = nBandCount;
        psWarpOptions->panSrcBands = 
            (int*) CPLMalloc( sizeof( int ) * nBandCount );
        psWarpOptions->panDstBands = 
            (int*) CPLMalloc( sizeof( int ) * nBandCount );
        psWarpOptions->padfDstNoDataReal =
            (double*) CPLMalloc( sizeof( double ) * nBandCount );
        psWarpOptions->padfDstNoDataImag =
            (double*) CPLMalloc( sizeof( double ) * nBandCount );

        for( int b = 0;b < srcDS->GetRasterCount();b++ ) {
            psWarpOptions->padfDstNoDataReal[b] = dfNoData;
            psWarpOptions->padfDstNoDataImag[b] = dfNoData;
         }

        if( pbSuccess == FALSE )
            dfNoData = -9999.0;

        psWarpOptions->papszWarpOptions =
            CSLSetNameValue( psWarpOptions->papszWarpOptions,
                             "INIT_DEST", "NO_DATA" );

        wrpDS = (GDALDataset*) GDALAutoCreateWarpedVRT( srcDS, srcWkt.c_str(),
                                                        dstWkt.c_str(),
                                                        GRA_NearestNeighbour,
                                                        1.0, psWarpOptions );
        if(wrpDS == NULL)
        {
            throw badForecastFile("Could not warp the forecast file, "
                                  "possibly non-uniform grid.");
        }

        if( varList[i] == "Temperature_height_above_ground" ) {
            GDAL2AsciiGrid( wrpDS, bandNum, airGrid );
        if( CPLIsNan( dfNoData ) ) {
        airGrid.set_noDataValue(-9999.0);
        airGrid.replaceNan( -9999.0 );
        }
    }
        else if( varList[i] == "v-component_of_wind_height_above_ground" ) {
            GDAL2AsciiGrid( wrpDS, bandNum, vGrid );
        if( CPLIsNan( dfNoData ) ) {
        vGrid.set_noDataValue(-9999.0);
        vGrid.replaceNan( -9999.0 );
        }
    }
        else if( varList[i] == "u-component_of_wind_height_above_ground" ) {
            GDAL2AsciiGrid( wrpDS, bandNum, uGrid );
        if( CPLIsNan( dfNoData ) ) {
        uGrid.set_noDataValue(-9999.0);
        uGrid.replaceNan( -9999.0 );
        }
    }
    else if( varList[i] == "Total_cloud_cover_entire_atmosphere" ) {
            GDAL2AsciiGrid( wrpDS, bandNum, cloudGrid );
        if( CPLIsNan( dfNoData ) ) {
        cloudGrid.set_noDataValue(-9999.0);
        cloudGrid.replaceNan( -9999.0 );
        }
    }

        GDALDestroyWarpOptions( psWarpOptions );
        GDALClose((GDALDatasetH) srcDS );
        GDALClose((GDALDatasetH) wrpDS );
    }
    cloudGrid /= 100.0;

    wGrid.set_headerData( uGrid );
    wGrid = 0.0;
}
Example #6
0
int GDALOverviewDataset::GetGCPCount()

{
    return poMainDS->GetGCPCount();
}
Example #7
0
const char *GDALOverviewDataset::GetGCPProjection()

{
    return poMainDS->GetGCPProjection();
}
Example #8
0
const QString OmgGdal::Gdal2Ascii(const QString theFileName)
{
  std::cout << "Running gdal to ascii conversion..." << std::endl;
  QFileInfo myFileInfo(theFileName);
  QString myExt("asc");
  QString myOutFileName(QDir::convertSeparators(myFileInfo.dirPath(true)+"/"+myFileInfo.baseName() + "." + myExt));
  QFile myFile( myOutFileName );
  if ( !myFile.open( IO_WriteOnly ) )
  {
    printf("Opening output file for write failed");
    return QString("");
  }
  QTextStream myStream( &myFile );
  GDALAllRegister();
  GDALDataset  *gdalDataset = (GDALDataset *) GDALOpen( theFileName.local8Bit(), GA_ReadOnly );
  if ( gdalDataset == NULL )
  {
    std::cout <<  "Error couldn't open file: " << theFileName << std::endl;
    return QString("");
  }

  //Write the ascii headers
  myStream << getAsciiHeader(theFileName);

  //assume to be working with first band in dataset only
  GDALRasterBand  *myGdalBand = gdalDataset->GetRasterBand( 1 );
  //find out the name of the band if any
  QString myColorInterpretation = GDALGetColorInterpretationName(myGdalBand->GetColorInterpretation());
  // get the dimensions of the raster
  int myColsInt = myGdalBand->GetXSize();
  int myRowsInt = myGdalBand->GetYSize();
  double myNullValue=myGdalBand->GetNoDataValue();
  //allocate a buffer to hold one row of ints
  int myAllocationSizeInt = sizeof(uint)*myColsInt;
  uint * myScanlineAllocInt = (uint*) CPLMalloc(myAllocationSizeInt);
  for (int myCurrentRowInt=0; myCurrentRowInt < myRowsInt;myCurrentRowInt++)
  {
    //get a scanline
    CPLErr myResult = myGdalBand->RasterIO(
                        GF_Read, 0,
                        myCurrentRowInt,
                        myColsInt,
                        1,
                        myScanlineAllocInt,
                        myColsInt,
                        1,
                        GDT_UInt32,
                        0,
                        0 );
    for (int myCurrentColInt=0; myCurrentColInt < myColsInt; myCurrentColInt++)
    {
      //get the nth element from the current row
      double myDouble=myScanlineAllocInt[myCurrentColInt];
      myStream << myDouble << " "; //pixel value
    } //end of column wise loop
    myStream << "\r\n"; //dos style new line
  } //end of row wise loop
  CPLFree(myScanlineAllocInt);
  myFile.close();
  std::cout << "The output ascii file is: " << myOutFileName << std::endl;
  return myOutFileName;
}
Example #9
0
int FindSRS( const char *pszInput, OGRSpatialReference &oSRS )

{
    int            bGotSRS = FALSE;
    VSILFILE      *fp = NULL;
    GDALDataset	  *poGDALDS = NULL; 
    OGRDataSource *poOGRDS = NULL;
    OGRLayer      *poLayer = NULL;
    char           *pszProjection = NULL;
    CPLErrorHandler oErrorHandler = NULL;
    int bIsFile = FALSE;
    OGRErr eErr = CE_None;
    int bDebug  = FALSE;

    /* temporarily supress error messages we may get from xOpen() */
    bDebug = CSLTestBoolean(CPLGetConfigOption("CPL_DEBUG", "OFF"));
    if ( ! bDebug )
        oErrorHandler = CPLSetErrorHandler ( CPLQuietErrorHandler );

    /* Test if argument is a file */
    fp = VSIFOpenL( pszInput, "r" );
    if ( fp )  {
        bIsFile = TRUE;
        VSIFCloseL( fp );
        CPLDebug( "gdalsrsinfo", "argument is a file" );
    } 
       
    /* try to open with GDAL */
    CPLDebug( "gdalsrsinfo", "trying to open with GDAL" );
    poGDALDS = (GDALDataset *) GDALOpen( pszInput, GA_ReadOnly );
    if ( poGDALDS != NULL && poGDALDS->GetProjectionRef( ) != NULL ) {
        pszProjection = (char *) poGDALDS->GetProjectionRef( );
        if( oSRS.importFromWkt( &pszProjection ) == CE_None ) {
            CPLDebug( "gdalsrsinfo", "got SRS from GDAL" );
            bGotSRS = TRUE;
        }
        GDALClose( (GDALDatasetH) poGDALDS );
        if ( ! bGotSRS ) 
            CPLDebug( "gdalsrsinfo", "did not open with GDAL" );
    }    
    
#ifdef OGR_ENABLED
    /* if unsuccessful, try to open with OGR */
    if ( ! bGotSRS ) {
        CPLDebug( "gdalsrsinfo", "trying to open with OGR" );
        poOGRDS = OGRSFDriverRegistrar::Open( pszInput, FALSE, NULL );
        if( poOGRDS != NULL ) {
            poLayer = poOGRDS->GetLayer( 0 );
            if ( poLayer != NULL ) {
                OGRSpatialReference *poSRS = poLayer->GetSpatialRef( );
                if ( poSRS != NULL ) {
                    CPLDebug( "gdalsrsinfo", "got SRS from OGR" );
                    bGotSRS = TRUE;
                    OGRSpatialReference* poSRSClone = poSRS->Clone();
                    oSRS = *poSRSClone;
                    OGRSpatialReference::DestroySpatialReference( poSRSClone );
                }
            }
            OGRDataSource::DestroyDataSource( poOGRDS );
            poOGRDS = NULL;
        } 
        if ( ! bGotSRS ) 
            CPLDebug( "gdalsrsinfo", "did not open with OGR" );
    }
#endif // OGR_ENABLED
    
    /* Try ESRI file */
    if ( ! bGotSRS && bIsFile && (strstr(pszInput,".prj") != NULL) ) {
        CPLDebug( "gdalsrsinfo", 
                  "trying to get SRS from ESRI .prj file [%s]", pszInput );

        char **pszTemp;
        if ( strstr(pszInput,"ESRI::") != NULL )
            pszTemp = CSLLoad( pszInput+6 );
        else 
            pszTemp = CSLLoad( pszInput );

        if( pszTemp ) {
            eErr = oSRS.importFromESRI( pszTemp );
            CSLDestroy( pszTemp );
        }
        else 
            eErr = OGRERR_UNSUPPORTED_SRS;

        if( eErr != OGRERR_NONE ) {
            CPLDebug( "gdalsrsinfo", "did not get SRS from ESRI .prj file" );
        }
        else {
            CPLDebug( "gdalsrsinfo", "got SRS from ESRI .prj file" );
            bGotSRS = TRUE;
        }
    }

    /* Last resort, try OSRSetFromUserInput() */
    if ( ! bGotSRS ) {
        CPLDebug( "gdalsrsinfo", 
                  "trying to get SRS from user input [%s]", pszInput );

        eErr = oSRS.SetFromUserInput( pszInput );
 
       if(  eErr != OGRERR_NONE ) {
            CPLDebug( "gdalsrsinfo", "did not get SRS from user input" );
        }
        else {
            CPLDebug( "gdalsrsinfo", "got SRS from user input" );
            bGotSRS = TRUE;
        }
    }
    
    /* restore error messages */
    if ( ! bDebug )
        CPLSetErrorHandler ( oErrorHandler );	


    return bGotSRS;
}
Example #10
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 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
      pvDebug().printf("[%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 );
      pvDebug().printf("[%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);
      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
      pvDebug().printf("[%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{
         pvError() << "Image data type " << GDALGetDataTypeName(dataType) << " not implemented for image rescaling\n";
      }

      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;

               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;

               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
         pvDebug().printf("[%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);
   }
#else
   pvError().printf(GDAL_CONFIG_ERR_STR);
#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{
            pvError() << "Image data type " << GDALGetDataTypeName(dataType) << " not implemented for image rescaling\n";
         }
         for( int n=0; n<numTotal; n++ ) {
            buf[n] *= fac;
         }
      }
   }
   return status;
}
Example #11
0
int Image::readImageFileGDAL(char const * filename, PVLayerLoc const * loc) {
   assert(parent->columnId()==0);

   GDALAllRegister();

   GDALDataset * dataset = PV_GDALOpen(filename);
   if (dataset==NULL) { return PV_FAILURE; } // PV_GDALOpen prints an error message.
   GDALRasterBand * poBand = dataset->GetRasterBand(1);
   GDALDataType dataType = poBand->GetRasterDataType();

   // 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)
   bool isBinary = true;
   for(int iBand = 0; iBand < GDALGetRasterCount(dataset); iBand++){
      GDALRasterBandH hBand = GDALGetRasterBand(dataset, iBand+1);
      char ** 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;
      }
   }

   int const xImageSize = imageLoc.nxGlobal;
   int const yImageSize = imageLoc.nyGlobal;
   int const bandsInFile = imageLoc.nf;

   int numTotal = xImageSize * yImageSize * bandsInFile;

   dataset->RasterIO(GF_Read, 0, 0, xImageSize, yImageSize, imageData,
         xImageSize, yImageSize, GDT_Float32, bandsInFile, NULL,
         bandsInFile*sizeof(float), bandsInFile*xImageSize*sizeof(float), sizeof(float));


   GDALClose(dataset);
   if(!isBinary){
      pvadata_t 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{
         pvError().printf("Image data type %s in file \"%s\" is not implemented.\n", GDALGetDataTypeName(dataType), filename);
      }
      for( int n=0; n<numTotal; n++ ) {
         imageData[n] *= fac;
      }
   }
   return EXIT_SUCCESS;
}
Example #12
0
int setImageLayerMemoryBuffer(InterColComm * icComm, char const * imageFile, ImageFromMemoryBuffer * imageLayer, uint8_t ** imageBufferPtr, size_t * imageBufferSizePtr)
{
   // Under MPI, only the root process (rank==0) uses imageFile, imageBufferPtr, or imageBufferSizePtr, but nonroot processes need to call it as well,
   // because the imegeBuffer is scattered to all processes during the call to ImageFromMemoryBuffer::setMemoryBuffer().
   int layerNx = imageLayer->getLayerLoc()->nxGlobal;
   int layerNy = imageLayer->getLayerLoc()->nyGlobal;
   int layerNf = imageLayer->getLayerLoc()->nf;
   int bufferNx, bufferNy, bufferNf;
   const uint8_t zeroVal = (uint8_t) 0;
   const uint8_t oneVal = (uint8_t) 255;
   int xStride, yStride, bandStride;
   int rank = icComm->commRank();
   if (rank==0) {
      // Doubleplusungood: much code duplication from PV::Image::readImage
      bool usingTempFile = false;
      char * path = NULL;
      if (strstr(imageFile, "://") != NULL) {
         printf("Image from URL \"%s\"\n", imageFile);
         usingTempFile = true;
         std::string pathstring = "/tmp/temp.XXXXXX";
         const char * ext = strrchr(imageFile, '.');
         if (ext) { pathstring += ext; }
         path = strdup(pathstring.c_str());
         int fid;
         fid=mkstemps(path, strlen(ext));
         if (fid<0) {
            fprintf(stderr,"Cannot create temp image file for image \"%s\".\n", imageFile);
            exit(EXIT_FAILURE);
         }   
         close(fid);
         std::string systemstring;
         if (strstr(imageFile, "s3://") != NULL) {
            systemstring = "aws s3 cp \'";
            systemstring += imageFile;
            systemstring += "\' ";
            systemstring += path;
         }   
         else { // URLs other than s3://
            systemstring = "wget -O ";
            systemstring += path;
            systemstring += " \'";
            systemstring += imageFile;
            systemstring += "\'";
         }   

         int const numAttempts = MAX_FILESYSTEMCALL_TRIES;
         for(int attemptNum = 0; attemptNum < numAttempts; attemptNum++){
            int status = system(systemstring.c_str());
            if(status != 0){ 
               if(attemptNum == numAttempts - 1){ 
                  fprintf(stderr, "download command \"%s\" failed: %s.  Exiting\n", systemstring.c_str(), strerror(errno));
                  exit(EXIT_FAILURE);
               }   
               else{
                  fprintf(stderr, "download command \"%s\" failed: %s.  Retrying %d out of %d.\n", systemstring.c_str(), strerror(errno), attemptNum+1, numAttempts);
                  sleep(1);
               }
            }
            else{
               break;
            }
         }
      }
      else {
         printf("Image from file \"%s\"\n", imageFile);
         path = strdup(imageFile);
      }
      GDALDataset * gdalDataset = PV_GDALOpen(path);
      if (gdalDataset==NULL)
      {
         fprintf(stderr, "setImageLayerMemoryBuffer: GDALOpen failed for image \"%s\".\n", imageFile);
         exit(EXIT_FAILURE);
      }
      int imageNx= gdalDataset->GetRasterXSize();
      int imageNy = gdalDataset->GetRasterYSize();
      int imageNf = GDALGetRasterCount(gdalDataset);
      // Need to rescale so that the the short side of the image equals the short side of the layer
      // ImageFromMemoryBuffer layer will handle the cropping.
      double xScaleFactor = (double)layerNx / (double) imageNx;
      double yScaleFactor = (double)layerNy / (double) imageNy;
      size_t imageBufferSize = *imageBufferSizePtr;
      uint8_t * imageBuffer = *imageBufferPtr;
      if (xScaleFactor < yScaleFactor) /* need to rescale so that bufferNy=layerNy and bufferNx>layerNx */
      {
         bufferNx = (int) round(imageNx * yScaleFactor);
         bufferNy = layerNy;
      }
      else {
         bufferNx = layerNx;
         bufferNy = (int) round(imageNy * xScaleFactor);
      }
      bufferNf = layerNf;
      size_t newImageBufferSize = (size_t)bufferNx * (size_t)bufferNy * (size_t)bufferNf;
      if (imageBuffer==NULL || newImageBufferSize != imageBufferSize)
      {
         imageBufferSize = newImageBufferSize;
         imageBuffer = (uint8_t *) realloc(imageBuffer, imageBufferSize*sizeof(uint8_t));
         if (imageBuffer==NULL)
         {
            fprintf(stderr, "setImageLayerMemoryBuffer: Unable to resize image buffer to %d-by-%d-by-%d for image \"%s\": %s\n",
                  bufferNx, bufferNy, bufferNf, imageFile, strerror(errno));
            exit(EXIT_FAILURE);
         }
      }

      bool isBinary = true;
      for (int iBand=0;iBand<imageNf; iBand++)
      {
         GDALRasterBandH hBand = GDALGetRasterBand(gdalDataset,iBand+1);
         char ** 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;
                  isBinary &= true;
                  break;
               }
            }
            if(!found){
               isBinary &= false;
            }
         }
         else{
            isBinary = false;
         }
         GDALDataType dataType = gdalDataset->GetRasterBand(iBand+1)->GetRasterDataType(); // Why are we using both GDALGetRasterBand and GDALDataset::GetRasterBand?
         if (dataType != GDT_Byte)
         {
            fprintf(stderr, "setImageLayerMemoryBuffer: Image file \"%s\", band %d, is not GDT_Byte type.\n", imageFile, iBand+1);
            exit(EXIT_FAILURE);
         }
      }

#ifdef PV_USE_OPENMP_THREADS
#pragma omp parallel for
#endif
      for (size_t n=0; n < imageBufferSize; n++)
      {
         imageBuffer[n] = oneVal;
      }

      xStride = bufferNf;
      yStride = bufferNf * bufferNx;
      bandStride = 1;
      gdalDataset->RasterIO(GF_Read, 0/*xOffset*/, 0/*yOffset*/, imageNx, imageNy, imageBuffer, bufferNx, bufferNy,
            GDT_Byte, layerNf, NULL, xStride*sizeof(uint8_t), yStride*sizeof(uint8_t), bandStride*sizeof(uint8_t));

      GDALClose(gdalDataset);
      if (usingTempFile) {
         int rmstatus = remove(path);
         if (rmstatus) {
            fprintf(stderr, "remove(\"%s\") failed.  Exiting.\n", path);
            exit(EXIT_FAILURE);
         }    
      }
      free(path);

      *imageBufferPtr = imageBuffer;
      *imageBufferSizePtr = imageBufferSize;

      int buffersize[3];
      buffersize[0] = bufferNx;
      buffersize[1] = bufferNy;
      buffersize[2] = bufferNf;
      MPI_Bcast(buffersize, 3, MPI_INT, 0, icComm->communicator());
   }
   else {
      int buffersize[3];
      MPI_Bcast(buffersize, 3, MPI_INT, 0, icComm->communicator());
      bufferNx = buffersize[0];
      bufferNy = buffersize[1];
      bufferNf = buffersize[2];
      xStride = bufferNf;
      yStride = bufferNf * bufferNx;
      bandStride = 1;
   }
   imageLayer->setMemoryBuffer(*imageBufferPtr, bufferNy, bufferNx, bufferNf, xStride, yStride, bandStride, zeroVal, oneVal);
   return PV_SUCCESS;
}