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 ); }