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 *GTXDataset::Open( GDALOpenInfo * poOpenInfo ) { if( !Identify( poOpenInfo ) ) return NULL; /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ GTXDataset *poDS = new GTXDataset(); poDS->eAccess = poOpenInfo->eAccess; /* -------------------------------------------------------------------- */ /* Open the file. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_ReadOnly ) poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); else poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb+" ); if( poDS->fpImage == NULL ) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Read the header. */ /* -------------------------------------------------------------------- */ poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[4] = 0.0; CPL_IGNORE_RET_VAL(VSIFReadL( poDS->adfGeoTransform+3, 8, 1, poDS->fpImage )); CPL_IGNORE_RET_VAL(VSIFReadL( poDS->adfGeoTransform+0, 8, 1, poDS->fpImage )); CPL_IGNORE_RET_VAL(VSIFReadL( poDS->adfGeoTransform+5, 8, 1, poDS->fpImage )); CPL_IGNORE_RET_VAL(VSIFReadL( poDS->adfGeoTransform+1, 8, 1, poDS->fpImage )); CPL_IGNORE_RET_VAL(VSIFReadL( &(poDS->nRasterYSize), 4, 1, poDS->fpImage )); CPL_IGNORE_RET_VAL(VSIFReadL( &(poDS->nRasterXSize), 4, 1, poDS->fpImage )); CPL_MSBPTR32( &(poDS->nRasterYSize) ); CPL_MSBPTR32( &(poDS->nRasterXSize) ); CPL_MSBPTR64( poDS->adfGeoTransform + 0 ); CPL_MSBPTR64( poDS->adfGeoTransform + 1 ); CPL_MSBPTR64( poDS->adfGeoTransform + 3 ); CPL_MSBPTR64( poDS->adfGeoTransform + 5 ); poDS->adfGeoTransform[3] += poDS->adfGeoTransform[5] * (poDS->nRasterYSize-1); poDS->adfGeoTransform[0] -= poDS->adfGeoTransform[1] * 0.5; poDS->adfGeoTransform[3] += poDS->adfGeoTransform[5] * 0.5; poDS->adfGeoTransform[5] *= -1; if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize)) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Guess the data type. Since October 1, 2009, it should be */ /* Float32. Before it was double. */ /* -------------------------------------------------------------------- */ CPL_IGNORE_RET_VAL(VSIFSeekL(poDS->fpImage, 0, SEEK_END)); const vsi_l_offset nSize = VSIFTellL(poDS->fpImage); GDALDataType eDT = GDT_Float32; if( nSize == 40 + 8 * static_cast<vsi_l_offset>(poDS->nRasterXSize) * poDS->nRasterYSize ) eDT = GDT_Float64; const int nDTSize = GDALGetDataTypeSizeBytes(eDT); /* -------------------------------------------------------------------- */ /* Create band information object. */ /* -------------------------------------------------------------------- */ RawRasterBand *poBand = new RawRasterBand( poDS, 1, poDS->fpImage, (poDS->nRasterYSize-1) * poDS->nRasterXSize*nDTSize + 40, nDTSize, poDS->nRasterXSize * -nDTSize, eDT, !CPL_IS_LSB, TRUE, FALSE ); poBand->SetNoDataValue( -88.8888 ); poDS->SetBand( 1, poBand ); /* -------------------------------------------------------------------- */ /* 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 ); }
GDALDataset *GSCDataset::Open( GDALOpenInfo * poOpenInfo ) { int nPixels, nLines, i, nRecordLen; /* -------------------------------------------------------------------- */ /* Does this plausible look like a GSC Geogrid file? */ /* -------------------------------------------------------------------- */ if( poOpenInfo->nHeaderBytes < 20 ) return NULL; if( poOpenInfo->pabyHeader[12] != 0x02 || poOpenInfo->pabyHeader[13] != 0x00 || poOpenInfo->pabyHeader[14] != 0x00 || poOpenInfo->pabyHeader[15] != 0x00 ) return NULL; nRecordLen = CPL_LSBWORD32(((GInt32 *) poOpenInfo->pabyHeader)[0]); nPixels = CPL_LSBWORD32(((GInt32 *) poOpenInfo->pabyHeader)[1]); nLines = CPL_LSBWORD32(((GInt32 *) poOpenInfo->pabyHeader)[2]); if( nPixels < 1 || nLines < 1 || nPixels > 100000 || nLines > 100000 ) return NULL; if( nRecordLen != nPixels * 4 ) return NULL; /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The GSC driver does not support update access to existing" " datasets.\n" ); return NULL; } nRecordLen += 8; /* for record length markers */ /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ GSCDataset *poDS; poDS = new GSCDataset(); poDS->nRasterXSize = nPixels; poDS->nRasterYSize = nLines; /* -------------------------------------------------------------------- */ /* Assume ownership of the file handled from the GDALOpenInfo. */ /* -------------------------------------------------------------------- */ poDS->fpImage = VSIFOpenL(poOpenInfo->pszFilename, "rb"); if (poDS->fpImage == NULL) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Read the header information in the second record. */ /* -------------------------------------------------------------------- */ float afHeaderInfo[8]; if( VSIFSeekL( poDS->fpImage, nRecordLen + 12, SEEK_SET ) != 0 || VSIFReadL( afHeaderInfo, sizeof(float), 8, poDS->fpImage ) != 8 ) { CPLError( CE_Failure, CPLE_FileIO, "Failure reading second record of GSC file with %d record length.", nRecordLen ); delete poDS; return NULL; } for( i = 0; i < 8; i++ ) { CPL_LSBPTR32( afHeaderInfo + i ); } poDS->adfGeoTransform[0] = afHeaderInfo[2]; poDS->adfGeoTransform[1] = afHeaderInfo[0]; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = afHeaderInfo[5]; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = -afHeaderInfo[1]; /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ RawRasterBand *poBand; #ifdef CPL_LSB int bNative = TRUE; #else int bNative = FALSE; #endif poBand = new RawRasterBand( poDS, 1, poDS->fpImage, nRecordLen * 2 + 4, sizeof(float), nRecordLen, GDT_Float32, bNative, TRUE ); poDS->SetBand( 1, poBand ); poBand->SetNoDataValue( -1.0000000150474662199e+30 ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
int PDSDataset::ParseImage( CPLString osPrefix ) { /* ------------------------------------------------------------------- */ /* We assume the user is pointing to the label (ie. .lbl) file. */ /* ------------------------------------------------------------------- */ // IMAGE can be inline or detached and point to an image name // ^IMAGE = 3 // ^IMAGE = "GLOBAL_ALBEDO_8PPD.IMG" // ^IMAGE = "MEGT90N000CB.IMG" // ^IMAGE = ("BLAH.IMG",1) -- start at record 1 (1 based) // ^IMAGE = ("BLAH.IMG") -- still start at record 1 (equiv of "BLAH.IMG") // ^IMAGE = ("BLAH.IMG", 5 <BYTES>) -- start at byte 5 (the fifth byte in the file) // ^IMAGE = 10851 <BYTES> // ^SPECTRAL_QUBE = 5 for multi-band images CPLString osImageKeyword = osPrefix + "^IMAGE"; CPLString osQube = GetKeyword( osImageKeyword, "" ); CPLString osTargetFile = GetDescription(); if (EQUAL(osQube,"")) { osImageKeyword = "^SPECTRAL_QUBE"; osQube = GetKeyword( osImageKeyword ); } int nQube = atoi(osQube); int nDetachedOffset = 0; int bDetachedOffsetInBytes = FALSE; if( osQube.size() && osQube[0] == '(' ) { osQube = "\""; osQube += GetKeywordSub( osImageKeyword, 1 ); osQube += "\""; nDetachedOffset = atoi(GetKeywordSub( osImageKeyword, 2, "1")) - 1; // If this is not explicitly in bytes, then it is assumed to be in // records, and we need to translate to bytes. if (strstr(GetKeywordSub(osImageKeyword,2),"<BYTES>") != NULL) bDetachedOffsetInBytes = TRUE; } if( osQube.size() && osQube[0] == '"' ) { CPLString osTPath = CPLGetPath(GetDescription()); CPLString osFilename = osQube; CleanString( osFilename ); osTargetFile = CPLFormCIFilename( osTPath, osFilename, NULL ); osExternalCube = osTargetFile; } GDALDataType eDataType = GDT_Byte; //image parameters int nRows, nCols, nBands = 1; int nSkipBytes = 0; int itype; int record_bytes; char chByteOrder = 'M'; //default to MSB double dfNoData = 0.0; /* -------------------------------------------------------------------- */ /* Checks to see if this is raw PDS image not compressed image */ /* so ENCODING_TYPE either does not exist or it equals "N/A". */ /* Compressed types will not be supported in this routine */ /* -------------------------------------------------------------------- */ const char *value; CPLString osEncodingType = GetKeyword(osPrefix+"IMAGE.ENCODING_TYPE","N/A"); CleanString(osEncodingType); if ( !EQUAL(osEncodingType.c_str(),"N/A") ) { CPLError( CE_Failure, CPLE_OpenFailed, "*** PDS image file has an ENCODING_TYPE parameter:\n" "*** gdal pds driver does not support compressed image types\n" "found: (%s)\n\n", osEncodingType.c_str() ); return FALSE; } /**************** end ENCODING_TYPE check ***********************/ /*********** Grab layout type (BSQ, BIP, BIL) ************/ // AXIS_NAME = (SAMPLE,LINE,BAND) /*********** Grab samples lines band **************/ /** if AXIS_NAME = "" then Bands=1 and Sample and Lines **/ /** are there own keywords "LINES" and "LINE_SAMPLES" **/ /** if not NULL then CORE_ITEMS keyword i.e. (234,322,2) **/ /***********************************************************/ char szLayout[10] = "BSQ"; //default to band seq. value = GetKeyword( osPrefix+"IMAGE.AXIS_NAME", "" ); if (EQUAL(value,"(SAMPLE,LINE,BAND)") ) { strcpy(szLayout,"BSQ"); nCols = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",1)); nRows = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",2)); nBands = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",3)); } else if (EQUAL(value,"(BAND,LINE,SAMPLE)") ) { strcpy(szLayout,"BIP"); nBands = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",1)); nRows = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",2)); nCols = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",3)); } else if (EQUAL(value,"(SAMPLE,BAND,LINE)") ) { strcpy(szLayout,"BIL"); nCols = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",1)); nBands = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",2)); nRows = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",3)); } else if ( EQUAL(value,"") ) { strcpy(szLayout,"BSQ"); nCols = atoi(GetKeyword(osPrefix+"IMAGE.LINE_SAMPLES","")); nRows = atoi(GetKeyword(osPrefix+"IMAGE.LINES","")); nBands = atoi(GetKeyword(osPrefix+"IMAGE.BANDS","1")); } else { CPLError( CE_Failure, CPLE_OpenFailed, "%s layout not supported. Abort\n\n", value); return FALSE; } /*********** Grab Qube record bytes **********/ record_bytes = atoi(GetKeyword(osPrefix+"IMAGE.RECORD_BYTES")); if (record_bytes == 0) record_bytes = atoi(GetKeyword(osPrefix+"RECORD_BYTES")); // this can happen with "record_type = undefined". if( record_bytes == 0 ) record_bytes = 1; if( nQube >0 && osQube.find("<BYTES>") != CPLString::npos ) nSkipBytes = nQube - 1; else if (nQube > 0 ) nSkipBytes = (nQube - 1) * record_bytes; else if( nDetachedOffset > 0 ) { if (bDetachedOffsetInBytes) nSkipBytes = nDetachedOffset; else nSkipBytes = nDetachedOffset * record_bytes; } else nSkipBytes = 0; nSkipBytes += atoi(GetKeyword(osPrefix+"IMAGE.LINE_PREFIX_BYTES","")); /*********** Grab SAMPLE_TYPE *****************/ /** if keyword not found leave as "M" or "MSB" **/ CPLString osST = GetKeyword( osPrefix+"IMAGE.SAMPLE_TYPE" ); if( osST.size() >= 2 && osST[0] == '"' && osST[osST.size()-1] == '"' ) osST = osST.substr( 1, osST.size() - 2 ); if( (EQUAL(osST,"LSB_INTEGER")) || (EQUAL(osST,"LSB")) || // just incase (EQUAL(osST,"LSB_UNSIGNED_INTEGER")) || (EQUAL(osST,"LSB_SIGNED_INTEGER")) || (EQUAL(osST,"UNSIGNED_INTEGER")) || (EQUAL(osST,"VAX_REAL")) || (EQUAL(osST,"VAX_INTEGER")) || (EQUAL(osST,"PC_INTEGER")) || //just incase (EQUAL(osST,"PC_REAL")) ) { chByteOrder = 'I'; } /**** Grab format type - pds supports 1,2,4,8,16,32,64 (in theory) **/ /**** I have only seen 8, 16, 32 (float) in released datasets **/ itype = atoi(GetKeyword(osPrefix+"IMAGE.SAMPLE_BITS","")); switch(itype) { case 8 : eDataType = GDT_Byte; dfNoData = NULL1; break; case 16 : if( strstr(osST,"UNSIGNED") != NULL ) eDataType = GDT_UInt16; else eDataType = GDT_Int16; dfNoData = NULL2; break; case 32 : eDataType = GDT_Float32; dfNoData = NULL3; break; case 64 : eDataType = GDT_Float64; dfNoData = NULL3; break; default : CPLError( CE_Failure, CPLE_AppDefined, "Sample_bits of %d is not supported in this gdal PDS reader.", itype); return FALSE; } /* -------------------------------------------------------------------- */ /* Is there a specific nodata value in the file? Either the */ /* MISSING or MISSING_CONSTANT keywords are nodata. */ /* -------------------------------------------------------------------- */ if( GetKeyword( osPrefix+"IMAGE.MISSING", NULL ) != NULL ) dfNoData = CPLAtofM( GetKeyword( osPrefix+"IMAGE.MISSING", "" ) ); if( GetKeyword( osPrefix+"IMAGE.MISSING_CONSTANT", NULL ) != NULL ) dfNoData = CPLAtofM( GetKeyword( osPrefix+"IMAGE.MISSING_CONSTANT","")); /* -------------------------------------------------------------------- */ /* Did we get the required keywords? If not we return with */ /* this never having been considered to be a match. This isn't */ /* an error! */ /* -------------------------------------------------------------------- */ if( nRows < 1 || nCols < 1 || nBands < 1 ) { CPLError( CE_Failure, CPLE_AppDefined, "File %s appears to be a PDS file, but failed to find some required keywords.", GetDescription() ); return FALSE; } /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ nRasterXSize = nCols; nRasterYSize = nRows; /* -------------------------------------------------------------------- */ /* Open target binary file. */ /* -------------------------------------------------------------------- */ if( eAccess == GA_ReadOnly ) { fpImage = VSIFOpenL( osTargetFile, "rb" ); if( fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open %s.\n%s", osTargetFile.c_str(), VSIStrerror( errno ) ); return FALSE; } } else { fpImage = VSIFOpenL( osTargetFile, "r+b" ); if( fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open %s with write permission.\n%s", osTargetFile.c_str(), VSIStrerror( errno ) ); return FALSE; } } /* -------------------------------------------------------------------- */ /* Compute the line offset. */ /* -------------------------------------------------------------------- */ int nItemSize = GDALGetDataTypeSize(eDataType)/8; int nLineOffset = record_bytes; int nPixelOffset, nBandOffset; if( EQUAL(szLayout,"BIP") ) { nPixelOffset = nItemSize * nBands; nBandOffset = nItemSize; nLineOffset = ((nPixelOffset * nCols + record_bytes - 1)/record_bytes) * record_bytes; } else if( EQUAL(szLayout,"BSQ") ) { nPixelOffset = nItemSize; nLineOffset = ((nPixelOffset * nCols + record_bytes - 1)/record_bytes) * record_bytes; nBandOffset = nLineOffset * nRows; } else /* assume BIL */ { nPixelOffset = nItemSize; nBandOffset = nItemSize * nCols; nLineOffset = ((nBandOffset * nCols + record_bytes - 1)/record_bytes) * record_bytes; } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ int i; for( i = 0; i < nBands; i++ ) { RawRasterBand *poBand; poBand = new RawRasterBand( this, i+1, fpImage, nSkipBytes + nBandOffset * i, nPixelOffset, nLineOffset, eDataType, #ifdef CPL_LSB chByteOrder == 'I' || chByteOrder == 'L', #else chByteOrder == 'M', #endif TRUE ); if( nBands == 1 ) { const char* pszMin = GetKeyword(osPrefix+"IMAGE.MINIMUM", NULL); const char* pszMax = GetKeyword(osPrefix+"IMAGE.MAXIMUM", NULL); const char* pszMean = GetKeyword(osPrefix+"IMAGE.MEAN", NULL); const char* pszStdDev= GetKeyword(osPrefix+"IMAGE.STANDARD_DEVIATION", NULL); if (pszMin != NULL && pszMax != NULL && pszMean != NULL && pszStdDev != NULL) { poBand->SetStatistics( CPLAtofM(pszMin), CPLAtofM(pszMax), CPLAtofM(pszMean), CPLAtofM(pszStdDev)); } } poBand->SetNoDataValue( dfNoData ); SetBand( i+1, poBand ); // Set offset/scale values at the PAM level. poBand->SetOffset( CPLAtofM(GetKeyword(osPrefix+"IMAGE.OFFSET","0.0"))); poBand->SetScale( CPLAtofM(GetKeyword(osPrefix+"IMAGE.SCALING_FACTOR","1.0"))); } return TRUE; }
GDALDataset *ISIS2Dataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Does this look like a CUBE or an IMAGE Primary Data Object? */ /* -------------------------------------------------------------------- */ if( !Identify( poOpenInfo ) ) return NULL; /* -------------------------------------------------------------------- */ /* Open the file using the large file API. */ /* -------------------------------------------------------------------- */ VSILFILE *fpQube = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); if( fpQube == NULL ) return NULL; ISIS2Dataset *poDS; poDS = new ISIS2Dataset(); if( ! poDS->oKeywords.Ingest( fpQube, 0 ) ) { VSIFCloseL( fpQube ); delete poDS; return NULL; } VSIFCloseL( fpQube ); /* -------------------------------------------------------------------- */ /* We assume the user is pointing to the label (ie. .lab) file. */ /* -------------------------------------------------------------------- */ // QUBE can be inline or detached and point to an image name // ^QUBE = 76 // ^QUBE = ("ui31s015.img",6441<BYTES>) - has another label on the image // ^QUBE = "ui31s015.img" - which implies no label or skip value const char *pszQube = poDS->GetKeyword( "^QUBE" ); GUIntBig nQube = 0; int bByteLocation = FALSE; CPLString osTargetFile = poOpenInfo->pszFilename; if( pszQube[0] == '"' ) { CPLString osTPath = CPLGetPath(poOpenInfo->pszFilename); CPLString osFilename = pszQube; poDS->CleanString( osFilename ); osTargetFile = CPLFormCIFilename( osTPath, osFilename, NULL ); poDS->osExternalCube = osTargetFile; } else if( pszQube[0] == '(' ) { CPLString osTPath = CPLGetPath(poOpenInfo->pszFilename); CPLString osFilename = poDS->GetKeywordSub("^QUBE",1,""); poDS->CleanString( osFilename ); osTargetFile = CPLFormCIFilename( osTPath, osFilename, NULL ); poDS->osExternalCube = osTargetFile; nQube = atoi(poDS->GetKeywordSub("^QUBE",2,"1")); if( strstr(poDS->GetKeywordSub("^QUBE",2,"1"),"<BYTES>") != NULL ) bByteLocation = true; } else { nQube = atoi(pszQube); if( strstr(pszQube,"<BYTES>") != NULL ) bByteLocation = true; } /* -------------------------------------------------------------------- */ /* Check if file an ISIS2 header file? Read a few lines of text */ /* searching for something starting with nrows or ncols. */ /* -------------------------------------------------------------------- */ GDALDataType eDataType = GDT_Byte; OGRSpatialReference oSRS; //image parameters int nRows, nCols, nBands = 1; GUIntBig nSkipBytes = 0; int itype; int s_ix, s_iy, s_iz; // check SUFFIX_ITEMS params. int record_bytes; int bNoDataSet = FALSE; char chByteOrder = 'M'; //default to MSB //Georef parameters double dfULXMap=0.5; double dfULYMap = 0.5; double dfXDim = 1.0; double dfYDim = 1.0; double dfNoData = 0.0; double xulcenter = 0.0; double yulcenter = 0.0; //projection parameters int bProjectionSet = TRUE; double semi_major = 0.0; double semi_minor = 0.0; double iflattening = 0.0; double center_lat = 0.0; double center_lon = 0.0; double first_std_parallel = 0.0; double second_std_parallel = 0.0; VSILFILE *fp; /* -------------------------------------------------------------------- */ /* Checks to see if this is valid ISIS2 cube */ /* SUFFIX_ITEM tag in .cub file should be (0,0,0); no side-planes */ /* -------------------------------------------------------------------- */ s_ix = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 1 )); s_iy = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 2 )); s_iz = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 3 )); if( s_ix != 0 || s_iy != 0 || s_iz != 0 ) { CPLError( CE_Failure, CPLE_OpenFailed, "*** ISIS 2 cube file has invalid SUFFIX_ITEMS parameters:\n" "*** gdal isis2 driver requires (0, 0, 0), thus no sideplanes or backplanes\n" "found: (%i, %i, %i)\n\n", s_ix, s_iy, s_iz ); delete poDS; return NULL; } /**************** end SUFFIX_ITEM check ***********************/ /*********** Grab layout type (BSQ, BIP, BIL) ************/ // AXIS_NAME = (SAMPLE,LINE,BAND) /***********************************************************/ const char *value; char szLayout[10] = "BSQ"; //default to band seq. value = poDS->GetKeyword( "QUBE.AXIS_NAME", "" ); if (EQUAL(value,"(SAMPLE,LINE,BAND)") ) strcpy(szLayout,"BSQ"); else if (EQUAL(value,"(BAND,LINE,SAMPLE)") ) strcpy(szLayout,"BIP"); else if (EQUAL(value,"(SAMPLE,BAND,LINE)") || EQUAL(value,"") ) strcpy(szLayout,"BSQ"); else { CPLError( CE_Failure, CPLE_OpenFailed, "%s layout not supported. Abort\n\n", value); delete poDS; return NULL; } /*********** Grab samples lines band ************/ nCols = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",1)); nRows = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",2)); nBands = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",3)); /*********** Grab Qube record bytes **********/ record_bytes = atoi(poDS->GetKeyword("RECORD_BYTES")); if (nQube > 0 && bByteLocation ) nSkipBytes = (nQube - 1); else if( nQube > 0 ) nSkipBytes = (nQube - 1) * record_bytes; else nSkipBytes = 0; /*********** Grab samples lines band ************/ CPLString osCoreItemType = poDS->GetKeyword( "QUBE.CORE_ITEM_TYPE" ); if( (EQUAL(osCoreItemType,"PC_INTEGER")) || (EQUAL(osCoreItemType,"PC_UNSIGNED_INTEGER")) || (EQUAL(osCoreItemType,"PC_REAL")) ) { chByteOrder = 'I'; } /******** Grab format type - isis2 only supports 8,16,32 *******/ itype = atoi(poDS->GetKeyword("QUBE.CORE_ITEM_BYTES","")); switch(itype) { case 1 : eDataType = GDT_Byte; dfNoData = NULL1; bNoDataSet = TRUE; break; case 2 : if( strstr(osCoreItemType,"UNSIGNED") != NULL ) { dfNoData = 0; eDataType = GDT_UInt16; } else { dfNoData = NULL2; eDataType = GDT_Int16; } bNoDataSet = TRUE; break; case 4 : eDataType = GDT_Float32; dfNoData = NULL3; bNoDataSet = TRUE; break; case 8 : eDataType = GDT_Float64; dfNoData = NULL3; bNoDataSet = TRUE; break; default : CPLError( CE_Failure, CPLE_AppDefined, "Itype of %d is not supported in ISIS 2.", itype); delete poDS; return NULL; } /*********** Grab Cellsize ************/ value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.MAP_SCALE"); if (strlen(value) > 0 ) { dfXDim = (float) atof(value) * 1000.0; /* convert from km to m */ dfYDim = (float) atof(value) * 1000.0 * -1; } /*********** Grab LINE_PROJECTION_OFFSET ************/ value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.LINE_PROJECTION_OFFSET"); if (strlen(value) > 0) { yulcenter = (float) atof(value); yulcenter = ((yulcenter) * dfYDim); dfULYMap = yulcenter - (dfYDim/2); } /*********** Grab SAMPLE_PROJECTION_OFFSET ************/ value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.SAMPLE_PROJECTION_OFFSET"); if( strlen(value) > 0 ) { xulcenter = (float) atof(value); xulcenter = ((xulcenter) * dfXDim); dfULXMap = xulcenter - (dfXDim/2); } /*********** Grab TARGET_NAME ************/ /**** This is the planets name i.e. MARS ***/ CPLString target_name = poDS->GetKeyword("QUBE.TARGET_NAME"); /*********** Grab MAP_PROJECTION_TYPE ************/ CPLString map_proj_name = poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.MAP_PROJECTION_TYPE"); poDS->CleanString( map_proj_name ); /*********** Grab SEMI-MAJOR ************/ semi_major = atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.A_AXIS_RADIUS")) * 1000.0; /*********** Grab semi-minor ************/ semi_minor = atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.C_AXIS_RADIUS")) * 1000.0; /*********** Grab CENTER_LAT ************/ center_lat = atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.CENTER_LATITUDE")); /*********** Grab CENTER_LON ************/ center_lon = atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.CENTER_LONGITUDE")); /*********** Grab 1st std parallel ************/ first_std_parallel = atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.FIRST_STANDARD_PARALLEL")); /*********** Grab 2nd std parallel ************/ second_std_parallel = atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.SECOND_STANDARD_PARALLEL")); /*** grab PROJECTION_LATITUDE_TYPE = "PLANETOCENTRIC" ****/ // Need to further study how ocentric/ographic will effect the gdal library. // So far we will use this fact to define a sphere or ellipse for some projections // Frank - may need to talk this over char bIsGeographic = TRUE; value = poDS->GetKeyword("CUBE.IMAGE_MAP_PROJECTION.PROJECTION_LATITUDE_TYPE"); if (EQUAL( value, "\"PLANETOCENTRIC\"" )) bIsGeographic = FALSE; CPLDebug("ISIS2","using projection %s", map_proj_name.c_str() ); //Set oSRS projection and parameters if ((EQUAL( map_proj_name, "EQUIRECTANGULAR_CYLINDRICAL" )) || (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) || (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) ) { oSRS.OGRSpatialReference::SetEquirectangular2 ( 0.0, center_lon, center_lat, 0, 0 ); } else if (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) { oSRS.OGRSpatialReference::SetOrthographic ( center_lat, center_lon, 0, 0 ); } else if ((EQUAL( map_proj_name, "SINUSOIDAL" )) || (EQUAL( map_proj_name, "SINUSOIDAL_EQUAL-AREA" ))) { oSRS.OGRSpatialReference::SetSinusoidal ( center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "MERCATOR" )) { oSRS.OGRSpatialReference::SetMercator ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" )) { oSRS.OGRSpatialReference::SetPS ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "TRANSVERSE_MERCATOR" )) { oSRS.OGRSpatialReference::SetTM ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "LAMBERT_CONFORMAL_CONIC" )) { oSRS.OGRSpatialReference::SetLCC ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "") ) { /* no projection */ bProjectionSet = FALSE; } else { CPLDebug( "ISIS2", "Dataset projection %s is not supported. Continuing...", map_proj_name.c_str() ); bProjectionSet = FALSE; } if (bProjectionSet) { //Create projection name, i.e. MERCATOR MARS and set as ProjCS keyword CPLString proj_target_name = map_proj_name + " " + target_name; oSRS.SetProjCS(proj_target_name); //set ProjCS keyword //The geographic/geocentric name will be the same basic name as the body name //'GCS' = Geographic/Geocentric Coordinate System CPLString geog_name = "GCS_" + target_name; //The datum and sphere names will be the same basic name aas the planet CPLString datum_name = "D_" + target_name; CPLString sphere_name = target_name; // + "_IAU_IAG"); //Might not be IAU defined so don't add //calculate inverse flattening from major and minor axis: 1/f = a/(a-b) if ((semi_major - semi_minor) < 0.0000001) iflattening = 0; else iflattening = semi_major / (semi_major - semi_minor); //Set the body size but take into consideration which proj is being used to help w/ proj4 compatibility //The use of a Sphere, polar radius or ellipse here is based on how ISIS does it internally if ( ( (EQUAL( map_proj_name, "STEREOGRAPHIC" ) && (fabs(center_lat) == 90)) ) || (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" ))) { if (bIsGeographic) { //Geograpraphic, so set an ellipse oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, iflattening, "Reference_Meridian", 0.0 ); } else { //Geocentric, so force a sphere using the semi-minor axis. I hope... sphere_name += "_polarRadius"; oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_minor, 0.0, "Reference_Meridian", 0.0 ); } } else if ( (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) || (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) || (EQUAL( map_proj_name, "STEREOGRAPHIC" )) || (EQUAL( map_proj_name, "SINUSOIDAL_EQUAL-AREA" )) || (EQUAL( map_proj_name, "SINUSOIDAL" )) ) { //isis uses the sphereical equation for these projections so force a sphere oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } else if ((EQUAL( map_proj_name, "EQUIRECTANGULAR_CYLINDRICAL" )) || (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) ) { //Calculate localRadius using ISIS3 simple elliptical method // not the more standard Radius of Curvature method //PI = 4 * atan(1); double radLat, localRadius; if (center_lon == 0) { //No need to calculate local radius oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } else { radLat = center_lat * PI / 180; // in radians localRadius = semi_major * semi_minor / sqrt(pow(semi_minor*cos(radLat),2) + pow(semi_major*sin(radLat),2) ); sphere_name += "_localRadius"; oSRS.SetGeogCS( geog_name, datum_name, sphere_name, localRadius, 0.0, "Reference_Meridian", 0.0 ); CPLDebug( "ISIS2", "local radius: %f", localRadius); } } else { //All other projections: Mercator, Transverse Mercator, Lambert Conformal, etc. //Geographic, so set an ellipse if (bIsGeographic) { oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, iflattening, "Reference_Meridian", 0.0 ); } else { //Geocentric, so force a sphere. I hope... oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } } // translate back into a projection string. char *pszResult = NULL; oSRS.exportToWkt( &pszResult ); poDS->osProjection = pszResult; CPLFree( pszResult ); } /* END ISIS2 Label Read */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* -------------------------------------------------------------------- */ /* Did we get the required keywords? If not we return with */ /* this never having been considered to be a match. This isn't */ /* an error! */ /* -------------------------------------------------------------------- */ if( nRows < 1 || nCols < 1 || nBands < 1 ) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ poDS->nRasterXSize = nCols; poDS->nRasterYSize = nRows; /* -------------------------------------------------------------------- */ /* Open target binary file. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_ReadOnly ) poDS->fpImage = VSIFOpenL( osTargetFile, "rb" ); else poDS->fpImage = VSIFOpenL( osTargetFile, "r+b" ); if( poDS->fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open %s with write permission.\n%s", osTargetFile.c_str(), VSIStrerror( errno ) ); delete poDS; return NULL; } poDS->eAccess = poOpenInfo->eAccess; /* -------------------------------------------------------------------- */ /* Compute the line offset. */ /* -------------------------------------------------------------------- */ int nItemSize = GDALGetDataTypeSize(eDataType)/8; int nLineOffset, nPixelOffset, nBandOffset; if( EQUAL(szLayout,"BIP") ) { nPixelOffset = nItemSize * nBands; nLineOffset = nPixelOffset * nCols; nBandOffset = nItemSize; } else if( EQUAL(szLayout,"BSQ") ) { nPixelOffset = nItemSize; nLineOffset = nPixelOffset * nCols; nBandOffset = nLineOffset * nRows; } else /* assume BIL */ { nPixelOffset = nItemSize; nLineOffset = nItemSize * nBands * nCols; nBandOffset = nItemSize * nCols; } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ int i; poDS->nBands = nBands;; for( i = 0; i < poDS->nBands; i++ ) { RawRasterBand *poBand; poBand = new RawRasterBand( poDS, i+1, poDS->fpImage, nSkipBytes + nBandOffset * i, nPixelOffset, nLineOffset, eDataType, #ifdef CPL_LSB chByteOrder == 'I' || chByteOrder == 'L', #else chByteOrder == 'M', #endif TRUE ); if( bNoDataSet ) poBand->SetNoDataValue( dfNoData ); poDS->SetBand( i+1, poBand ); // Set offset/scale values at the PAM level. poBand->SetOffset( CPLAtofM(poDS->GetKeyword("QUBE.CORE_BASE","0.0"))); poBand->SetScale( CPLAtofM(poDS->GetKeyword("QUBE.CORE_MULTIPLIER","1.0"))); } /* -------------------------------------------------------------------- */ /* Check for a .prj file. For isis2 I would like to keep this in */ /* -------------------------------------------------------------------- */ CPLString osPath, osName; osPath = CPLGetPath( poOpenInfo->pszFilename ); osName = CPLGetBasename(poOpenInfo->pszFilename); const char *pszPrjFile = CPLFormCIFilename( osPath, osName, "prj" ); fp = VSIFOpenL( pszPrjFile, "r" ); if( fp != NULL ) { char **papszLines; OGRSpatialReference oSRS; VSIFCloseL( fp ); papszLines = CSLLoad( pszPrjFile ); if( oSRS.importFromESRI( papszLines ) == OGRERR_NONE ) { char *pszResult = NULL; oSRS.exportToWkt( &pszResult ); poDS->osProjection = pszResult; CPLFree( pszResult ); } CSLDestroy( papszLines ); } if( dfULYMap != 0.5 || dfULYMap != 0.5 || dfXDim != 1.0 || dfYDim != 1.0 ) { poDS->bGotTransform = TRUE; poDS->adfGeoTransform[0] = dfULXMap; poDS->adfGeoTransform[1] = dfXDim; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = dfULYMap; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = dfYDim; } if( !poDS->bGotTransform ) poDS->bGotTransform = GDALReadWorldFile( poOpenInfo->pszFilename, "cbw", poDS->adfGeoTransform ); if( !poDS->bGotTransform ) poDS->bGotTransform = GDALReadWorldFile( poOpenInfo->pszFilename, "wld", poDS->adfGeoTransform ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }