EIRDataset::~EIRDataset() { FlushCache(); if( nBands > 0 && GetAccess() == GA_Update ) { int bNoDataSet; double dfNoData; RawRasterBand *poBand = (RawRasterBand *) GetRasterBand( 1 ); dfNoData = poBand->GetNoDataValue(&bNoDataSet); if( bNoDataSet ) { ResetKeyValue( "NODATA", CPLString().Printf( "%.8g", dfNoData ) ); } } if( fpImage != NULL ) VSIFCloseL( fpImage ); CSLDestroy( papszHDR ); CSLDestroy( papszExtraFiles ); }
CPLErr RawDataset::IRasterIO( GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, int nBandCount, int *panBandMap, int nPixelSpace, int nLineSpace, int nBandSpace ) { const char* pszInterleave; /* The default GDALDataset::IRasterIO() implementation would go to */ /* BlockBasedRasterIO if the dataset is interleaved. However if the */ /* access pattern is compatible with DirectIO() we don't want to go */ /* BlockBasedRasterIO, but rather used our optimized path in RawRasterBand::IRasterIO() */ if (nXSize == nBufXSize && nYSize == nBufYSize && nBandCount > 1 && (pszInterleave = GetMetadataItem("INTERLEAVE", "IMAGE_STRUCTURE")) != NULL && EQUAL(pszInterleave, "PIXEL")) { int iBandIndex; for(iBandIndex = 0; iBandIndex < nBandCount; iBandIndex ++ ) { RawRasterBand* poBand = (RawRasterBand*) GetRasterBand(panBandMap[iBandIndex]); if( !poBand->CanUseDirectIO(nXOff, nYOff, nXSize, nYSize, eBufType ) ) { break; } } if( iBandIndex == nBandCount ) { CPLErr eErr = CE_None; for( iBandIndex = 0; iBandIndex < nBandCount && eErr == CE_None; iBandIndex++ ) { GDALRasterBand *poBand = GetRasterBand(panBandMap[iBandIndex]); GByte *pabyBandData; if (poBand == NULL) { eErr = CE_Failure; break; } pabyBandData = ((GByte *) pData) + iBandIndex * nBandSpace; eErr = poBand->RasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, (void *) pabyBandData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace ); } return eErr; } } return GDALDataset::IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nBandCount, panBandMap, nPixelSpace, nLineSpace, nBandSpace ); }
GDALDataset *ARGDataset::CreateCopy( const char *pszFilename, GDALDataset *poSrcDS, int /* bStrict */ , char ** /* papszOptions */ , GDALProgressFunc /* pfnProgress */ , void * /*pProgressData */ ) { const int nBands = poSrcDS->GetRasterCount(); if( nBands != 1 ) { CPLError( CE_Failure, CPLE_NotSupported, "ARG driver doesn't support %d bands. Must be 1 band.", nBands ); return nullptr; } CPLString pszDataType; int nPixelOffset = 0; GDALDataType eType = poSrcDS->GetRasterBand(1)->GetRasterDataType(); if( eType == GDT_Unknown || eType == GDT_CInt16 || eType == GDT_CInt32 || eType == GDT_CFloat32 || eType == GDT_CFloat64 ) { CPLError( CE_Failure, CPLE_NotSupported, "ARG driver doesn't support data type %s.", GDALGetDataTypeName(eType) ); return nullptr; } else if (eType == GDT_Int16) { pszDataType = "int16"; nPixelOffset = 2; } else if (eType == GDT_Int32) { pszDataType = "int32"; nPixelOffset = 4; } else if (eType == GDT_Byte) { pszDataType = "uint8"; nPixelOffset = 1; } else if (eType == GDT_UInt16) { pszDataType = "uint16"; nPixelOffset = 2; } else if (eType == GDT_UInt32) { pszDataType = "uint32"; nPixelOffset = 4; } else if (eType == GDT_Float32) { pszDataType = "float32"; nPixelOffset = 4; } else if (eType == GDT_Float64) { pszDataType = "float64"; nPixelOffset = 8; } double adfTransform[6]; poSrcDS->GetGeoTransform( adfTransform ); const char *pszWKT = poSrcDS->GetProjectionRef(); OGRSpatialReference oSRS; OGRErr nErr = oSRS.importFromWkt(pszWKT); if (nErr != OGRERR_NONE) { CPLError( CE_Failure, CPLE_NotSupported, "Cannot import spatial reference WKT from source dataset."); return nullptr; } int nSrs = 0; if (oSRS.GetAuthorityCode("PROJCS") != nullptr) { nSrs = atoi(oSRS.GetAuthorityCode("PROJCS")); } else if (oSRS.GetAuthorityCode("GEOGCS") != nullptr) { nSrs = atoi(oSRS.GetAuthorityCode("GEOGCS")); } else { // could not determine projected or geographic code // default to EPSG:3857 if no code could be found nSrs = 3857; } /********************************************************************/ /* Create JSON companion file. */ /********************************************************************/ const CPLString osJSONFilename = GetJsonFilename(pszFilename); json_object *poJSONObject = json_object_new_object(); char **pszTokens = poSrcDS->GetMetadata(); const char *pszLayer = CSLFetchNameValue(pszTokens, "LAYER"); if ( pszLayer == nullptr) { // Set the layer json_object_object_add(poJSONObject, "layer", json_object_new_string( CPLGetBasename(osJSONFilename) )); } else { // Set the layer json_object_object_add(poJSONObject, "layer", json_object_new_string( pszLayer )); } // Set the type json_object_object_add(poJSONObject, "type", json_object_new_string("arg")); // Set the datatype json_object_object_add(poJSONObject, "datatype", json_object_new_string(pszDataType)); const int nXSize = poSrcDS->GetRasterXSize(); const int nYSize = poSrcDS->GetRasterYSize(); // Set the number of rows json_object_object_add(poJSONObject, "rows", json_object_new_int(nYSize)); // Set the number of columns json_object_object_add(poJSONObject, "cols", json_object_new_int(nXSize)); // Set the xmin json_object_object_add(poJSONObject, "xmin", json_object_new_double(adfTransform[0])); // Set the ymax json_object_object_add(poJSONObject, "ymax", json_object_new_double(adfTransform[3])); // Set the cellwidth json_object_object_add(poJSONObject, "cellwidth", json_object_new_double(adfTransform[1])); // Set the cellheight json_object_object_add(poJSONObject, "cellheight", json_object_new_double(-adfTransform[5])); // Set the xmax json_object_object_add(poJSONObject, "xmax", json_object_new_double(adfTransform[0] + nXSize * adfTransform[1])); // Set the ymin json_object_object_add(poJSONObject, "ymin", json_object_new_double(adfTransform[3] + nYSize * adfTransform[5])); // Set the xskew json_object_object_add(poJSONObject, "xskew", json_object_new_double(adfTransform[2])); // Set the yskew json_object_object_add(poJSONObject, "yskew", json_object_new_double(adfTransform[4])); if (nSrs > 0) { // Set the epsg json_object_object_add(poJSONObject, "epsg", json_object_new_int(nSrs)); } if (json_object_to_file(const_cast<char *>(osJSONFilename.c_str()), poJSONObject) < 0) { CPLError( CE_Failure, CPLE_NotSupported, "ARG driver can't write companion file."); json_object_put(poJSONObject); poJSONObject = nullptr; return nullptr; } json_object_put(poJSONObject); poJSONObject = nullptr; VSILFILE *fpImage = VSIFOpenL(pszFilename, "wb"); if (fpImage == nullptr) { CPLError( CE_Failure, CPLE_NotSupported, "ARG driver can't create data file %s.", pszFilename); // remove JSON file VSIUnlink( osJSONFilename.c_str() ); return nullptr; } // only 1 raster band GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 ); #ifdef CPL_LSB bool bNative = false; #else bool bNative = true; #endif RawRasterBand *poDstBand = new RawRasterBand( fpImage, 0, nPixelOffset, nPixelOffset * nXSize, eType, bNative, nXSize, nYSize, RawRasterBand::OwnFP::NO); int nXBlockSize, nYBlockSize; poSrcBand->GetBlockSize(&nXBlockSize, &nYBlockSize); void *pabyData = CPLMalloc(nXBlockSize * nPixelOffset); // convert any blocks into scanlines for (int nYBlock = 0; nYBlock * nYBlockSize < nYSize; nYBlock++) { for (int nYScanline = 0; nYScanline < nYBlockSize; nYScanline++) { if ((nYScanline+1) + nYBlock * nYBlockSize > poSrcBand->GetYSize() ) { continue; } for (int nXBlock = 0; nXBlock * nXBlockSize < nXSize; nXBlock++) { int nXValid; if( (nXBlock+1) * nXBlockSize > poSrcBand->GetXSize() ) nXValid = poSrcBand->GetXSize() - nXBlock * nXBlockSize; else nXValid = nXBlockSize; CPLErr eErr = poSrcBand->RasterIO(GF_Read, nXBlock * nXBlockSize, nYBlock * nYBlockSize + nYScanline, nXValid, 1, pabyData, nXBlockSize, 1, eType, 0, 0, nullptr); if (eErr != CE_None) { CPLError(CE_Failure, CPLE_AppDefined, "Error reading."); CPLFree( pabyData ); delete poDstBand; VSIFCloseL( fpImage ); return nullptr; } eErr = poDstBand->RasterIO(GF_Write, nXBlock * nXBlockSize, nYBlock * nYBlockSize + nYScanline, nXValid, 1, pabyData, nXBlockSize, 1, eType, 0, 0, nullptr); if (eErr != CE_None) { CPLError(CE_Failure, CPLE_AppDefined, "Error writing."); CPLFree( pabyData ); delete poDstBand; VSIFCloseL( fpImage ); return nullptr; } } } } CPLFree( pabyData ); delete poDstBand; VSIFCloseL( fpImage ); return reinterpret_cast<GDALDataset *>( GDALOpen( pszFilename, GA_ReadOnly ) ); }
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 ); }
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 *NDFDataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* The user must select the header file (ie. .H1). */ /* -------------------------------------------------------------------- */ if( poOpenInfo->nHeaderBytes < 50 ) return NULL; if( !EQUALN((const char *)poOpenInfo->pabyHeader,"NDF_REVISION=2",14) && !EQUALN((const char *)poOpenInfo->pabyHeader,"NDF_REVISION=0",14) ) return NULL; /* -------------------------------------------------------------------- */ /* Read and process the header into a local name/value */ /* stringlist. We just take off the trailing semicolon. The */ /* keyword is already seperated from the value by an equal */ /* sign. */ /* -------------------------------------------------------------------- */ VSILFILE* fp = VSIFOpenL(poOpenInfo->pszFilename, "rb"); if (fp == NULL) return NULL; const char *pszLine; const int nHeaderMax = 1000; int nHeaderLines = 0; char **papszHeader = (char **) CPLMalloc(sizeof(char *) * (nHeaderMax+1)); while( nHeaderLines < nHeaderMax && (pszLine = CPLReadLineL( fp )) != NULL && !EQUAL(pszLine,"END_OF_HDR;") ) { char *pszFixed; if( strstr(pszLine,"=") == NULL ) break; pszFixed = CPLStrdup( pszLine ); if( pszFixed[strlen(pszFixed)-1] == ';' ) pszFixed[strlen(pszFixed)-1] = '\0'; papszHeader[nHeaderLines++] = pszFixed; papszHeader[nHeaderLines] = NULL; } VSIFCloseL(fp); fp = NULL; if( CSLFetchNameValue( papszHeader, "PIXELS_PER_LINE" ) == NULL || CSLFetchNameValue( papszHeader, "LINES_PER_DATA_FILE" ) == NULL || CSLFetchNameValue( papszHeader, "BITS_PER_PIXEL" ) == NULL || CSLFetchNameValue( papszHeader, "PIXEL_FORMAT" ) == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Dataset appears to be NDF but is missing a required field."); CSLDestroy( papszHeader ); return NULL; } if( !EQUAL(CSLFetchNameValue( papszHeader, "PIXEL_FORMAT"), "BYTE" ) || !EQUAL(CSLFetchNameValue( papszHeader, "BITS_PER_PIXEL"),"8") ) { CPLError( CE_Failure, CPLE_AppDefined, "Currently NDF driver supports only 8bit BYTE format." ); CSLDestroy( papszHeader ); return NULL; } /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CSLDestroy( papszHeader ); CPLError( CE_Failure, CPLE_NotSupported, "The NDF driver does not support update access to existing" " datasets.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ NDFDataset *poDS; poDS = new NDFDataset(); poDS->papszHeader = papszHeader; poDS->nRasterXSize = atoi(poDS->Get("PIXELS_PER_LINE","")); poDS->nRasterYSize = atoi(poDS->Get("LINES_PER_DATA_FILE","")); /* -------------------------------------------------------------------- */ /* Create a raw raster band for each file. */ /* -------------------------------------------------------------------- */ int iBand; const char* pszBand = CSLFetchNameValue(papszHeader, "NUMBER_OF_BANDS_IN_VOLUME"); if (pszBand == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot find band count"); delete poDS; return NULL; } int nBands = atoi(pszBand); if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) || !GDALCheckBandCount(nBands, FALSE)) { delete poDS; return NULL; } for( iBand = 0; iBand < nBands; iBand++ ) { char szKey[100]; CPLString osFilename; sprintf( szKey, "BAND%d_FILENAME", iBand+1 ); osFilename = poDS->Get(szKey,""); // NDF1 file do not include the band filenames. if( osFilename.size() == 0 ) { char szBandExtension[15]; sprintf( szBandExtension, "I%d", iBand+1 ); osFilename = CPLResetExtension( poOpenInfo->pszFilename, szBandExtension ); } else { CPLString osBasePath = CPLGetPath(poOpenInfo->pszFilename); osFilename = CPLFormFilename( osBasePath, osFilename, NULL); } VSILFILE *fpRaw = VSIFOpenL( osFilename, "rb" ); if( fpRaw == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to open band file: %s", osFilename.c_str() ); delete poDS; return NULL; } poDS->papszExtraFiles = CSLAddString( poDS->papszExtraFiles, osFilename ); RawRasterBand *poBand = new RawRasterBand( poDS, iBand+1, fpRaw, 0, 1, poDS->nRasterXSize, GDT_Byte, TRUE, TRUE ); sprintf( szKey, "BAND%d_NAME", iBand+1 ); poBand->SetDescription( poDS->Get(szKey, "") ); sprintf( szKey, "BAND%d_WAVELENGTHS", iBand+1 ); poBand->SetMetadataItem( "WAVELENGTHS", poDS->Get(szKey,"") ); sprintf( szKey, "BAND%d_RADIOMETRIC_GAINS/BIAS", iBand+1 ); poBand->SetMetadataItem( "RADIOMETRIC_GAINS_BIAS", poDS->Get(szKey,"") ); poDS->SetBand( iBand+1, poBand ); } /* -------------------------------------------------------------------- */ /* Fetch and parse USGS projection parameters. */ /* -------------------------------------------------------------------- */ double adfUSGSParms[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; char **papszParmTokens = CSLTokenizeStringComplex( poDS->Get( "USGS_PROJECTION_NUMBER", "" ), ",", FALSE, TRUE ); if( CSLCount( papszParmTokens ) >= 15 ) { int i; for( i = 0; i < 15; i++ ) adfUSGSParms[i] = CPLAtof(papszParmTokens[i]); } CSLDestroy(papszParmTokens); papszParmTokens = NULL; /* -------------------------------------------------------------------- */ /* Minimal georef support ... should add full USGS style */ /* support at some point. */ /* -------------------------------------------------------------------- */ OGRSpatialReference oSRS; int nUSGSProjection = atoi(poDS->Get( "USGS_PROJECTION_NUMBER", "" )); int nZone = atoi(poDS->Get("USGS_MAP_ZONE","0")); oSRS.importFromUSGS( nUSGSProjection, nZone, adfUSGSParms, 12 ); CPLString osDatum = poDS->Get( "HORIZONTAL_DATUM", "" ); if( EQUAL(osDatum,"WGS84") || EQUAL(osDatum,"NAD83") || EQUAL(osDatum,"NAD27") ) { oSRS.SetWellKnownGeogCS( osDatum ); } else if( EQUALN(osDatum,"NAD27",5) ) { oSRS.SetWellKnownGeogCS( "NAD27" ); } else { CPLError( CE_Warning, CPLE_AppDefined, "Unrecognised datum name in NLAPS/NDF file:%s, assuming WGS84.", osDatum.c_str() ); oSRS.SetWellKnownGeogCS( "WGS84" ); } if( oSRS.GetRoot() != NULL ) { CPLFree( poDS->pszProjection ); poDS->pszProjection = NULL; oSRS.exportToWkt( &(poDS->pszProjection) ); } /* -------------------------------------------------------------------- */ /* Get geotransform. */ /* -------------------------------------------------------------------- */ char **papszUL = CSLTokenizeString2( poDS->Get("UPPER_LEFT_CORNER",""), ",", 0 ); char **papszUR = CSLTokenizeString2( poDS->Get("UPPER_RIGHT_CORNER",""), ",", 0 ); char **papszLL = CSLTokenizeString2( poDS->Get("LOWER_LEFT_CORNER",""), ",", 0 ); if( CSLCount(papszUL) == 4 && CSLCount(papszUR) == 4 && CSLCount(papszLL) == 4 ) { poDS->adfGeoTransform[0] = CPLAtof(papszUL[2]); poDS->adfGeoTransform[1] = (CPLAtof(papszUR[2]) - CPLAtof(papszUL[2])) / (poDS->nRasterXSize-1); poDS->adfGeoTransform[2] = (CPLAtof(papszUR[3]) - CPLAtof(papszUL[3])) / (poDS->nRasterXSize-1); poDS->adfGeoTransform[3] = CPLAtof(papszUL[3]); poDS->adfGeoTransform[4] = (CPLAtof(papszLL[2]) - CPLAtof(papszUL[2])) / (poDS->nRasterYSize-1); poDS->adfGeoTransform[5] = (CPLAtof(papszLL[3]) - CPLAtof(papszUL[3])) / (poDS->nRasterYSize-1); // Move origin up-left half a pixel. poDS->adfGeoTransform[0] -= poDS->adfGeoTransform[1] * 0.5; poDS->adfGeoTransform[0] -= poDS->adfGeoTransform[4] * 0.5; poDS->adfGeoTransform[3] -= poDS->adfGeoTransform[2] * 0.5; poDS->adfGeoTransform[3] -= poDS->adfGeoTransform[5] * 0.5; } CSLDestroy( papszUL ); CSLDestroy( papszLL ); CSLDestroy( papszUR ); /* -------------------------------------------------------------------- */ /* 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 ); }
GDALDataset *CTable2Dataset::Open( GDALOpenInfo * poOpenInfo ) { if( !Identify( poOpenInfo ) ) return NULL; /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ CTable2Dataset *poDS = new CTable2Dataset(); poDS->eAccess = poOpenInfo->eAccess; /* -------------------------------------------------------------------- */ /* Open the file. */ /* -------------------------------------------------------------------- */ CPLString osFilename = poOpenInfo->pszFilename; if( poOpenInfo->eAccess == GA_ReadOnly ) poDS->fpImage = VSIFOpenL( osFilename, "rb" ); else poDS->fpImage = VSIFOpenL( osFilename, "rb+" ); if( poDS->fpImage == NULL ) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Read the file header. */ /* -------------------------------------------------------------------- */ CPL_IGNORE_RET_VAL(VSIFSeekL( poDS->fpImage, 0, SEEK_SET )); char achHeader[160] = { '\0' }; CPL_IGNORE_RET_VAL(VSIFReadL( achHeader, 1, 160, poDS->fpImage )); achHeader[16+79] = '\0'; CPLString osDescription = reinterpret_cast<const char *>( achHeader + 16 ); osDescription.Trim(); poDS->SetMetadataItem( "DESCRIPTION", osDescription ); /* -------------------------------------------------------------------- */ /* Convert from LSB to local machine byte order. */ /* -------------------------------------------------------------------- */ CPL_LSBPTR64( achHeader + 96 ); CPL_LSBPTR64( achHeader + 104 ); CPL_LSBPTR64( achHeader + 112 ); CPL_LSBPTR64( achHeader + 120 ); CPL_LSBPTR32( achHeader + 128 ); CPL_LSBPTR32( achHeader + 132 ); /* -------------------------------------------------------------------- */ /* Extract size, and geotransform. */ /* -------------------------------------------------------------------- */ int nRasterXSize, nRasterYSize; memcpy( &nRasterXSize, achHeader + 128, 4 ); memcpy( &nRasterYSize, achHeader + 132, 4 ); if (!GDALCheckDatasetDimensions(nRasterXSize, nRasterYSize)) { delete poDS; return NULL; } poDS->nRasterXSize = nRasterXSize; poDS->nRasterYSize = nRasterYSize; double adfValues[4]; memcpy( adfValues, achHeader + 96, sizeof(double)*4 ); for( int i = 0; i < 4; i++ ) adfValues[i] *= 180/M_PI; // Radians to degrees. poDS->adfGeoTransform[0] = adfValues[0] - adfValues[2]*0.5; poDS->adfGeoTransform[1] = adfValues[2]; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = adfValues[1] + adfValues[3]*(nRasterYSize-0.5); poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = -adfValues[3]; /* -------------------------------------------------------------------- */ /* Setup the bands. */ /* -------------------------------------------------------------------- */ RawRasterBand *poBand = new RawRasterBand( poDS, 1, poDS->fpImage, 160 + 4 + nRasterXSize * (nRasterYSize-1) * 2 * 4, 8, -8 * nRasterXSize, GDT_Float32, CPL_IS_LSB, TRUE, FALSE ); poBand->SetDescription( "Latitude Offset (radians)" ); poDS->SetBand( 1, poBand ); poBand = new RawRasterBand( poDS, 2, poDS->fpImage, 160 + nRasterXSize * (nRasterYSize-1) * 2 * 4, 8, -8 * nRasterXSize, GDT_Float32, CPL_IS_LSB, TRUE, FALSE ); poBand->SetDescription( "Longitude Offset (radians)" ); poDS->SetBand( 2, poBand ); /* -------------------------------------------------------------------- */ /* 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 ); }
GDALDataset *KRODataset::Open( GDALOpenInfo * poOpenInfo ) { if( !Identify( poOpenInfo ) || poOpenInfo->fpL == nullptr ) return nullptr; /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ KRODataset *poDS = new KRODataset(); poDS->eAccess = poOpenInfo->eAccess; poDS->fpImage = poOpenInfo->fpL; poOpenInfo->fpL = nullptr; /* -------------------------------------------------------------------- */ /* Read the file header. */ /* -------------------------------------------------------------------- */ char achHeader[20] = { '\0' }; CPL_IGNORE_RET_VAL(VSIFReadL( achHeader, 1, 20, poDS->fpImage )); int nXSize; memcpy(&nXSize, achHeader + 4, 4); CPL_MSBPTR32( &nXSize ); int nYSize = 0; memcpy(&nYSize, achHeader + 8, 4); CPL_MSBPTR32( &nYSize ); int nDepth = 0; memcpy(&nDepth, achHeader + 12, 4); CPL_MSBPTR32( &nDepth ); int nComp = 0; memcpy(&nComp, achHeader + 16, 4); CPL_MSBPTR32( &nComp ); if( !GDALCheckDatasetDimensions(nXSize, nYSize) || !GDALCheckBandCount(nComp, FALSE) ) { delete poDS; return nullptr; } poDS->nRasterXSize = nXSize; poDS->nRasterYSize = nYSize; GDALDataType eDT = GDT_Unknown; if( nDepth == 8 ) { eDT = GDT_Byte; } else if( nDepth == 16 ) { eDT = GDT_UInt16; } else if( nDepth == 32 ) { eDT = GDT_Float32; } else { CPLError( CE_Failure, CPLE_AppDefined, "Unhandled depth : %d", nDepth ); delete poDS; return nullptr; } const int nDataTypeSize = nDepth / 8; if( nComp == 0 || nDataTypeSize == 0 || poDS->nRasterXSize > INT_MAX / (nComp * nDataTypeSize) ) { CPLError( CE_Failure, CPLE_AppDefined, "Too large width / number of bands" ); delete poDS; return nullptr; } vsi_l_offset nExpectedSize = static_cast<vsi_l_offset>(poDS->nRasterXSize) * poDS->nRasterYSize * nComp * nDataTypeSize + 20; VSIFSeekL(poDS->fpImage, 0, SEEK_END); if( VSIFTellL(poDS->fpImage) < nExpectedSize ) { CPLError( CE_Failure, CPLE_FileIO, "File too short" ); delete poDS; return nullptr; } /* -------------------------------------------------------------------- */ /* Create bands. */ /* -------------------------------------------------------------------- */ CPLErrorReset(); for( int iBand = 0; iBand < nComp; iBand++ ) { RawRasterBand *poBand = new RawRasterBand( poDS, iBand+1, poDS->fpImage, 20 + nDataTypeSize * iBand, nComp * nDataTypeSize, poDS->nRasterXSize * nComp * nDataTypeSize, eDT, !CPL_IS_LSB, RawRasterBand::OwnFP::NO ); if( nComp == 3 || nComp == 4 ) { poBand->SetColorInterpretation( static_cast<GDALColorInterp>(GCI_RedBand + iBand) ); } poDS->SetBand( iBand+1, poBand ); if( CPLGetLastErrorType() != CE_None ) { delete poDS; return nullptr; } } if( nComp > 1 ) poDS->SetMetadataItem( "INTERLEAVE", "PIXEL", "IMAGE_STRUCTURE" ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return poDS; }
GDALDataset *KRODataset::Open( GDALOpenInfo * poOpenInfo ) { if( !Identify( poOpenInfo ) ) return NULL; /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ KRODataset *poDS; poDS = new KRODataset(); 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 file header. */ /* -------------------------------------------------------------------- */ char achHeader[20]; int nXSize, nYSize, nDepth, nComp; VSIFReadL( achHeader, 1, 20, poDS->fpImage ); memcpy(&nXSize, achHeader + 4, 4); CPL_MSBPTR32( &nXSize ); memcpy(&nYSize, achHeader + 8, 4); CPL_MSBPTR32( &nYSize ); memcpy(&nDepth, achHeader + 12, 4); CPL_MSBPTR32( &nDepth ); memcpy(&nComp, achHeader + 16, 4); CPL_MSBPTR32( &nComp ); if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) || !GDALCheckBandCount(nComp, FALSE)) { delete poDS; return NULL; } poDS->nRasterXSize = nXSize; poDS->nRasterYSize = nYSize; GDALDataType eDT; if( nDepth == 8 ) eDT = GDT_Byte; else if( nDepth == 16 ) eDT = GDT_UInt16; else if( nDepth == 32 ) eDT = GDT_Float32; else { CPLError(CE_Failure, CPLE_AppDefined, "Unhandled depth : %d", nDepth); delete poDS; return NULL; } int nDataTypeSize = nDepth / 8; /* -------------------------------------------------------------------- */ /* Create bands. */ /* -------------------------------------------------------------------- */ for( int iBand = 0; iBand < nComp; iBand++ ) { RawRasterBand *poBand = new RawRasterBand( poDS, iBand+1, poDS->fpImage, 20 + nDataTypeSize * iBand, nComp * nDataTypeSize, poDS->nRasterXSize * nComp * nDataTypeSize, eDT, !CPL_IS_LSB, TRUE, FALSE ); if( nComp == 3 || nComp == 4 ) { poBand->SetColorInterpretation( (GDALColorInterp) (GCI_RedBand + iBand) ); } poDS->SetBand( iBand+1, poBand ); } if( nComp > 1 ) poDS->SetMetadataItem( "INTERLEAVE", "PIXEL", "IMAGE_STRUCTURE" ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }