Пример #1
0
GDALDataset *ARGDataset::Open( GDALOpenInfo *poOpenInfo )
{
    if ( !Identify( poOpenInfo ) || poOpenInfo->fpL == nullptr )
        return nullptr;

/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "The ARG driver does not support update access to existing"
                  " datasets." );
        return nullptr;
    }
/* -------------------------------------------------------------------- */
/*      Check metadata settings in JSON.                                */
/* -------------------------------------------------------------------- */

    json_object *pJSONObject = GetJsonObject(poOpenInfo->pszFilename);

    if (pJSONObject == nullptr) {
        CPLError(CE_Failure, CPLE_AppDefined, "Error parsing JSON.");
        return nullptr;
    }

    // get the type (always 'arg')
    const char *pszJSONStr = GetJsonValueStr(pJSONObject, "type");
    if (pszJSONStr == nullptr ) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'type' is missing from the JSON file.");
        json_object_put(pJSONObject);
        pJSONObject = nullptr;
        return nullptr;
    }
    else if (!EQUAL(pszJSONStr, "arg")) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'type' is not recognized: '%s'.", pszJSONStr);
        json_object_put(pJSONObject);
        pJSONObject = nullptr;
        return nullptr;
    }

    double dfNoDataValue;
    GDALDataType eType;
    int nPixelOffset;

    // get the datatype
    pszJSONStr = GetJsonValueStr(pJSONObject, "datatype");
    if (pszJSONStr == nullptr) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'datatype' is missing from the JSON file.");
        json_object_put(pJSONObject);
        pJSONObject = nullptr;
        return nullptr;
    }
    else if (EQUAL(pszJSONStr, "int8")) {
        CPLDebug("ARGDataset", "Open(): "
            "int8 data is not supported in GDAL -- mapped to uint8");
        eType = GDT_Byte;
        nPixelOffset = 1;
        dfNoDataValue = 128;
    }
    else if (EQUAL(pszJSONStr, "int16")) {
        eType = GDT_Int16;
        nPixelOffset = 2;
        dfNoDataValue = -32767;
    }
    else if (EQUAL(pszJSONStr, "int32")) {
        eType = GDT_Int32;
        nPixelOffset = 4;
        dfNoDataValue = -2e31;
    }
    else if (EQUAL(pszJSONStr, "uint8")) {
        eType = GDT_Byte;
        nPixelOffset = 1;
        dfNoDataValue = 255;
    }
    else if (EQUAL(pszJSONStr, "uint16")) {
        eType = GDT_UInt16;
        nPixelOffset = 2;
        dfNoDataValue = 65535;
    }
    else if (EQUAL(pszJSONStr, "uint32")) {
        eType = GDT_UInt32;
        nPixelOffset = 4;
        dfNoDataValue = -2e31;
    }
    else if (EQUAL(pszJSONStr, "float32")) {
        eType = GDT_Float32;
        nPixelOffset = 4;
        dfNoDataValue = std::numeric_limits<double>::quiet_NaN();
    }
    else if (EQUAL(pszJSONStr, "float64")) {
        eType = GDT_Float64;
        nPixelOffset = 8;
        dfNoDataValue = std::numeric_limits<double>::quiet_NaN();
    }
    else {
        if (EQUAL(pszJSONStr, "int64") ||
            EQUAL(pszJSONStr, "uint64")) {
            CPLError(CE_Failure, CPLE_AppDefined,
                "The ARG 'datatype' is unsupported in GDAL: '%s'.", pszJSONStr);
        }
        else {
            CPLError(CE_Failure, CPLE_AppDefined,
                "The ARG 'datatype' is unknown: '%s'.", pszJSONStr);
        }
        json_object_put(pJSONObject);
        pJSONObject = nullptr;
        return nullptr;
    }

    // get the xmin of the bounding box
    const double dfXmin = GetJsonValueDbl(pJSONObject, "xmin");
    if (CPLIsNan(dfXmin)) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'xmin' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = nullptr;
        return nullptr;
    }

    // get the ymin of the bounding box
    const double dfYmin = GetJsonValueDbl(pJSONObject, "ymin");
    if (CPLIsNan(dfYmin)) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'ymin' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = nullptr;
        return nullptr;
    }

    // get the xmax of the bounding boxfpL
    const double dfXmax = GetJsonValueDbl(pJSONObject, "xmax");
    if (CPLIsNan(dfXmax)) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'xmax' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = nullptr;
        return nullptr;
    }

    // get the ymax of the bounding box
    const double dfYmax = GetJsonValueDbl(pJSONObject, "ymax");
    if (CPLIsNan(dfYmax)) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'ymax' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = nullptr;
        return nullptr;
    }

    // get the cell width
    const double dfCellwidth = GetJsonValueDbl(pJSONObject, "cellwidth");
    if (CPLIsNan(dfCellwidth)) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'cellwidth' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = nullptr;
        return nullptr;
    }

    // get the cell height
    const double dfCellheight = GetJsonValueDbl(pJSONObject, "cellheight");
    if (CPLIsNan(dfCellheight)) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'cellheight' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = nullptr;
        return nullptr;
    }

    double dfXSkew = GetJsonValueDbl(pJSONObject, "xskew");
    if (CPLIsNan(dfXSkew)) {
        // not an error -- default to 0.0
        dfXSkew = 0.0f;
    }

    double dfYSkew = GetJsonValueDbl(pJSONObject, "yskew");
    if (CPLIsNan(dfYSkew)) {
        // not an error -- default to 0.0
        dfYSkew = 0.0f;
    }

    // get the rows
    const int nRows = GetJsonValueInt(pJSONObject, "rows");
    if (nRows < 0) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'rows' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = nullptr;
        return nullptr;
    }

    // get the columns
    const int nCols = GetJsonValueInt(pJSONObject, "cols");
    if (nCols < 0) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'cols' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = nullptr;
        return nullptr;
    }

    int nSrs = GetJsonValueInt(pJSONObject, "epsg");
    if (nSrs < 0) {
        // not an error -- default to web mercator
        nSrs = 3857;
    }

    OGRSpatialReference oSRS;
    OGRErr nErr = oSRS.importFromEPSG(nSrs);
    if (nErr != OGRERR_NONE) {
        nErr = oSRS.importFromEPSG(3857);

        if (nErr == OGRERR_NONE) {
            CPLDebug("ARGDataset", "Open(): "
                     "The EPSG provided did not import cleanly. "
                     "Defaulting to EPSG:3857");
        }
        else {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "The 'epsg' value did not translate to a known "
                      "spatial reference. "
                      "Please check the 'epsg' value and try again.");

            json_object_put(pJSONObject);
            pJSONObject = nullptr;

            return nullptr;
        }
    }

    char *pszWKT = nullptr;
    nErr = oSRS.exportToWkt(&pszWKT);
    if (nErr != OGRERR_NONE) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The spatial reference is known, but could not be set on the "
            "dataset. Please check the 'epsg' value and try again.");

        json_object_put(pJSONObject);
        pJSONObject = nullptr;

        return nullptr;
    }

    // get the layer (always the file basename)
    pszJSONStr = GetJsonValueStr(pJSONObject, "layer");
    if (pszJSONStr == nullptr) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'layer' is missing from the JSON file.");
        json_object_put(pJSONObject);
        pJSONObject = nullptr;
        CPLFree(pszWKT);
        return nullptr;
    }

    char *pszLayer = CPLStrdup(pszJSONStr);

    // done with the json object now
    json_object_put(pJSONObject);
    pJSONObject = nullptr;

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    ARGDataset *poDS = new ARGDataset();

    poDS->pszFilename = CPLStrdup(poOpenInfo->pszFilename);
    poDS->SetMetadataItem("LAYER",pszLayer,nullptr);
    poDS->nRasterXSize = nCols;
    poDS->nRasterYSize = nRows;
    poDS->SetProjection( pszWKT );

    // done with the projection string
    CPLFree(pszWKT);
    CPLFree(pszLayer);

/* -------------------------------------------------------------------- */
/*      Assume ownership of the file handled from the GDALOpenInfo.     */
/* -------------------------------------------------------------------- */
    poDS->fpImage = poOpenInfo->fpL;
    poOpenInfo->fpL = nullptr;

    poDS->adfGeoTransform[0] = dfXmin;
    poDS->adfGeoTransform[1] = dfCellwidth;
    poDS->adfGeoTransform[2] = dfXSkew;
    poDS->adfGeoTransform[3] = dfYmax;
    poDS->adfGeoTransform[4] = dfYSkew;
    poDS->adfGeoTransform[5] = -dfCellheight;

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
#ifdef CPL_LSB
    bool bNative = false;
#else
    bool bNative = true;
#endif

    RawRasterBand *poBand
        = new RawRasterBand( poDS, 1, poDS->fpImage,
                             0, nPixelOffset, nPixelOffset * nCols,
                             eType, bNative, RawRasterBand::OwnFP::NO );
    poDS->SetBand( 1, poBand );

    poBand->SetNoDataValue( dfNoDataValue );

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();

/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    return poDS;
}
GDALDataset *ARGDataset::Open( GDALOpenInfo * poOpenInfo )
{
    json_object * pJSONObject;
    const char * pszJSONStr;
    char * pszLayer;
    /***** items from the json metadata *****/
    GDALDataType eType = GDT_Unknown;
    double fXmin = 0.0;
    double fYmin = 0.0;
    double fXmax = 0.0;
    double fYmax = 0.0;
    double fCellwidth = 1.0;
    double fCellheight = 1.0;
    double fXSkew = 0.0;
    double fYSkew = 0.0;
    int nRows = 0;
    int nCols = 0;
    int nSrs = 3857;
    /***** items from the json metadata *****/
    int nPixelOffset = 0;
    double fNoDataValue = NAN;

    char * pszWKT = NULL;
    OGRSpatialReference oSRS;
    OGRErr nErr = OGRERR_NONE;

    if ( !Identify( poOpenInfo ) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Check metadata settings in JSON.                                */
/* -------------------------------------------------------------------- */

    pJSONObject = GetJsonObject(poOpenInfo->pszFilename);

    if (pJSONObject == NULL) {
        CPLError(CE_Failure, CPLE_AppDefined, "Error parsing JSON.");
        return NULL;
    }

    // get the type (always 'arg')
    pszJSONStr = GetJsonValueStr(pJSONObject, "type");
    if (pszJSONStr == NULL ) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'type' is missing from the JSON file.");
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }
    else if (!EQUAL(pszJSONStr, "arg")) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'type' is not recognized: '%s'.", pszJSONStr);
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }

    // get the datatype
    pszJSONStr = GetJsonValueStr(pJSONObject, "datatype");
    if (pszJSONStr == NULL) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'datatype' is missing from the JSON file.");
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }
    else if (EQUAL(pszJSONStr, "int8")) {
        CPLDebug("ARGDataset", "Open(): "
            "int8 data is not supported in GDAL -- mapped to uint8");
        eType = GDT_Byte; 
        nPixelOffset = 1;
        fNoDataValue = 128;
    }
    else if (EQUAL(pszJSONStr, "int16")) {
        eType = GDT_Int16;
        nPixelOffset = 2;
        fNoDataValue = -32767;
    }
    else if (EQUAL(pszJSONStr, "int32")) {
        eType = GDT_Int32;
        nPixelOffset = 4;
        fNoDataValue = -2e31;
    }
    else if (EQUAL(pszJSONStr, "uint8")) {
        eType = GDT_Byte; 
        nPixelOffset = 1;
        fNoDataValue = 255;
    }
    else if (EQUAL(pszJSONStr, "uint16")) {
        eType = GDT_UInt16;
        nPixelOffset = 2;
        fNoDataValue = 65535;
    }
    else if (EQUAL(pszJSONStr, "uint32")) {
        eType = GDT_UInt32;
        nPixelOffset = 4;
        fNoDataValue = -2e31;
    }
    else if (EQUAL(pszJSONStr, "float32")) {
        eType = GDT_Float32;
        nPixelOffset = 4;
        fNoDataValue = NAN;
    }
    else if (EQUAL(pszJSONStr, "float64")) { 
        eType = GDT_Float64;
        nPixelOffset = 8;
        fNoDataValue = NAN;
    }
    else {
        if (EQUAL(pszJSONStr, "int64") ||
            EQUAL(pszJSONStr, "uint64")) {
            CPLError(CE_Failure, CPLE_AppDefined,
                "The ARG 'datatype' is unsupported in GDAL: '%s'.", pszJSONStr);
        }
        else {
            CPLError(CE_Failure, CPLE_AppDefined,
                "The ARG 'datatype' is unknown: '%s'.", pszJSONStr);
        }
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }

    // get the xmin of the bounding box
    fXmin = GetJsonValueDbl(pJSONObject, "xmin");
    if (CPLIsNan(fXmin)) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'xmin' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }
    
    // get the ymin of the bounding box
    fYmin = GetJsonValueDbl(pJSONObject, "ymin");
    if (CPLIsNan(fYmin)) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'ymin' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }

    // get the xmax of the bounding box
    fXmax = GetJsonValueDbl(pJSONObject, "xmax");
    if (CPLIsNan(fXmax)) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'xmax' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }

    // get the ymax of the bounding box
    fYmax = GetJsonValueDbl(pJSONObject, "ymax");
    if (CPLIsNan(fYmax)) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'ymax' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }

    // get the cell width
    fCellwidth = GetJsonValueDbl(pJSONObject, "cellwidth");
    if (CPLIsNan(fCellwidth)) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'cellwidth' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }

    // get the cell height
    fCellheight = GetJsonValueDbl(pJSONObject, "cellheight");
    if (CPLIsNan(fCellheight)) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'cellheight' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }

    fXSkew = GetJsonValueDbl(pJSONObject, "xskew");
    if (CPLIsNan(fXSkew)) {
        // not an error -- default to 0.0
        fXSkew = 0.0f;
    }

    fYSkew = GetJsonValueDbl(pJSONObject, "yskew");
    if (CPLIsNan(fYSkew)) {
        // not an error -- default to 0.0
        fYSkew = 0.0f;
    }

    // get the rows
    nRows = GetJsonValueInt(pJSONObject, "rows");
    if (nRows < 0) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'rows' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }

    // get the columns
    nCols = GetJsonValueInt(pJSONObject, "cols");
    if (nCols < 0) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'cols' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }

    nSrs = GetJsonValueInt(pJSONObject, "epsg");
    if (nSrs < 0) {
        // not an error -- default to web mercator
        nSrs = 3857;
    }

    nErr = oSRS.importFromEPSG(nSrs);
    if (nErr != OGRERR_NONE) {
        nErr = oSRS.importFromEPSG(3857);

        if (nErr == OGRERR_NONE) {
            CPLDebug("ARGDataset", "Open(): "
                "The EPSG provided did not import cleanly. Defaulting to EPSG:3857");
        }
        else {
            CPLError(CE_Failure, CPLE_AppDefined,
                "The 'epsg' value did not transate to a known spatial reference."
                " Please check the 'epsg' value and try again.");

            json_object_put(pJSONObject);
            pJSONObject = NULL;

            return NULL;
        }
    }

    nErr = oSRS.exportToWkt(&pszWKT);
    if (nErr != OGRERR_NONE) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The spatial reference is known, but could not be set on the "
            "dataset. Please check the 'epsg' value and try again.");

        json_object_put(pJSONObject);
        pJSONObject = NULL;

        return NULL;
    }

    // get the layer (always the file basename)
    pszJSONStr = GetJsonValueStr(pJSONObject, "layer");
    if (pszJSONStr == NULL) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'layer' is missing from the JSON file.");
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }

    pszLayer = CPLStrdup(pszJSONStr);

    // done with the json object now
    json_object_put(pJSONObject);
    pJSONObject = NULL;

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    ARGDataset *poDS;

    poDS = new ARGDataset();

    poDS->pszFilename = CPLStrdup(poOpenInfo->pszFilename);
    poDS->SetMetadataItem("LAYER",pszLayer,NULL);
    poDS->nRasterXSize = nCols;
    poDS->nRasterYSize = nRows;
    poDS->SetProjection( pszWKT );

    // done with the projection string
    CPLFree(pszWKT);
    CPLFree(pszLayer);

/* -------------------------------------------------------------------- */
/*      Assume ownership of the file handled from the GDALOpenInfo.     */
/* -------------------------------------------------------------------- */
    poDS->fpImage = VSIFOpenL(poOpenInfo->pszFilename, "rb");
    if (poDS->fpImage == NULL)
    {
        delete poDS;
        CPLError(CE_Failure, CPLE_AppDefined,
            "Could not open dataset '%s'", poOpenInfo->pszFilename);
        return NULL;
    }

    poDS->adfGeoTransform[0] = fXmin;
    poDS->adfGeoTransform[1] = fCellwidth;
    poDS->adfGeoTransform[2] = fXSkew;
    poDS->adfGeoTransform[3] = fYmax;
    poDS->adfGeoTransform[4] = fYSkew;
    poDS->adfGeoTransform[5] = -fCellheight;
    
/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    RawRasterBand *poBand;

#ifdef CPL_LSB
    int bNative = FALSE;
#else
    int bNative = TRUE;
#endif

    poBand = new RawRasterBand( poDS, 1, poDS->fpImage,
                                0, nPixelOffset, nPixelOffset * nCols,
                                eType, bNative, TRUE );
    poDS->SetBand( 1, poBand );

    poBand->SetNoDataValue( fNoDataValue );

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();
    
/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    return( poDS );
}