コード例 #1
0
void GDALPamRasterBand::PamInitialize()

{
    if( psPam )
        return;

    GDALPamDataset *poParentDS = (GDALPamDataset *) GetDataset();

    if( poParentDS == NULL || !(poParentDS->GetMOFlags() & GMO_PAM_CLASS) )
        return;

    poParentDS->PamInitialize();
    if( poParentDS->psPam == NULL )
        return;

    // Often (always?) initializing our parent will have initialized us. 
    if( psPam != NULL )
        return;

    psPam = (GDALRasterBandPamInfo *)
        CPLCalloc(sizeof(GDALRasterBandPamInfo),1);

    psPam->dfScale = 1.0;
    psPam->poParentDS = poParentDS;
    psPam->dfNoDataValue = -1e10;
    psPam->poDefaultRAT = NULL;
}
コード例 #2
0
ファイル: gdalpamrasterband.cpp プロジェクト: ksshannon/gdal
void GDALPamRasterBand::PamInitialize()

{
    if( psPam )
        return;

    GDALDataset* poNonPamParentDS = GetDataset();
    if( poNonPamParentDS == nullptr ||
        !(poNonPamParentDS->GetMOFlags() & GMO_PAM_CLASS) )
        return;

    GDALPamDataset *poParentDS =
        dynamic_cast<GDALPamDataset *>( poNonPamParentDS );
    if( poParentDS == nullptr ) {
        // Should never happen.
        CPLAssert(false);
        return;
    }

    poParentDS->PamInitialize();
    if( poParentDS->psPam == nullptr )
        return;

    // Often (always?) initializing our parent will have initialized us.
    if( psPam != nullptr )
        return;

    psPam = static_cast<GDALRasterBandPamInfo *>(
        VSI_CALLOC_VERBOSE(sizeof(GDALRasterBandPamInfo), 1) );
    if( psPam == nullptr )
        return;

    psPam->dfScale = 1.0;
    psPam->poParentDS = poParentDS;
    psPam->dfNoDataValue = -1e10;
    psPam->poDefaultRAT = nullptr;
}
コード例 #3
0
ファイル: aaigriddataset.cpp プロジェクト: hdfeos/gdal
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;
}
コード例 #4
0
ファイル: rcreatecopy.cpp プロジェクト: Mavrx-inc/gdal
GDALDataset *
RCreateCopy( const char * pszFilename,
             GDALDataset *poSrcDS,
             CPL_UNUSED int bStrict,
             char ** papszOptions,
             GDALProgressFunc pfnProgress,
             void * pProgressData )
{
    const int nBands = poSrcDS->GetRasterCount();
    const int nXSize = poSrcDS->GetRasterXSize();
    const int nYSize = poSrcDS->GetRasterYSize();
    const bool bASCII = CPLFetchBool(papszOptions, "ASCII", false);
    const bool bCompressed = CPLFetchBool(papszOptions, "COMPRESS", !bASCII);

    // Some some rudimentary checks.

    // Setup the filename to actually use.  We prefix with
    // /vsigzip/ if we want compressed output.
    const CPLString osAdjustedFilename =
        std::string(bCompressed ? "/vsigzip/" : "") + pszFilename;

    // Create the file.
    VSILFILE *fp = VSIFOpenL(osAdjustedFilename, "wb");
    if( fp == NULL )
    {
        CPLError(CE_Failure, CPLE_OpenFailed,
                 "Unable to create file %s.",
                 pszFilename);
        return NULL;
    }

    // Write header with version, etc.
    if( bASCII )
    {
        const char *pszHeader = "RDA2\nA\n";
        VSIFWriteL(pszHeader, 1, strlen(pszHeader), fp);
    }
    else
    {
        const char *pszHeader = "RDX2\nX\n";
        VSIFWriteL(pszHeader, 1, strlen(pszHeader), fp);
    }

    RWriteInteger(fp, bASCII, 2);
    RWriteInteger(fp, bASCII, 133377);
    RWriteInteger(fp, bASCII, 131840);

    // Establish the primary pairlist with one component object.
    RWriteInteger(fp, bASCII, 1026);
    RWriteInteger(fp, bASCII, 1);

    // Write the object name.  Eventually we should derive this
    // from the filename, possible with override by a creation option.
    RWriteString(fp, bASCII, "gg");

    // For now we write the raster as a numeric array with attributes (526).
    RWriteInteger(fp, bASCII, 526);
    RWriteInteger(fp, bASCII, nXSize * nYSize * nBands);

    // Write the raster data.
    CPLErr eErr = CE_None;

    double *padfScanline =
        static_cast<double *>(CPLMalloc(nXSize * sizeof(double)));

    for( int iBand = 0; iBand < nBands; iBand++ )
    {
        GDALRasterBand *poBand = poSrcDS->GetRasterBand(iBand + 1);

        for( int iLine = 0; iLine < nYSize && eErr == CE_None; iLine++ )
        {
            eErr = poBand->RasterIO(GF_Read, 0, iLine, nXSize, 1,
                                    padfScanline, nXSize, 1, GDT_Float64,
                                    sizeof(double), 0, NULL);

            if( bASCII )
            {
                for( int iValue = 0; iValue < nXSize; iValue++ )
                {
                    char szValue[128] = { '\0' };
                    CPLsnprintf(szValue, sizeof(szValue), "%.16g\n",
                                padfScanline[iValue]);
                    VSIFWriteL(szValue, 1, strlen(szValue), fp);
                }
            }
            else
            {
                for( int iValue = 0; iValue < nXSize; iValue++ )
                    CPL_MSBPTR64(padfScanline + iValue);

                VSIFWriteL(padfScanline, 8, nXSize, fp);
            }

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

    CPLFree(padfScanline);

    // Write out the dims attribute.
    RWriteInteger(fp, bASCII, 1026);
    RWriteInteger(fp, bASCII, 1);

    RWriteString(fp, bASCII, "dim");

    RWriteInteger(fp, bASCII, 13);
    RWriteInteger(fp, bASCII, 3);
    RWriteInteger(fp, bASCII, nXSize);
    RWriteInteger(fp, bASCII, nYSize);
    RWriteInteger(fp, bASCII, nBands);

    RWriteInteger(fp, bASCII, 254);

    // Terminate overall pairlist.
    RWriteInteger(fp, bASCII, 254);

    // Cleanup.
    VSIFCloseL(fp);

    if( eErr != CE_None )
        return NULL;

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

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

    return poDS;
}
コード例 #5
0
ファイル: dteddataset.cpp プロジェクト: drownedout/datamap
static GDALDataset *
DTEDCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
                int bStrict, char ** papszOptions, 
                GDALProgressFunc pfnProgress, void * pProgressData )

{
    (void) pProgressData;
    (void) pfnProgress;
    (void) papszOptions;
    (void) bStrict;


/* -------------------------------------------------------------------- */
/*      Some some rudimentary checks                                    */
/* -------------------------------------------------------------------- */
    int nBands = poSrcDS->GetRasterCount();
    if (nBands == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "DTED driver does not support source dataset with zero band.\n");
        return NULL;
    }
    
    if (nBands != 1)
    {
        CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, 
                  "DTED driver only uses the first band of the dataset.\n");
        if (bStrict)
            return NULL;
    }

    if( pfnProgress && !pfnProgress( 0.0, NULL, pProgressData ) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Work out the level.                                             */
/* -------------------------------------------------------------------- */
    int nLevel;

    if( poSrcDS->GetRasterYSize() == 121 )
        nLevel = 0;
    else if( poSrcDS->GetRasterYSize() == 1201 )
        nLevel = 1;
    else if( poSrcDS->GetRasterYSize() == 3601 )
        nLevel = 2;
    else
    {
        CPLError( CE_Warning, CPLE_AppDefined, 
               "The source does not appear to be a properly formatted cell." );
        nLevel = 1;
    }

/* -------------------------------------------------------------------- */
/*      Checks the input SRS                                            */
/* -------------------------------------------------------------------- */
    OGRSpatialReference ogrsr_input;
    OGRSpatialReference ogrsr_wgs84;
    char* c = (char*)poSrcDS->GetProjectionRef();
    ogrsr_input.importFromWkt(&c);
    ogrsr_wgs84.SetWellKnownGeogCS( "WGS84" );
    if ( ogrsr_input.IsSameGeogCS(&ogrsr_wgs84) == FALSE)
    {
        CPLError( CE_Warning, CPLE_AppDefined, 
                  "The source projection coordinate system is %s. Only WGS 84 is supported.\n"
                  "The DTED driver will generate a file as if the source was WGS 84 projection coordinate system.",
                  poSrcDS->GetProjectionRef() );
    }

/* -------------------------------------------------------------------- */
/*      Work out the LL origin.                                         */
/* -------------------------------------------------------------------- */
    int  nLLOriginLat, nLLOriginLong;
    double adfGeoTransform[6];

    poSrcDS->GetGeoTransform( adfGeoTransform );

    nLLOriginLat = (int) 
        floor(adfGeoTransform[3] 
              + poSrcDS->GetRasterYSize() * adfGeoTransform[5] + 0.5);
    
    nLLOriginLong = (int) floor(adfGeoTransform[0] + 0.5);

    if (fabs(nLLOriginLat - (adfGeoTransform[3] 
              + (poSrcDS->GetRasterYSize() - 0.5) * adfGeoTransform[5])) > 1e-10 ||
        fabs(nLLOriginLong - (adfGeoTransform[0] + 0.5 * adfGeoTransform[1])) > 1e-10)
    {
        CPLError( CE_Warning, CPLE_AppDefined, 
               "The corner coordinates of the source are not properly "
               "aligned on plain latitude/longitude boundaries.");
    }

/* -------------------------------------------------------------------- */
/*     Check horizontal source size.                                    */
/* -------------------------------------------------------------------- */
    int expectedXSize;
    if( ABS(nLLOriginLat) >= 80 )
        expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 6 + 1;
    else if( ABS(nLLOriginLat) >= 75 )
        expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 4 + 1;
    else if( ABS(nLLOriginLat) >= 70 )
        expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 3 + 1;
    else if( ABS(nLLOriginLat) >= 50 )
        expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 2 + 1;
    else
        expectedXSize = poSrcDS->GetRasterYSize();

    if (poSrcDS->GetRasterXSize() != expectedXSize)
    {
        CPLError( CE_Warning, CPLE_AppDefined, 
               "The horizontal source size is not conformant with the one "
               "expected by DTED Level %d at this latitude (%d pixels found instead of %d).", nLevel,
                poSrcDS->GetRasterXSize(), expectedXSize);
    }

/* -------------------------------------------------------------------- */
/*      Create the output dted file.                                    */
/* -------------------------------------------------------------------- */
    const char *pszError;

    pszError = DTEDCreate( pszFilename, nLevel, nLLOriginLat, nLLOriginLong );

    if( pszError != NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "%s", pszError );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Open the DTED file so we can output the data to it.             */
/* -------------------------------------------------------------------- */
    DTEDInfo *psDTED;

    psDTED = DTEDOpen( pszFilename, "rb+", FALSE );
    if( psDTED == NULL )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Read all the data in a single buffer.                           */
/* -------------------------------------------------------------------- */
    GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 );
    GInt16      *panData;

    panData = (GInt16 *) 
        VSIMalloc(sizeof(GInt16) * psDTED->nXSize * psDTED->nYSize);
    if (panData == NULL)
    {
        CPLError( CE_Failure, CPLE_OutOfMemory, "Out of memory");
        DTEDClose(psDTED);
        return NULL;
    }

    for( int iY = 0; iY < psDTED->nYSize; iY++ )
    {
        poSrcBand->RasterIO( GF_Read, 0, iY, psDTED->nXSize, 1, 
                            (void *) (panData + iY * psDTED->nXSize), psDTED->nXSize, 1, 
                            GDT_Int16, 0, 0, NULL );

        if( pfnProgress && !pfnProgress(0.5 * (iY+1) / (double) psDTED->nYSize, NULL, pProgressData ) )
        {
            CPLError( CE_Failure, CPLE_UserInterrupt, 
                        "User terminated CreateCopy()" );
            DTEDClose( psDTED );
            CPLFree( panData );
            return NULL;
        }
    }

    int bSrcBandHasNoData;
    double srcBandNoData = poSrcBand->GetNoDataValue(&bSrcBandHasNoData);

/* -------------------------------------------------------------------- */
/*      Write all the profiles.                                         */
/* -------------------------------------------------------------------- */
    GInt16      anProfData[3601];
    int         dfNodataCount=0;
    GByte       iPartialCell;

    for( int iProfile = 0; iProfile < psDTED->nXSize; iProfile++ )
    {
        for( int iY = 0; iY < psDTED->nYSize; iY++ )
        {
            anProfData[iY] = panData[iProfile + iY * psDTED->nXSize];
            if ( bSrcBandHasNoData && anProfData[iY] == srcBandNoData)
            {
                anProfData[iY] = DTED_NODATA_VALUE;
                dfNodataCount++;
            }
            else if ( anProfData[iY] == DTED_NODATA_VALUE )
                dfNodataCount++;
        }
        DTEDWriteProfile( psDTED, iProfile, anProfData );

        if( pfnProgress
            && !pfnProgress( 0.5 + 0.5 * (iProfile+1) / (double) psDTED->nXSize,
                             NULL, pProgressData ) )
        {
            CPLError( CE_Failure, CPLE_UserInterrupt, 
                      "User terminated CreateCopy()" );
            DTEDClose( psDTED );
            CPLFree( panData );
            return NULL;
        }
    }
    CPLFree( panData );

/* -------------------------------------------------------------------- */
/* Partial cell indicator: 0 for complete coverage; 1-99 for incomplete */
/* -------------------------------------------------------------------- */
    char szPartialCell[3];

    if ( dfNodataCount == 0 )
        iPartialCell = 0;
    else
    {
      iPartialCell = (GByte)int(floor(100.0 - 
           (dfNodataCount*100.0/(psDTED->nXSize * psDTED->nYSize))));
        if (iPartialCell < 1)
           iPartialCell=1;
    }
    sprintf(szPartialCell,"%02d",iPartialCell);
    DTEDSetMetadata(psDTED, DTEDMD_PARTIALCELL_DSI, szPartialCell); 

/* -------------------------------------------------------------------- */
/*      Try to copy any matching available metadata.                    */
/* -------------------------------------------------------------------- */
    if( poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_UHL" ) != NULL )
        DTEDSetMetadata( psDTED, DTEDMD_VERTACCURACY_UHL, 
                     poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_UHL" ) );

    if( poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_ACC" ) != NULL )
        DTEDSetMetadata( psDTED, DTEDMD_VERTACCURACY_ACC, 
                    poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_ACC" ) );

    if( poSrcDS->GetMetadataItem( "DTED_SecurityCode_UHL" ) != NULL )
        DTEDSetMetadata( psDTED, DTEDMD_SECURITYCODE_UHL, 
                    poSrcDS->GetMetadataItem( "DTED_SecurityCode_UHL" ) );

    if( poSrcDS->GetMetadataItem( "DTED_SecurityCode_DSI" ) != NULL )
        DTEDSetMetadata( psDTED, DTEDMD_SECURITYCODE_DSI, 
                    poSrcDS->GetMetadataItem( "DTED_SecurityCode_DSI" ) );

    if( poSrcDS->GetMetadataItem( "DTED_UniqueRef_UHL" ) != NULL )
        DTEDSetMetadata( psDTED, DTEDMD_UNIQUEREF_UHL, 
                         poSrcDS->GetMetadataItem( "DTED_UniqueRef_UHL" ) );

    if( poSrcDS->GetMetadataItem( "DTED_UniqueRef_DSI" ) != NULL )
        DTEDSetMetadata( psDTED, DTEDMD_UNIQUEREF_DSI, 
                         poSrcDS->GetMetadataItem( "DTED_UniqueRef_DSI" ) );

    if( poSrcDS->GetMetadataItem( "DTED_DataEdition" ) != NULL )
        DTEDSetMetadata( psDTED, DTEDMD_DATA_EDITION, 
                         poSrcDS->GetMetadataItem( "DTED_DataEdition" ) );

    if( poSrcDS->GetMetadataItem( "DTED_MatchMergeVersion" ) != NULL )
        DTEDSetMetadata( psDTED, DTEDMD_MATCHMERGE_VERSION, 
                     poSrcDS->GetMetadataItem( "DTED_MatchMergeVersion" ) );

    if( poSrcDS->GetMetadataItem( "DTED_MaintenanceDate" ) != NULL )
        DTEDSetMetadata( psDTED, DTEDMD_MAINT_DATE, 
                         poSrcDS->GetMetadataItem( "DTED_MaintenanceDate" ) );

    if( poSrcDS->GetMetadataItem( "DTED_MatchMergeDate" ) != NULL )
        DTEDSetMetadata( psDTED, DTEDMD_MATCHMERGE_DATE, 
                         poSrcDS->GetMetadataItem( "DTED_MatchMergeDate" ) );

    if( poSrcDS->GetMetadataItem( "DTED_MaintenanceDescription" ) != NULL )
        DTEDSetMetadata( psDTED, DTEDMD_MAINT_DESCRIPTION, 
                 poSrcDS->GetMetadataItem( "DTED_MaintenanceDescription" ) );

    if( poSrcDS->GetMetadataItem( "DTED_Producer" ) != NULL )
        DTEDSetMetadata( psDTED, DTEDMD_PRODUCER, 
                         poSrcDS->GetMetadataItem( "DTED_Producer" ) );

    if( poSrcDS->GetMetadataItem( "DTED_VerticalDatum" ) != NULL )
        DTEDSetMetadata( psDTED, DTEDMD_VERTDATUM, 
                         poSrcDS->GetMetadataItem( "DTED_VerticalDatum" ) );

    if( poSrcDS->GetMetadataItem( "DTED_HorizontalDatum" ) != NULL )
        DTEDSetMetadata( psDTED, DTEDMD_HORIZDATUM, 
                         poSrcDS->GetMetadataItem( "DTED_HorizontalDatum" ) );

    if( poSrcDS->GetMetadataItem( "DTED_DigitizingSystem" ) != NULL )
        DTEDSetMetadata( psDTED, DTEDMD_DIGITIZING_SYS, 
                         poSrcDS->GetMetadataItem( "DTED_DigitizingSystem" ) );

    if( poSrcDS->GetMetadataItem( "DTED_CompilationDate" ) != NULL )
        DTEDSetMetadata( psDTED, DTEDMD_COMPILATION_DATE, 
                         poSrcDS->GetMetadataItem( "DTED_CompilationDate" ) );

    if( poSrcDS->GetMetadataItem( "DTED_HorizontalAccuracy" ) != NULL )
        DTEDSetMetadata( psDTED, DTEDMD_HORIZACCURACY, 
                     poSrcDS->GetMetadataItem( "DTED_HorizontalAccuracy" ) );

    if( poSrcDS->GetMetadataItem( "DTED_RelHorizontalAccuracy" ) != NULL )
        DTEDSetMetadata( psDTED, DTEDMD_REL_HORIZACCURACY, 
                   poSrcDS->GetMetadataItem( "DTED_RelHorizontalAccuracy" ) );

    if( poSrcDS->GetMetadataItem( "DTED_RelVerticalAccuracy" ) != NULL )
        DTEDSetMetadata( psDTED, DTEDMD_REL_VERTACCURACY, 
                     poSrcDS->GetMetadataItem( "DTED_RelVerticalAccuracy" ) );

/* -------------------------------------------------------------------- */
/*      Try to open the resulting DTED file.                            */
/* -------------------------------------------------------------------- */
    DTEDClose( psDTED );

/* -------------------------------------------------------------------- */
/*      Reopen and copy missing information into a PAM file.            */
/* -------------------------------------------------------------------- */
    GDALPamDataset *poDS = (GDALPamDataset *) 
        GDALOpen( pszFilename, GA_ReadOnly );

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

    return poDS;
}
コード例 #6
0
ファイル: gmtdataset.cpp プロジェクト: AbdelghaniDr/mirror
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;
}
コード例 #7
0
ファイル: gs7bgdataset.cpp プロジェクト: bbradbury/lib_gdal
GDALDataset *GS7BGDataset::CreateCopy( const char *pszFilename,
                                       GDALDataset *poSrcDS,
                                       int bStrict,
                                       CPL_UNUSED char **papszOptions,
                                       GDALProgressFunc pfnProgress,
                                       void *pProgressData )
{
    if( pfnProgress == NULL )
        pfnProgress = GDALDummyProgress;

    int nBands = poSrcDS->GetRasterCount();
    if (nBands == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "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, "
                "format only supports one raster band.\n" );
            return NULL;
        }
        else
            CPLError( CE_Warning, CPLE_NotSupported,
                "Format only supports one "
                "raster band, first band will be copied.\n" );
    }

    GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 );

    if( !pfnProgress( 0.0, NULL, pProgressData ) )
    {
        CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated\n" );
        return NULL;
    }

    VSILFILE    *fp = VSIFOpenL( pszFilename, "w+b" );

    if( fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Attempt to create file '%s' failed.\n",
                  pszFilename );
        return NULL;
    }

    GInt32  nXSize = poSrcBand->GetXSize();
    GInt32  nYSize = poSrcBand->GetYSize();
    double  adfGeoTransform[6];

    poSrcDS->GetGeoTransform( adfGeoTransform );

    double dfMinX = adfGeoTransform[0] + adfGeoTransform[1] / 2;
    double dfMaxX = adfGeoTransform[1] * (nXSize - 0.5) + adfGeoTransform[0];
    double dfMinY = adfGeoTransform[5] * (nYSize - 0.5) + adfGeoTransform[3];
    double dfMaxY = adfGeoTransform[3] + adfGeoTransform[5] / 2;
    CPLErr eErr = WriteHeader( fp, nXSize, nYSize,
                   dfMinX, dfMaxX, dfMinY, dfMaxY, 0.0, 0.0 );

    if( eErr != CE_None )
    {
        VSIFCloseL( fp );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Copy band data.                                                 */
/* -------------------------------------------------------------------- */
    double *pfData = (double *)VSI_MALLOC2_VERBOSE( nXSize, sizeof( double ) );
    if( pfData == NULL )
    {
        VSIFCloseL( fp );
        return NULL;
    }

    int     bSrcHasNDValue;
    double   dfSrcNoDataValue = poSrcBand->GetNoDataValue( &bSrcHasNDValue );
    double  dfMinZ = DBL_MAX;
    double  dfMaxZ = -DBL_MAX;
    for( GInt32 iRow = nYSize - 1; iRow >= 0; iRow-- )
    {
        eErr = poSrcBand->RasterIO( GF_Read, 0, iRow,
                    nXSize, 1, pfData,
                    nXSize, 1, GDT_Float64, 0, 0, NULL );

        if( eErr != CE_None )
        {
            VSIFCloseL( fp );
            VSIFree( pfData );
            return NULL;
        }

        for( int iCol=0; iCol<nXSize; iCol++ )
        {
            if( bSrcHasNDValue && pfData[iCol] == dfSrcNoDataValue )
            {
                pfData[iCol] = dfDefaultNoDataValue;
            }
            else
            {
                if( pfData[iCol] > dfMaxZ )
                    dfMaxZ = pfData[iCol];

                if( pfData[iCol] < dfMinZ )
                    dfMinZ = pfData[iCol];
            }

            CPL_LSBPTR64( pfData+iCol );
        }

        if( VSIFWriteL( (void *)pfData, sizeof( double ), nXSize,
                fp ) != static_cast<unsigned>(nXSize) )
        {
            VSIFCloseL( fp );
            VSIFree( pfData );
            CPLError( CE_Failure, CPLE_FileIO,
                "Unable to write grid row. Disk full?\n" );
            return NULL;
        }

        if( !pfnProgress( static_cast<double>(nYSize - iRow)/nYSize,
                NULL, pProgressData ) )
        {
            VSIFCloseL( fp );
            VSIFree( pfData );
            CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
            return NULL;
        }
    }

    VSIFree( pfData );

    /* write out the min and max values */
    eErr = WriteHeader( fp, nXSize, nYSize,
            dfMinX, dfMaxX, dfMinY, dfMaxY, dfMinZ, dfMaxZ );

    if( eErr != CE_None )
    {
        VSIFCloseL( fp );
        return NULL;
    }

    VSIFCloseL( fp );

    GDALPamDataset *poDS = (GDALPamDataset *)GDALOpen( pszFilename,
                                                GA_Update );
    if (poDS)
    {
        poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT );
    }

    return poDS;
}
コード例 #8
0
GDALDataset *
GIFDataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
               int bStrict, char ** papszOptions, 
               GDALProgressFunc pfnProgress, void * pProgressData )

{
    int  nBands = poSrcDS->GetRasterCount();
    int  nXSize = poSrcDS->GetRasterXSize();
    int  nYSize = poSrcDS->GetRasterYSize();
    int	 bInterlace = FALSE;

/* -------------------------------------------------------------------- */
/*      Check for interlaced option.                                    */
/* -------------------------------------------------------------------- */
    bInterlace = CSLFetchBoolean(papszOptions, "INTERLACING", FALSE);

/* -------------------------------------------------------------------- */
/*      Some some rudimentary checks                                    */
/* -------------------------------------------------------------------- */
    if( nBands != 1 )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "GIF driver only supports one band images.\n" );

        return NULL;
    }

    if (nXSize > 65535 || nYSize > 65535)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "GIF driver only supports datasets up to 65535x65535 size.\n" );

        return NULL;
    }

    if( poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Byte 
        && bStrict )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "GIF driver doesn't support data type %s. "
                  "Only eight bit bands supported.\n", 
                  GDALGetDataTypeName( 
                      poSrcDS->GetRasterBand(1)->GetRasterDataType()) );

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Open the output file.                                           */
/* -------------------------------------------------------------------- */
    GifFileType *hGifFile;
    VSILFILE *fp;

    fp = VSIFOpenL( pszFilename, "wb" );
    if( fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "Failed to create %s:\n%s", 
                  pszFilename, VSIStrerror( errno ) );
        return NULL;
    }

#if defined(GIFLIB_MAJOR) && GIFLIB_MAJOR >= 5
    int nError;
    hGifFile = EGifOpen( fp, VSIGIFWriteFunc, &nError );
#else
    hGifFile = EGifOpen( fp, VSIGIFWriteFunc );
#endif
    if( hGifFile == NULL )
    {
        VSIFCloseL( fp );
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "EGifOpenFilename(%s) failed.  Does file already exist?",
                  pszFilename );

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Prepare colortable.                                             */
/* -------------------------------------------------------------------- */
    GDALRasterBand	*poBand = poSrcDS->GetRasterBand(1);
    ColorMapObject	*psGifCT;
    int			iColor;

    if( poBand->GetColorTable() == NULL )
    {
        psGifCT = GifMakeMapObject( 256, NULL );
        for( iColor = 0; iColor < 256; iColor++ )
        {
            psGifCT->Colors[iColor].Red = (GifByteType) iColor;
            psGifCT->Colors[iColor].Green = (GifByteType) iColor;
            psGifCT->Colors[iColor].Blue = (GifByteType) iColor;
        }
    }
    else
    {
        GDALColorTable	*poCT = poBand->GetColorTable();
        int nFullCount = 1;

        while( nFullCount < poCT->GetColorEntryCount() )
            nFullCount = nFullCount * 2;

        psGifCT = GifMakeMapObject( nFullCount, NULL );
        for( iColor = 0; iColor < poCT->GetColorEntryCount(); iColor++ )
        {
            GDALColorEntry	sEntry;

            poCT->GetColorEntryAsRGB( iColor, &sEntry );
            psGifCT->Colors[iColor].Red = (GifByteType) sEntry.c1;
            psGifCT->Colors[iColor].Green = (GifByteType) sEntry.c2;
            psGifCT->Colors[iColor].Blue = (GifByteType) sEntry.c3;
        }
        for( ; iColor < nFullCount; iColor++ )
        {
            psGifCT->Colors[iColor].Red = 0;
            psGifCT->Colors[iColor].Green = 0;
            psGifCT->Colors[iColor].Blue = 0;
        }
    }

/* -------------------------------------------------------------------- */
/*      Setup parameters.                                               */
/* -------------------------------------------------------------------- */
    if (EGifPutScreenDesc(hGifFile, nXSize, nYSize, 
                          psGifCT->ColorCount, 255, psGifCT) == GIF_ERROR)
    {
        GifFreeMapObject(psGifCT);
        GDALPrintGifError(hGifFile, "Error writing gif file.");
        GIFAbstractDataset::myEGifCloseFile(hGifFile);
        VSIFCloseL( fp );
        return NULL;
    }
    
    GifFreeMapObject(psGifCT);
    psGifCT = NULL;

    /* Support for transparency */
    int bNoDataValue;
    double noDataValue = poBand->GetNoDataValue(&bNoDataValue);
    if (bNoDataValue && noDataValue >= 0 && noDataValue <= 255)
    {
        unsigned char extensionData[4];
        extensionData[0] = 1; /*  Transparent Color Flag */
        extensionData[1] = 0;
        extensionData[2] = 0;
        extensionData[3] = (unsigned char)noDataValue;
        EGifPutExtension(hGifFile, 0xf9, 4, extensionData);
    }

    if (EGifPutImageDesc(hGifFile, 0, 0, nXSize, nYSize, bInterlace, NULL) == GIF_ERROR )
    {
        GDALPrintGifError(hGifFile, "Error writing gif file.");
        GIFAbstractDataset::myEGifCloseFile(hGifFile);
        VSIFCloseL( fp );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Loop over image, copying image data.                            */
/* -------------------------------------------------------------------- */
    CPLErr      eErr;
    GDALPamDataset *poDS;
    GByte      *pabyScanline;

    pabyScanline = (GByte *) CPLMalloc( nXSize );

    if( !pfnProgress( 0.0, NULL, pProgressData ) )
        eErr = CE_Failure;

    if( !bInterlace )
    {
        for( int iLine = 0; iLine < nYSize; iLine++ )
        {
            eErr = poBand->RasterIO( GF_Read, 0, iLine, nXSize, 1, 
                                     pabyScanline, nXSize, 1, GDT_Byte,
                                     nBands, nBands * nXSize );

            if( eErr != CE_None || EGifPutLine( hGifFile, pabyScanline, nXSize ) == GIF_ERROR )
            {
                CPLError( CE_Failure, CPLE_AppDefined, 
                          "Error writing gif file." );
                goto error;
            }

            if( !pfnProgress( (iLine + 1) * 1.0 / nYSize, NULL, pProgressData ) )
            {
                goto error;
            }

        }
    }
    else
    {
        int 	i, j;
        int nLinesRead = 0;
        int nLinesToRead = 0;
        for ( i = 0; i < 4; i++)
        {
            for (j = InterlacedOffset[i]; j < nYSize; j += InterlacedJumps[i]) 
            {
                nLinesToRead ++;
            }
        }

        /* Need to perform 4 passes on the images: */
        for ( i = 0; i < 4; i++)
        {
            for (j = InterlacedOffset[i]; j < nYSize; j += InterlacedJumps[i]) 
            {
                eErr= poBand->RasterIO( GF_Read, 0, j, nXSize, 1, 
                                        pabyScanline, nXSize, 1, GDT_Byte,
                                        1, nXSize );

                if (eErr != CE_None || EGifPutLine(hGifFile, pabyScanline, nXSize) == GIF_ERROR)
                {
                    CPLError( CE_Failure, CPLE_AppDefined, 
                            "Error writing gif file." );
                    goto error;
                }

                nLinesRead ++;
                if( !pfnProgress( nLinesRead * 1.0 / nYSize, NULL, pProgressData ) )
                {
                    goto error;
                }
            }
        }
    }

    CPLFree( pabyScanline );
    pabyScanline = NULL;

/* -------------------------------------------------------------------- */
/*      cleanup                                                         */
/* -------------------------------------------------------------------- */
    if (GIFAbstractDataset::myEGifCloseFile(hGifFile) == GIF_ERROR)
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "EGifCloseFile() failed.\n" );
        hGifFile = NULL;
        goto error;
    }
    hGifFile = NULL;

    VSIFCloseL( fp );
    fp = NULL;

/* -------------------------------------------------------------------- */
/*      Do we need a world file?                                          */
/* -------------------------------------------------------------------- */
    if( CSLFetchBoolean( papszOptions, "WORLDFILE", FALSE ) )
    {
    	double      adfGeoTransform[6];
	
	if( poSrcDS->GetGeoTransform( adfGeoTransform ) == CE_None )
            GDALWriteWorldFile( pszFilename, "wld", adfGeoTransform );
    }

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

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

        GIFDataset* poGIF_DS = new GIFDataset();
        poGIF_DS->nRasterXSize = nXSize;
        poGIF_DS->nRasterYSize = nYSize;
        for(int i=0;i<nBands;i++)
            poGIF_DS->SetBand( i+1, new GIFRasterBand( poGIF_DS, i+1, NULL, 0 ) );
        return poGIF_DS;
    }

error:
    if (hGifFile)
        GIFAbstractDataset::myEGifCloseFile(hGifFile);
    if (fp)
        VSIFCloseL( fp );
    if (pabyScanline)
        CPLFree( pabyScanline );
    return NULL;
}
コード例 #9
0
ファイル: srtmhgtdataset.cpp プロジェクト: hdfeos/gdal
GDALDataset * SRTMHGTDataset::CreateCopy( const char * pszFilename,
                                          GDALDataset *poSrcDS,
                                          int bStrict,
                                          char ** /* papszOptions*/,
                                          GDALProgressFunc pfnProgress,
                                          void * pProgressData )
{
/* -------------------------------------------------------------------- */
/*      Some some rudimentary checks                                    */
/* -------------------------------------------------------------------- */
    const int nBands = poSrcDS->GetRasterCount();
    if (nBands == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "SRTMHGT driver does not support source dataset with zero band.\n");
        return nullptr;
    }
    else if (nBands != 1)
    {
        CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported,
                  "SRTMHGT driver only uses the first band of the dataset.\n");
        if (bStrict)
            return nullptr;
    }

/* -------------------------------------------------------------------- */
/*      Checks the input SRS                                            */
/* -------------------------------------------------------------------- */
    OGRSpatialReference ogrsr_input;
    ogrsr_input.importFromWkt(poSrcDS->GetProjectionRef());

    OGRSpatialReference ogrsr_wgs84;
    ogrsr_wgs84.SetWellKnownGeogCS( "WGS84" );

    if ( ogrsr_input.IsSameGeogCS(&ogrsr_wgs84) == FALSE)
    {
        CPLError( CE_Warning, CPLE_AppDefined,
                  "The source projection coordinate system is %s. Only WGS 84 "
                  "is supported.\nThe SRTMHGT driver will generate a file as "
                  "if the source was WGS 84 projection coordinate system.",
                  poSrcDS->GetProjectionRef() );
    }

/* -------------------------------------------------------------------- */
/*      Work out the LL origin.                                         */
/* -------------------------------------------------------------------- */
    double adfGeoTransform[6];
    if (poSrcDS->GetGeoTransform( adfGeoTransform ) != CE_None)
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Source image must have a geo transform matrix.");
        return nullptr;
    }

    const int nLLOriginLat = static_cast<int>(
        std::floor(adfGeoTransform[3]
              + poSrcDS->GetRasterYSize() * adfGeoTransform[5] + 0.5) );

    int nLLOriginLong = static_cast<int>(
        std::floor(adfGeoTransform[0] + 0.5) );

    if (std::abs(nLLOriginLat - (
            adfGeoTransform[3] + (poSrcDS->GetRasterYSize() - 0.5 )
            * adfGeoTransform[5] ) ) > 1e-10 ||
        std::abs(nLLOriginLong - (
            adfGeoTransform[0] + 0.5 * adfGeoTransform[1])) > 1e-10 )
    {
        CPLError( CE_Warning, CPLE_AppDefined,
               "The corner coordinates of the source are not properly "
               "aligned on plain latitude/longitude boundaries.");
    }

/* -------------------------------------------------------------------- */
/*      Check image dimensions.                                         */
/* -------------------------------------------------------------------- */
    const int nXSize = poSrcDS->GetRasterXSize();
    const int nYSize = poSrcDS->GetRasterYSize();

    if (!((nXSize == 1201 && nYSize == 1201) ||
          (nXSize == 3601 && nYSize == 3601) ||
          (nXSize == 1801 && nYSize == 3601)))
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Image dimensions should be 1201x1201, 3601x3601 or 1801x3601.");
        return nullptr;
    }

/* -------------------------------------------------------------------- */
/*      Check filename.                                                 */
/* -------------------------------------------------------------------- */
    char expectedFileName[12];

    CPLsnprintf(expectedFileName, sizeof(expectedFileName), "%c%02d%c%03d.HGT",
             (nLLOriginLat >= 0) ? 'N' : 'S',
             (nLLOriginLat >= 0) ? nLLOriginLat : -nLLOriginLat,
             (nLLOriginLong >= 0) ? 'E' : 'W',
             (nLLOriginLong >= 0) ? nLLOriginLong : -nLLOriginLong);

    if (!EQUAL(expectedFileName, CPLGetFilename(pszFilename)))
    {
        CPLError( CE_Warning, CPLE_AppDefined,
                  "Expected output filename is %s.", expectedFileName);
    }

/* -------------------------------------------------------------------- */
/*      Write output file.                                              */
/* -------------------------------------------------------------------- */
    VSILFILE* fp = VSIFOpenL(pszFilename, "wb");
    if (fp == nullptr)
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Cannot create file %s", pszFilename );
        return nullptr;
    }

    GInt16* panData
        = reinterpret_cast<GInt16 *>( CPLMalloc(sizeof(GInt16) * nXSize) );
    GDALRasterBand* poSrcBand = poSrcDS->GetRasterBand(1);

    int bSrcBandHasNoData;
    double srcBandNoData = poSrcBand->GetNoDataValue(&bSrcBandHasNoData);

    for( int iY = 0; iY < nYSize; iY++ )
    {
        if( poSrcBand->RasterIO( GF_Read, 0, iY, nXSize, 1,
                                 reinterpret_cast<void *>( panData ), nXSize, 1,
                                 GDT_Int16, 0, 0, nullptr ) != CE_None )
        {
            VSIFCloseL(fp);
            CPLFree( panData );
            return nullptr;
        }

        /* Translate nodata values */
        if (bSrcBandHasNoData && srcBandNoData != SRTMHG_NODATA_VALUE)
        {
            for( int iX = 0; iX < nXSize; iX++ )
            {
                if (panData[iX] == srcBandNoData)
                    panData[iX] = SRTMHG_NODATA_VALUE;
            }
        }

#ifdef CPL_LSB
        GDALSwapWords(panData, 2, nXSize, 2);
#endif

        if( VSIFWriteL( panData,sizeof(GInt16) * nXSize,1,fp ) != 1)
        {
            CPLError( CE_Failure, CPLE_FileIO,
                      "Failed to write line %d in SRTMHGT dataset.\n",
                      iY );
            VSIFCloseL(fp);
            CPLFree( panData );
            return nullptr;
        }

        if( pfnProgress && !pfnProgress( (iY+1) / static_cast<double>( nYSize ),
                                         nullptr, pProgressData ) )
        {
            CPLError( CE_Failure, CPLE_UserInterrupt,
                        "User terminated CreateCopy()" );
            VSIFCloseL(fp);
            CPLFree( panData );
            return nullptr;
        }
    }

    CPLFree( panData );
    VSIFCloseL(fp);

/* -------------------------------------------------------------------- */
/*      Reopen and copy missing information into a PAM file.            */
/* -------------------------------------------------------------------- */
    GDALPamDataset *poDS = reinterpret_cast<GDALPamDataset *>(
        GDALOpen( pszFilename, GA_ReadOnly ) );

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

    return poDS;
}
コード例 #10
0
static GDALDataset *
XPMCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
               int bStrict, char ** papszOptions, 
               GDALProgressFunc pfnProgress, void * pProgressData )

{
    int  nBands = poSrcDS->GetRasterCount();
    int  nXSize = poSrcDS->GetRasterXSize();
    int  nYSize = poSrcDS->GetRasterYSize();
    GDALColorTable *poCT;

/* -------------------------------------------------------------------- */
/*      Some some rudimentary checks                                    */
/* -------------------------------------------------------------------- */
    if( nBands != 1 )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "XPM driver only supports one band images.\n" );

        return NULL;
    }

    if( poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Byte 
        && bStrict )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "XPM driver doesn't support data type %s. "
                  "Only eight bit bands supported.\n", 
                  GDALGetDataTypeName( 
                      poSrcDS->GetRasterBand(1)->GetRasterDataType()) );

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      If there is no colortable on the source image, create a         */
/*      greyscale one with 64 levels of grey.                           */
/* -------------------------------------------------------------------- */
    GDALRasterBand	*poBand = poSrcDS->GetRasterBand(1);
    int                 i;
    GDALColorTable      oGreyTable;

    poCT = poBand->GetColorTable();
    if( poCT == NULL )
    {
        poCT = &oGreyTable;

        for( i = 0; i < 256; i++ )
        {
            GDALColorEntry sColor;

            sColor.c1 = (short) i;
            sColor.c2 = (short) i;
            sColor.c3 = (short) i;
            sColor.c4 = 255;

            poCT->SetColorEntry( i, &sColor );
        }
    }

/* -------------------------------------------------------------------- */
/*      Build list of active colors, and the mapping from pixels to     */
/*      our active colormap.                                            */
/* -------------------------------------------------------------------- */
    const char *pszColorCodes = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-+=[]|:;,.<>?/";

    int  anPixelMapping[256];
    GDALColorEntry asPixelColor[256];
    int  nActiveColors = MIN(poCT->GetColorEntryCount(),256);

    // Setup initial colortable and pixel value mapping. 
    memset( anPixelMapping+0, 0, sizeof(int) * 256 );
    for( i = 0; i < nActiveColors; i++ )
    {
        poCT->GetColorEntryAsRGB( i, asPixelColor + i );
        anPixelMapping[i] = i;
    }

/* ==================================================================== */
/*      Iterate merging colors until we are under our limit (about 85). */
/* ==================================================================== */
    while( nActiveColors > (int) strlen(pszColorCodes) )
    {
        int nClosestDistance = 768;
        int iClose1 = -1, iClose2 = -1;
        int iColor1, iColor2;

        // Find the closest pair of colors. 
        for( iColor1 = 0; iColor1 < nActiveColors; iColor1++ )
        {
            for( iColor2 = iColor1+1; iColor2 < nActiveColors; iColor2++ )
            {
                int	nDistance;

                if( asPixelColor[iColor1].c4 < 128 
                    && asPixelColor[iColor2].c4 < 128 )
                    nDistance = 0;
                else
                    nDistance = 
                        ABS(asPixelColor[iColor1].c1-asPixelColor[iColor2].c1)
                      + ABS(asPixelColor[iColor1].c2-asPixelColor[iColor2].c2)
                      + ABS(asPixelColor[iColor1].c3-asPixelColor[iColor2].c3);

                if( nDistance < nClosestDistance )
                {
                    nClosestDistance = nDistance;
                    iClose1 = iColor1;
                    iClose2 = iColor2;
                }
            }

            if( nClosestDistance < 8 )
                break;
        }

        // This should never happen!
        if( iClose1 == -1 )
            break;

        // Merge two selected colors - shift icolor2 into icolor1 and
        // move the last active color into icolor2's slot. 
        for( i = 0; i < 256; i++ )
        {
            if( anPixelMapping[i] == iClose2 )
                anPixelMapping[i] = iClose1;
            else if( anPixelMapping[i] == nActiveColors-1 )
                anPixelMapping[i] = iClose2;
        }

        asPixelColor[iClose2] = asPixelColor[nActiveColors-1];
        nActiveColors--;
    }
        
/* ==================================================================== */
/*      Write the output image.                                         */
/* ==================================================================== */
    FILE	*fpPBM;

    fpPBM = VSIFOpen( pszFilename, "wt+" );
    if( fpPBM == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "Unable to create file `%s'.", 
                  pszFilename );

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Write the header lines.                                         */
/* -------------------------------------------------------------------- */
    fprintf( fpPBM, "/* XPM */\n" );
    fprintf( fpPBM, "static char *%s[] = {\n", 
             CPLGetBasename( pszFilename ) );
    fprintf( fpPBM, "/* width height num_colors chars_per_pixel */\n" );
    fprintf( fpPBM, "\"  %3d   %3d     %3d             1\",\n",
             nXSize, nYSize, nActiveColors );
    fprintf( fpPBM, "/* colors */\n" );

/* -------------------------------------------------------------------- */
/*      Write the color table.                                          */
/* -------------------------------------------------------------------- */
    for( i = 0; i < nActiveColors; i++ )
    {
        if( asPixelColor[i].c4 < 128 )
            fprintf( fpPBM, "\"%c c None\",\n", pszColorCodes[i] );
        else
            fprintf( fpPBM, 
                     "\"%c c #%02x%02x%02x\",\n",
                     pszColorCodes[i],
                     asPixelColor[i].c1, 
                     asPixelColor[i].c2, 
                     asPixelColor[i].c3 );
    }

/* -------------------------------------------------------------------- */
/*	Dump image.							*/
/* -------------------------------------------------------------------- */
    int iLine;
    GByte 	*pabyScanline;

    pabyScanline = (GByte *) CPLMalloc( nXSize );
    for( iLine = 0; iLine < nYSize; iLine++ )
    {
        poBand->RasterIO( GF_Read, 0, iLine, nXSize, 1, 
                          (void *) pabyScanline, nXSize, 1, GDT_Byte, 0, 0 );
        
        fputc( '"', fpPBM );
        for( int iPixel = 0; iPixel < nXSize; iPixel++ )
            fputc( pszColorCodes[anPixelMapping[pabyScanline[iPixel]]], 
                   fpPBM);
        fprintf( fpPBM, "\",\n" );
    }
    
    CPLFree( pabyScanline );

/* -------------------------------------------------------------------- */
/*      cleanup                                                         */
/* -------------------------------------------------------------------- */
    fprintf( fpPBM, "};\n" );
    VSIFClose( fpPBM );

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

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

    return poDS;
}
コード例 #11
0
ファイル: fitdataset.cpp プロジェクト: AsgerPetersen/gdal
static GDALDataset *FITCreateCopy(const char * pszFilename,
                                  GDALDataset *poSrcDS,
                                  int bStrict, char ** papszOptions,
                                  GDALProgressFunc pfnProgress,
                                  void * pProgressData )
{
    CPLDebug("FIT", "CreateCopy %s - %i", pszFilename, bStrict);

    int nBands = poSrcDS->GetRasterCount();
    if (nBands == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "FIT driver does not support source dataset with zero band.\n");
        return nullptr;
    }

/* -------------------------------------------------------------------- */
/*      Create the dataset.                                             */
/* -------------------------------------------------------------------- */
    if( !pfnProgress( 0.0, nullptr, pProgressData ) )
    {
        CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
        return nullptr;
    }

    VSILFILE *fpImage = VSIFOpenL( pszFilename, "wb" );
    if( fpImage == nullptr )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "FIT - unable to create file %s.\n",
                  pszFilename );
        return nullptr;
    }

/* -------------------------------------------------------------------- */
/*      Generate header.                                                */
/* -------------------------------------------------------------------- */
    // XXX - should FIT_PAGE_SIZE be based on file page size ??

    const size_t size = std::max(sizeof(FIThead02), FIT_PAGE_SIZE);
    FIThead02 *head = (FIThead02 *) malloc(size);
    FreeGuard<FIThead02> guardHead( head );

    // clean header so padding (past real header) is all zeros
    memset( head, 0, size );

    memcpy((char *) &head->magic, "IT", 2);
    memcpy((char *) &head->version, "02", 2);

    head->xSize = poSrcDS->GetRasterXSize();
    gst_swapb(head->xSize);
    head->ySize = poSrcDS->GetRasterYSize();
    gst_swapb(head->ySize);
    head->zSize = 1;
    gst_swapb(head->zSize);

    head->cSize = nBands;
    gst_swapb(head->cSize);

    GDALRasterBand *firstBand = poSrcDS->GetRasterBand(1);
    if (! firstBand) {
        CPL_IGNORE_RET_VAL(VSIFCloseL(fpImage));
        return nullptr;
    }

    head->dtype = fitGetDataType(firstBand->GetRasterDataType());
    if (! head->dtype) {
        CPL_IGNORE_RET_VAL(VSIFCloseL(fpImage));
        return nullptr;
    }
    gst_swapb(head->dtype);
    head->order = 1; // interleaved - RGBRGB
    gst_swapb(head->order);
    head->space = 1; // upper left
    gst_swapb(head->space);

    // XXX - need to check all bands
    head->cm = fitGetColorModel(firstBand->GetColorInterpretation(), nBands);
    gst_swapb(head->cm);

    int blockX, blockY;
    firstBand->GetBlockSize(&blockX, &blockY);
    blockX = std::min(blockX, poSrcDS->GetRasterXSize());
    blockY = std::min(blockY, poSrcDS->GetRasterYSize());
    int nDTSize = GDALGetDataTypeSizeBytes(firstBand->GetRasterDataType());
    try
    {
        CPL_IGNORE_RET_VAL(
            CPLSM(blockX) * CPLSM(blockY) * CPLSM(nDTSize) * CPLSM(nBands));
        CPLDebug("FIT write", "inherited block size %ix%i", blockX, blockY);
    }
    catch( ... )
    {
        blockX = std::min(256, poSrcDS->GetRasterXSize());
        blockY = std::min(256, poSrcDS->GetRasterYSize());
    }

    if( CSLFetchNameValue(papszOptions,"PAGESIZE") != nullptr )
    {
        const char *str = CSLFetchNameValue(papszOptions,"PAGESIZE");
        int newBlockX, newBlockY;
        sscanf(str, "%i,%i", &newBlockX, &newBlockY);
        if (newBlockX && newBlockY) {
            blockX = newBlockX;
            blockY = newBlockY;
        }
        else {
            CPLError(CE_Failure, CPLE_OpenFailed,
                     "FIT - Unable to parse option PAGESIZE values [%s]", str);
        }
    }

    // XXX - need to do lots of checking of block size
    // * provide ability to override block size with options
    // * handle non-square block size (like scanline)
    //   - probably default from non-tiled image - have default block size
    // * handle block size bigger than image size
    // * undesirable block size (non power of 2, others?)
    // * mismatched block sizes for different bands
    // * image that isn't even pages (i.e. partially empty pages at edge)
    CPLDebug("FIT write", "using block size %ix%i", blockX, blockY);

    head->xPageSize = blockX;
    gst_swapb(head->xPageSize);
    head->yPageSize = blockY;
    gst_swapb(head->yPageSize);
    head->zPageSize = 1;
    gst_swapb(head->zPageSize);
    head->cPageSize = nBands;
    gst_swapb(head->cPageSize);

    // XXX - need to check all bands
    head->minValue = firstBand->GetMinimum();
    gst_swapb(head->minValue);
    // XXX - need to check all bands
    head->maxValue = firstBand->GetMaximum();
    gst_swapb(head->maxValue);
    head->dataOffset = static_cast<unsigned int>(size);
    gst_swapb(head->dataOffset);

    CPL_IGNORE_RET_VAL(VSIFWriteL(head, size, 1, fpImage));

/* -------------------------------------------------------------------- */
/*      Loop over image, copying image data.                            */
/* -------------------------------------------------------------------- */
    unsigned long bytesPerPixel = nBands * nDTSize;

    size_t pageBytes = blockX * blockY * bytesPerPixel;
    char *output = (char *) malloc(pageBytes);
    if (! output)
    {
        CPLError(CE_Failure, CPLE_OutOfMemory,
                 "FITRasterBand couldn't allocate %lu bytes",
                 static_cast<unsigned long>(pageBytes));
        CPL_IGNORE_RET_VAL(VSIFCloseL(fpImage));
        return nullptr;
    }
    FreeGuard<char> guardOutput( output );

    long maxx = (long) ceil(poSrcDS->GetRasterXSize() / (double) blockX);
    long maxy = (long) ceil(poSrcDS->GetRasterYSize() / (double) blockY);
    long maxx_full = (long) floor(poSrcDS->GetRasterXSize() / (double) blockX);
    long maxy_full = (long) floor(poSrcDS->GetRasterYSize() / (double) blockY);

    CPLDebug("FIT", "about to write %ld x %ld blocks", maxx, maxy);

    for(long y=0; y < maxy; y++)
        for(long x=0; x < maxx; x++) {
            long readX = blockX;
            long readY = blockY;
            int do_clean = FALSE;

            // handle cases where image size isn't an exact multiple
            // of page size
            if (x >= maxx_full) {
                readX = poSrcDS->GetRasterXSize() % blockX;
                do_clean = TRUE;
            }
            if (y >= maxy_full) {
                readY = poSrcDS->GetRasterYSize() % blockY;
                do_clean = TRUE;
            }

            // clean out image if only doing partial reads
            if (do_clean)
                memset( output, 0, pageBytes );

            for( int iBand = 0; iBand < nBands; iBand++ ) {
                GDALRasterBand * poBand = poSrcDS->GetRasterBand( iBand+1 );
                CPLErr eErr =
                    poBand->RasterIO( GF_Read, // eRWFlag
                                      static_cast<int>(x * blockX), // nXOff
                                      static_cast<int>(y * blockY), // nYOff
                                      static_cast<int>(readX), // nXSize
                                      static_cast<int>(readY), // nYSize
                                      output + iBand * nDTSize,
                                      // pData
                                      blockX, // nBufXSize
                                      blockY, // nBufYSize
                                      firstBand->GetRasterDataType(),
                                      // eBufType
                                      bytesPerPixel, // nPixelSpace
                                      bytesPerPixel * blockX, nullptr); // nLineSpace
                if (eErr != CE_None)
                {
                    CPLError(CE_Failure, CPLE_FileIO,
                             "FIT write - CreateCopy got read error %i", eErr);
                    CPL_IGNORE_RET_VAL(VSIFCloseL( fpImage ));
                    VSIUnlink( pszFilename );
                    return nullptr;
                }
            } // for iBand

#ifdef swapping
            char *p = output;
            unsigned long i;
            switch(nDTSize) {
            case 1:
                // do nothing
                break;
            case 2:
                for(i=0; i < pageBytes; i+= nDTSize)
                    gst_swap16(p + i);
                break;
            case 4:
                for(i=0; i < pageBytes; i+= nDTSize)
                    gst_swap32(p + i);
                break;
            case 8:
                for(i=0; i < pageBytes; i+= nDTSize)
                    gst_swap64(p + i);
                break;
            default:
                CPLError(CE_Failure, CPLE_NotSupported,
                         "FIT write - unsupported bytesPerPixel %d",
                         nDTSize);
            } // switch
#endif // swapping

            if( VSIFWriteL(output, 1, pageBytes, fpImage) != pageBytes )
            {
                CPLError( CE_Failure, CPLE_FileIO, "Write failed" );
                CPL_IGNORE_RET_VAL(VSIFCloseL( fpImage ));
                VSIUnlink( pszFilename );
                return nullptr;
            }

            double perc = ((double) (y * maxx + x)) / (maxx * maxy);
            if( !pfnProgress( perc, nullptr, pProgressData ) )
            {
                CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
                //free(output);
                CPL_IGNORE_RET_VAL(VSIFCloseL( fpImage ));
                VSIUnlink( pszFilename );
                return nullptr;
            }
        } // for x

    //free(output);

    CPL_IGNORE_RET_VAL(VSIFCloseL( fpImage ));

    pfnProgress( 1.0, nullptr, pProgressData );

/* -------------------------------------------------------------------- */
/*      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;
}
コード例 #12
0
ファイル: gsagdataset.cpp プロジェクト: afarnham/gdal
GDALDataset *GSAGDataset::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, 
                  "GSAG 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, Golden Software ASCII Grid "
		      "format only supports one raster band.\n" );
	    return NULL;
	}
	else
	    CPLError( CE_Warning, CPLE_NotSupported,
		      "Golden Software ASCII Grid format only supports one "
		      "raster band, first band will be copied.\n" );
    }

    if( !pfnProgress( 0.0, NULL, pProgressData ) )
    {
        CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated\n" );
        return NULL;
    }

    VSILFILE *fp = VSIFOpenL( pszFilename, "w+b" );

    if( fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Attempt to create file '%s' failed.\n",
                  pszFilename );
        return NULL;
    }

    int          nXSize = poSrcDS->GetRasterXSize();
    int          nYSize = poSrcDS->GetRasterYSize();
    double	 adfGeoTransform[6];

    poSrcDS->GetGeoTransform( adfGeoTransform );

    std::ostringstream ssHeader;
    ssHeader.precision( nFIELD_PRECISION );
    ssHeader.setf( std::ios::uppercase );

    ssHeader << "DSAA\x0D\x0A";

    ssHeader << nXSize << " " << nYSize << "\x0D\x0A";

    ssHeader << adfGeoTransform[0] + adfGeoTransform[1] / 2 << " "
	     << adfGeoTransform[1] * (nXSize - 0.5) + adfGeoTransform[0]
	     << "\x0D\x0A";

    ssHeader << adfGeoTransform[5] * (nYSize - 0.5) + adfGeoTransform[3] << " "
	     << adfGeoTransform[3] + adfGeoTransform[5] / 2
	     << "\x0D\x0A";

    if( VSIFWriteL( (void *)ssHeader.str().c_str(), 1, ssHeader.str().length(),
		    fp ) != ssHeader.str().length() )
    {
	VSIFCloseL( fp );
        CPLError( CE_Failure, CPLE_FileIO,
                  "Unable to create copy, writing header failed.\n" );
        return NULL;
    }

    /* Save the location and write placeholders for the min/max Z value */
    vsi_l_offset nRangeStart = VSIFTellL( fp );
    const char *szDummyRange = "0.0000000000001 0.0000000000001\x0D\x0A";
    size_t nDummyRangeLen = strlen( szDummyRange );
    if( VSIFWriteL( (void *)szDummyRange, 1, nDummyRangeLen,
		    fp ) != nDummyRangeLen )
    {
	VSIFCloseL( fp );
        CPLError( CE_Failure, CPLE_FileIO,
                  "Unable to create copy, writing header failed.\n" );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Copy band data.							*/
/* -------------------------------------------------------------------- */
    double *pdfData = (double *)VSIMalloc2( nXSize, sizeof( double ) );
    if( pdfData == NULL )
    {
	VSIFCloseL( fp );
	CPLError( CE_Failure, CPLE_OutOfMemory,
		  "Unable to create copy, unable to allocate line buffer.\n" );
	return NULL;
    }

    GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand(1);
    int bSrcHasNDValue;
    double dfSrcNoDataValue = poSrcBand->GetNoDataValue( &bSrcHasNDValue );
    double dfMin = DBL_MAX;
    double dfMax = -DBL_MAX;
    for( int iRow=0; iRow<nYSize; iRow++ )
    {
	CPLErr eErr = poSrcBand->RasterIO( GF_Read, 0, nYSize-iRow-1,
					   nXSize, 1, pdfData,
					   nXSize, 1, GDT_Float64, 0, 0 );

	if( eErr != CE_None )
	{
	    VSIFCloseL( fp );
	    VSIFree( pdfData );
	    return NULL;
	}

	for( int iCol=0; iCol<nXSize; )
	{
	    for( int iCount=0;
		 iCount<10 && iCol<nXSize;
		 iCount++, iCol++ )
	    {
		double dfValue = pdfData[iCol];

		if( bSrcHasNDValue && AlmostEqual( dfValue, dfSrcNoDataValue ) )
		{
		    dfValue = dfNODATA_VALUE;
		}
		else
		{
		    if( dfValue > dfMax )
			dfMax = dfValue;

		    if( dfValue < dfMin )
			dfMin = dfValue;
		}

		std::ostringstream ssOut;
		ssOut.precision(nFIELD_PRECISION);
		ssOut.setf( std::ios::uppercase );
		ssOut << dfValue << " ";
		CPLString sOut = ssOut.str();

		if( VSIFWriteL( sOut.c_str(), 1, sOut.length(), fp )
		    != sOut.length() )
		{
		    VSIFCloseL( fp );
		    VSIFree( pdfData );
		    CPLError( CE_Failure, CPLE_FileIO,
			      "Unable to write grid cell.  Disk full?\n" );
		    return NULL;
		}
	    }

	    if( VSIFWriteL( (void *)"\x0D\x0A", 1, 2, fp ) != 2 )
	    {
		VSIFCloseL( fp );
		VSIFree( pdfData );
		CPLError( CE_Failure, CPLE_FileIO,
			  "Unable to finish write of grid line. Disk full?\n" );
		return NULL;
	    }
	}

	if( VSIFWriteL( (void *)"\x0D\x0A", 1, 2, fp ) != 2 )
	{
	    VSIFCloseL( fp );
	    VSIFree( pdfData );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to finish write of grid row. Disk full?\n" );
	    return NULL;
	}

	if( !pfnProgress( static_cast<double>(iRow + 1)/nYSize,
			  NULL, pProgressData ) )
	{
	    VSIFCloseL( fp );
	    VSIFree( pdfData );
	    CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
	    return NULL;
	}
    }

    VSIFree( pdfData );

    /* write out the min and max values */
    std::ostringstream ssRange;
    ssRange.precision( nFIELD_PRECISION );
    ssRange.setf( std::ios::uppercase );
    ssRange << dfMin << " " << dfMax << "\x0D\x0A";
    if( ssRange.str().length() != nDummyRangeLen )
    {
	int nShiftSize = ssRange.str().length() - nDummyRangeLen;
	if( ShiftFileContents( fp, nRangeStart + nDummyRangeLen,
			       nShiftSize, "\x0D\x0A" ) != CE_None )
	{
	    VSIFCloseL( fp );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to shift file contents.\n" );
	    return NULL;
	}
    }

    if( VSIFSeekL( fp, nRangeStart, SEEK_SET ) != 0 )
    {
	VSIFCloseL( fp );
	CPLError( CE_Failure, CPLE_FileIO,
		  "Unable to seek to start of grid file copy.\n" );
	return NULL;
    }

    if( VSIFWriteL( (void *)ssRange.str().c_str(), 1, ssRange.str().length(),
		    fp ) != ssRange.str().length() )
    {
	VSIFCloseL( fp );
        CPLError( CE_Failure, CPLE_FileIO,
                  "Unable to write range information.\n" );
        return NULL;
    }

    VSIFCloseL( fp );

    GDALPamDataset *poDS = (GDALPamDataset *)GDALOpen( pszFilename,
                                                GA_Update );
    if (poDS)
    {
        poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT );
    }
    return poDS;
}
コード例 #13
0
GDALDataset *GSBGDataset::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, 
                  "GSBG 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, Golden Software Binary Grid "
		      "format only supports one raster band.\n" );
	    return NULL;
	}
	else
	    CPLError( CE_Warning, CPLE_NotSupported,
		      "Golden Software Binary Grid format only supports one "
		      "raster band, first band will be copied.\n" );
    }

    GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 );
    if( poSrcBand->GetXSize() > SHRT_MAX
	|| poSrcBand->GetYSize() > SHRT_MAX )
    {
	CPLError( CE_Failure, CPLE_IllegalArg,
		  "Unable to create grid, Golden Software Binary Grid format "
		  "only supports sizes up to %dx%d.  %dx%d not supported.\n",
		  SHRT_MAX, SHRT_MAX,
		  poSrcBand->GetXSize(), poSrcBand->GetYSize() );

	return NULL;
    }

    if( !pfnProgress( 0.0, NULL, pProgressData ) )
    {
        CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated\n" );
        return NULL;
    }

    VSILFILE    *fp = VSIFOpenL( pszFilename, "w+b" );

    if( fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Attempt to create file '%s' failed.\n",
                  pszFilename );
        return NULL;
    }

    GInt16  nXSize = (GInt16) poSrcBand->GetXSize();
    GInt16  nYSize = (GInt16) poSrcBand->GetYSize();
    double  adfGeoTransform[6];

    poSrcDS->GetGeoTransform( adfGeoTransform );

    double dfMinX = adfGeoTransform[0] + adfGeoTransform[1] / 2;
    double dfMaxX = adfGeoTransform[1] * (nXSize - 0.5) + adfGeoTransform[0];
    double dfMinY = adfGeoTransform[5] * (nYSize - 0.5) + adfGeoTransform[3];
    double dfMaxY = adfGeoTransform[3] + adfGeoTransform[5] / 2;
    CPLErr eErr = WriteHeader( fp, nXSize, nYSize,
			       dfMinX, dfMaxX, dfMinY, dfMaxY, 0.0, 0.0 );

    if( eErr != CE_None )
    {
	VSIFCloseL( fp );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Copy band data.							*/
/* -------------------------------------------------------------------- */
    float *pfData = (float *)VSIMalloc2( nXSize, sizeof( float ) );
    if( pfData == NULL )
    {
	VSIFCloseL( fp );
	CPLError( CE_Failure, CPLE_OutOfMemory,
		  "Unable to create copy, unable to allocate line buffer.\n" );
	return NULL;
    }

    int     bSrcHasNDValue;
    float   fSrcNoDataValue = (float) poSrcBand->GetNoDataValue( &bSrcHasNDValue );
    double  dfMinZ = DBL_MAX;
    double  dfMaxZ = -DBL_MAX;
    for( GInt16 iRow = nYSize - 1; iRow >= 0; iRow-- )
    {
	eErr = poSrcBand->RasterIO( GF_Read, 0, iRow,
				    nXSize, 1, pfData,
				    nXSize, 1, GDT_Float32, 0, 0 );

	if( eErr != CE_None )
	{
	    VSIFCloseL( fp );
	    VSIFree( pfData );
	    return NULL;
	}

	for( int iCol=0; iCol<nXSize; iCol++ )
	{
	    if( bSrcHasNDValue && pfData[iCol] == fSrcNoDataValue )
	    {
		pfData[iCol] = fNODATA_VALUE;
	    }
	    else
	    {
		if( pfData[iCol] > dfMaxZ )
		    dfMaxZ = pfData[iCol];

		if( pfData[iCol] < dfMinZ )
		    dfMinZ = pfData[iCol];
	    }

	    CPL_LSBPTR32( pfData+iCol );
	}

	if( VSIFWriteL( (void *)pfData, 4, nXSize,
			fp ) != static_cast<unsigned>(nXSize) )
	{
	    VSIFCloseL( fp );
	    VSIFree( pfData );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to write grid row. Disk full?\n" );
	    return NULL;
	}

	if( !pfnProgress( static_cast<double>(nYSize - iRow)/nYSize,
			  NULL, pProgressData ) )
	{
	    VSIFCloseL( fp );
	    VSIFree( pfData );
	    CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
	    return NULL;
	}
    }

    VSIFree( pfData );

    /* write out the min and max values */
    eErr = WriteHeader( fp, nXSize, nYSize,
			dfMinX, dfMaxX, dfMinY, dfMaxY, dfMinZ, dfMaxZ );

    if( eErr != CE_None )
    {
	VSIFCloseL( fp );
        return NULL;
    }

    VSIFCloseL( fp );

    GDALPamDataset *poDS = (GDALPamDataset *)GDALOpen( pszFilename,
                                                GA_Update );
    if (poDS)
    {
        poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT );
    }
    return poDS;
}
コード例 #14
0
GDALDataset *GSBGDataset::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, 
                  "GSBG 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, Golden Software Binary Grid "
		      "format only supports one raster band.\n" );
	    return NULL;
	}
	else
	    CPLError( CE_Warning, CPLE_NotSupported,
		      "Golden Software Binary Grid format only supports one "
		      "raster band, first band will be copied.\n" );
    }

    GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 );
    if( poSrcBand->GetXSize() > SHRT_MAX
	|| poSrcBand->GetYSize() > SHRT_MAX )
    {
	CPLError( CE_Failure, CPLE_IllegalArg,
		  "Unable to create grid, Golden Software Binary Grid format "
		  "only supports sizes up to %dx%d.  %dx%d not supported.\n",
		  SHRT_MAX, SHRT_MAX,
		  poSrcBand->GetXSize(), poSrcBand->GetYSize() );

	return NULL;
    }

    if( !pfnProgress( 0.0, NULL, pProgressData ) )
    {
        CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated\n" );
        return NULL;
    }

    VSILFILE    *fp = VSIFOpenL( pszFilename, "w+b" );

    if( fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Attempt to create file '%s' failed.\n",
                  pszFilename );
        return NULL;
    }

    GInt16  nXSize = poSrcBand->GetXSize();
    GInt16  nYSize = poSrcBand->GetYSize();
    double  adfGeoTransform[6];

    poSrcDS->GetGeoTransform( adfGeoTransform );

    double dfMinX = adfGeoTransform[0] + adfGeoTransform[1] / 2;
    double dfMaxX = adfGeoTransform[1] * (nXSize - 0.5) + adfGeoTransform[0];
    double dfMinY = adfGeoTransform[5] * (nYSize - 0.5) + adfGeoTransform[3];
    double dfMaxY = adfGeoTransform[3] + adfGeoTransform[5] / 2;
    CPLErr eErr = WriteHeader( fp, nXSize, nYSize,
			       dfMinX, dfMaxX, dfMinY, dfMaxY, 0.0, 0.0 );

    if( eErr != CE_None )
    {
	VSIFCloseL( fp );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Copy band data.							*/
/* -------------------------------------------------------------------- */
    float *pfData = (float *)VSIMalloc2( nXSize, sizeof( float ) );
    if( pfData == NULL )
    {
	VSIFCloseL( fp );
	CPLError( CE_Failure, CPLE_OutOfMemory,
		  "Unable to create copy, unable to allocate line buffer.\n" );
	return NULL;
    }

    int     bSrcHasNDValue;
    float   fSrcNoDataValue = poSrcBand->GetNoDataValue( &bSrcHasNDValue );
    double  dfMinZ = DBL_MAX;
    double  dfMaxZ = -DBL_MAX;
    for( GInt16 iRow = nYSize - 1; iRow >= 0; iRow-- )
    {
	eErr = poSrcBand->RasterIO( GF_Read, 0, iRow,
				    nXSize, 1, pfData,
				    nXSize, 1, GDT_Float32, 0, 0 );

	if( eErr != CE_None )
	{
	    VSIFCloseL( fp );
	    VSIFree( pfData );
	    return NULL;
	}

	for( int iCol=0; iCol<nXSize; iCol++ )
	{
	    if( bSrcHasNDValue && pfData[iCol] == fSrcNoDataValue )
	    {
		pfData[iCol] = fNODATA_VALUE;
	    }
	    else
	    {
		if( pfData[iCol] > dfMaxZ )
		    dfMaxZ = pfData[iCol];

		if( pfData[iCol] < dfMinZ )
		    dfMinZ = pfData[iCol];
	    }

	    CPL_LSBPTR32( pfData+iCol );
	}

	if( VSIFWriteL( (void *)pfData, 4, nXSize,
			fp ) != static_cast<unsigned>(nXSize) )
	{
	    VSIFCloseL( fp );
	    VSIFree( pfData );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to write grid row. Disk full?\n" );
	    return NULL;
	}

	if( !pfnProgress( static_cast<double>(iRow)/nYSize,
			  NULL, pProgressData ) )
	{
	    VSIFCloseL( fp );
	    VSIFree( pfData );
	    CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
	    return NULL;
	}
    }

    VSIFree( pfData );

    /* write out the min and max values */
    eErr = WriteHeader( fp, nXSize, nYSize,
			dfMinX, dfMaxX, dfMinY, dfMaxY, dfMinZ, dfMaxZ );

    if( eErr != CE_None )
    {
	VSIFCloseL( fp );
        return NULL;
    }

    VSIFCloseL( fp );

    GDALPamDataset *poDstDS = (GDALPamDataset *)GDALOpen( pszFilename,
							  GA_Update );
    if( poDstDS == NULL )
    {
	VSIUnlink( pszFilename );
	CPLError( CE_Failure, CPLE_FileIO,
		  "Unable to open copy of dataset.\n" );
	return NULL;
    }
    else if( dynamic_cast<GSBGDataset *>(poDstDS) == NULL )
    {
	VSIUnlink( pszFilename );
	delete poDstDS;
	CPLError( CE_Failure, CPLE_FileIO,
		  "Copy dataset not opened as Golden Surfer Binary Grid!?\n" );
	return NULL;
    }

    GDALRasterBand *poDstBand = poSrcDS->GetRasterBand(1);
    if( poDstBand == NULL )
    {
	VSIUnlink( pszFilename );
	delete poDstDS;
	CPLError( CE_Failure, CPLE_FileIO,
		  "Unable to open copy of raster band?\n" );
	return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Attempt to copy metadata.					*/
/* -------------------------------------------------------------------- */
    if( !bStrict )
	CPLPushErrorHandler( CPLQuietErrorHandler );

    /* non-zero transform 2 or 4 or negative 1 or 5  not supported natively */
    /*if( adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0
	|| adfGeoTransform[1] < 0.0 || adfGeoTransform[5] < 0.0 )
	poDstDS->GDALPamDataset::SetGeoTransform( adfGeoTransform );*/

    const char *szProjectionRef = poSrcDS->GetProjectionRef();
    if( *szProjectionRef != '\0' )
	poDstDS->SetProjection( szProjectionRef );

    char **pszMetadata = poSrcDS->GetMetadata();
    if( pszMetadata != NULL )
	poDstDS->SetMetadata( pszMetadata );

    /* FIXME:  Should the dataset description be copied as well, or is it
     *         always the file name? */
    poDstBand->SetDescription( poSrcBand->GetDescription() );

    int bSuccess;
    double dfOffset = poSrcBand->GetOffset( &bSuccess );
    if( bSuccess && dfOffset != 0.0 )
	poDstBand->SetOffset( dfOffset );

    double dfScale = poSrcBand->GetScale( &bSuccess );
    if( bSuccess && dfScale != 1.0 )
	poDstBand->SetScale( dfScale );

    GDALColorInterp oColorInterp = poSrcBand->GetColorInterpretation();
    if( oColorInterp != GCI_Undefined )
        poDstBand->SetColorInterpretation( oColorInterp );

    char **pszCatNames = poSrcBand->GetCategoryNames();
    if( pszCatNames != NULL)
	poDstBand->SetCategoryNames( pszCatNames );

    GDALColorTable *poColorTable = poSrcBand->GetColorTable();
    if( poColorTable != NULL )
	poDstBand->SetColorTable( poColorTable );

    if( !bStrict )
	CPLPopErrorHandler();

    return poDstDS;
}
コード例 #15
0
/*!
  \warning   The source raster must have only 1 band. Currently, the values in
             the source raster must be stored in one of the supported cell
             representations (CR_UINT1, CR_INT4, CR_REAL4, CR_REAL8).

  The meta data item PCRASTER_VALUESCALE will be checked to see what value
  scale to use. Otherwise a value scale is determined using
  GDALType2ValueScale(GDALDataType).

  This function always writes rasters using CR_UINT1, CR_INT4 or CR_REAL4
  cell representations.
*/
GDALDataset* PCRasterDataset::createCopy(
    char const* filename,
    GDALDataset* source,
    CPL_UNUSED int strict,
    CPL_UNUSED char** options,
    GDALProgressFunc progress,
    void* progressData)
{
  // Checks.
  int nrBands = source->GetRasterCount();
  if(nrBands != 1) {
    CPLError(CE_Failure, CPLE_NotSupported,
         "PCRaster driver: Too many bands ('%d'): must be 1 band", nrBands);
    return 0;
  }

  GDALRasterBand* raster = source->GetRasterBand(1);

  // Create PCRaster raster. Determine properties of raster to create.
  size_t nrRows = raster->GetYSize();
  size_t nrCols = raster->GetXSize();
  std::string string;

  // The in-file type of the cells.
  CSF_CR fileCellRepresentation = GDALType2CellRepresentation(
         raster->GetRasterDataType(), false);

  if(fileCellRepresentation == CR_UNDEFINED) {
    CPLError(CE_Failure, CPLE_NotSupported,
         "PCRaster driver: Cannot determine a valid cell representation");
    return 0;
  }

  // The value scale of the values.
  CSF_VS valueScale = VS_UNDEFINED;
  if(source->GetMetadataItem("PCRASTER_VALUESCALE")) {
    string = source->GetMetadataItem("PCRASTER_VALUESCALE");
  }

  valueScale = !string.empty()
         ? string2ValueScale(string)
         : GDALType2ValueScale(raster->GetRasterDataType());

  if(valueScale == VS_UNDEFINED) {
    CPLError(CE_Failure, CPLE_NotSupported,
         "PCRaster driver: Cannot determine a valid value scale");
    return 0;
  }

  CSF_PT const projection = PT_YDECT2B;
  REAL8  const angle = 0.0;
  REAL8 west = 0.0;
  REAL8 north = 0.0;
  REAL8 cellSize = 1.0;

  double transform[6];
  if(source->GetGeoTransform(transform) == CE_None) {
    if(transform[2] == 0.0 && transform[4] == 0.0) {
      west = static_cast<REAL8>(transform[0]);
      north = static_cast<REAL8>(transform[3]);
      cellSize = static_cast<REAL8>(transform[1]);
    }
  }

  // The in-memory type of the cells.
  CSF_CR appCellRepresentation = CR_UNDEFINED;
  appCellRepresentation = GDALType2CellRepresentation(
         raster->GetRasterDataType(), true);

  if(appCellRepresentation == CR_UNDEFINED) {
    CPLError(CE_Failure, CPLE_NotSupported,
         "PCRaster driver: Cannot determine a valid cell representation");
    return 0;
  }

  // Check whether value scale fits the cell representation. Adjust when
  // needed.
  valueScale = fitValueScale(valueScale, appCellRepresentation);

  // Create a raster with the in file cell representation.
  MAP* map = Rcreate(filename, nrRows, nrCols, fileCellRepresentation,
         valueScale, projection, west, north, angle, cellSize);

  if(!map) {
    CPLError(CE_Failure, CPLE_OpenFailed,
         "PCRaster driver: Unable to create raster %s", filename);
    return 0;
  }

  // Try to convert in app cell representation to the cell representation
  // of the file.
  if(RuseAs(map, appCellRepresentation)) {
    CPLError(CE_Failure, CPLE_NotSupported,
         "PCRaster driver: Cannot convert cells: %s", MstrError());
    Mclose(map);
    return 0;
  }

  int hasMissingValue;
  double missingValue = raster->GetNoDataValue(&hasMissingValue);

  // This is needed to get my (KDJ) unit tests running.
  // I am still uncertain why this is needed. If the input raster has float32
  // values and the output int32, than the missing value in the dataset object
  // is not updated like the values are.
  if(missingValue == ::missingValue(CR_REAL4) &&
         fileCellRepresentation == CR_INT4) {
    missingValue = ::missingValue(fileCellRepresentation);
  }

  // TODO conversie van INT2 naar INT4 ondersteunen. zie ruseas.c regel 503.
  // conversie op r 159.

  // Create buffer for one row of values.
  void* buffer = Rmalloc(map, nrCols);

  // Copy values from source to target.
  CPLErr errorCode = CE_None;
  for(size_t row = 0; errorCode == CE_None && row < nrRows; ++row) {

    // Get row from source.
    if(raster->RasterIO(GF_Read, 0, row, nrCols, 1, buffer, nrCols, 1,
         raster->GetRasterDataType(), 0, 0, NULL) != CE_None) {
      CPLError(CE_Failure, CPLE_FileIO,
         "PCRaster driver: Error reading from source raster");
      errorCode = CE_Failure;
      break;
    }

    // Upon reading values are converted to the
    // right data type. This includes the missing value. If the source
    // value cannot be represented in the target data type it is set to a
    // missing value.

    if(hasMissingValue) {
      alterToStdMV(buffer, nrCols, appCellRepresentation, missingValue);
    }

    if(valueScale == VS_BOOLEAN) {
      castValuesToBooleanRange(buffer, nrCols, appCellRepresentation);
    }

    // Write row in target.
    RputRow(map, row, buffer);

    if(!progress((row + 1) / (static_cast<double>(nrRows)), 0, progressData)) {
      CPLError(CE_Failure, CPLE_UserInterrupt,
         "PCRaster driver: User terminated CreateCopy()");
      errorCode = CE_Failure;
      break;
    }
  }

  Mclose(map);
  map = 0;

  free(buffer);
  buffer = 0;

  if( errorCode != CE_None )
      return NULL;

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

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

  return poDS;
}
コード例 #16
0
ファイル: rcreatecopy.cpp プロジェクト: brunosimoes/WorldWind
GDALDataset *
RCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
             int bStrict, char ** papszOptions, 
             GDALProgressFunc pfnProgress, void * pProgressData )

{
    int  nBands = poSrcDS->GetRasterCount();
    int  nXSize = poSrcDS->GetRasterXSize();
    int  nYSize = poSrcDS->GetRasterYSize();
    int  bASCII = CSLFetchBoolean( papszOptions, "ASCII", FALSE );
    int  bCompressed = CSLFetchBoolean( papszOptions, "COMPRESS", !bASCII );

/* -------------------------------------------------------------------- */
/*      Some some rudimentary checks                                    */
/* -------------------------------------------------------------------- */

/* -------------------------------------------------------------------- */
/*      Setup the filename to actually use.  We prefix with             */
/*      /vsigzip/ if we want compressed output.                         */
/* -------------------------------------------------------------------- */
    CPLString osAdjustedFilename;

    if( bCompressed )
        osAdjustedFilename = "/vsigzip/";

    osAdjustedFilename += pszFilename;

/* -------------------------------------------------------------------- */
/*      Create the file.                                                */
/* -------------------------------------------------------------------- */
    FILE	*fp;

    fp = VSIFOpenL( osAdjustedFilename, "wb" );
    if( fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "Unable to create file %s.\n", 
                  pszFilename );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Write header with version, etc.                                 */
/* -------------------------------------------------------------------- */
    if( bASCII )
    {
        const char *pszHeader = "RDA2\nA\n";
        VSIFWriteL( pszHeader, 1, strlen(pszHeader), fp );
    }
    else
    {
        const char *pszHeader = "RDX2\nX\n";
        VSIFWriteL( pszHeader, 1, strlen(pszHeader), fp );
    }

    RWriteInteger( fp, bASCII, 2 );
    RWriteInteger( fp, bASCII, 133377 );
    RWriteInteger( fp, bASCII, 131840 );

/* -------------------------------------------------------------------- */
/*      Establish the primary pairlist with one component object.       */
/* -------------------------------------------------------------------- */
    RWriteInteger( fp, bASCII, 1026 );
    RWriteInteger( fp, bASCII, 1 );  

/* -------------------------------------------------------------------- */
/*      Write the object name.  Eventually we should derive this        */
/*      from the filename, possible with override by a creation         */
/*      option.                                                         */
/* -------------------------------------------------------------------- */
    RWriteString( fp, bASCII, "gg" );

/* -------------------------------------------------------------------- */
/*      For now we write the raster as a numeric array with             */
/*      attributes (526).                                               */
/* -------------------------------------------------------------------- */
    RWriteInteger( fp, bASCII, 526 );
    RWriteInteger( fp, bASCII, nXSize * nYSize * nBands );

/* -------------------------------------------------------------------- */
/*      Write the raster data.                                          */
/* -------------------------------------------------------------------- */
    double 	*padfScanline;
    CPLErr      eErr = CE_None;
    int         iLine;

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

    for( int iBand = 0; iBand < nBands; iBand++ )
    {
        GDALRasterBand * poBand = poSrcDS->GetRasterBand( iBand+1 );

        for( iLine = 0; iLine < nYSize && eErr == CE_None; iLine++ )
        {
            int iValue;

            eErr = poBand->RasterIO( GF_Read, 0, iLine, nXSize, 1, 
                                     padfScanline, nXSize, 1, GDT_Float64,
                                     sizeof(double), 0 );

            if( bASCII )
            {
                for( iValue = 0; iValue < nXSize; iValue++ )
                {
                    char szValue[128];
                    sprintf(szValue,"%.16g\n", padfScanline[iValue] );
                    VSIFWriteL( szValue, 1, strlen(szValue), fp );
                }
            }
            else
            {
                for( iValue = 0; iValue < nXSize; iValue++ )
                    CPL_MSBPTR64( padfScanline + iValue );

                VSIFWriteL( padfScanline, 8, nXSize, fp );
            }
            
            if( eErr == CE_None
                && !pfnProgress( (iLine+1) / (double) nYSize,
                                 NULL, pProgressData ) )
            {
                eErr = CE_Failure;
                CPLError( CE_Failure, CPLE_UserInterrupt,
                          "User terminated CreateCopy()" );
            }
        }
    }

    CPLFree( padfScanline );

/* -------------------------------------------------------------------- */
/*      Write out the dims attribute.                                   */
/* -------------------------------------------------------------------- */
    RWriteInteger( fp, bASCII, 1026 );
    RWriteInteger( fp, bASCII, 1 );  
    
    RWriteString( fp, bASCII, "dim" );

    RWriteInteger( fp, bASCII, 13 );
    RWriteInteger( fp, bASCII, 3 );
    RWriteInteger( fp, bASCII, nXSize );
    RWriteInteger( fp, bASCII, nYSize );
    RWriteInteger( fp, bASCII, nBands );

    RWriteInteger( fp, bASCII, 254 );

/* -------------------------------------------------------------------- */
/*      Terminate overall pairlist.                                     */
/* -------------------------------------------------------------------- */
    RWriteInteger( fp, bASCII, 254 );

/* -------------------------------------------------------------------- */
/*      Cleanup.                                                        */
/* -------------------------------------------------------------------- */
    VSIFCloseL( fp );

    if( eErr != CE_None )
        return NULL;

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

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

    return poDS;
}