COASPMetadataReader::COASPMetadataReader(char *pszFname) { this->fp = NULL; this->nCurrentItem = 0; this->papszMetadata = CSLLoad(pszFname); this->nMetadataCount = CSLCount(this->papszMetadata); }
CPLErr GNMFileNetwork::LoadNetworkSrs() { const char* pszSrsFileName = CPLFormFilename(m_soNetworkFullName, GNM_SRSFILENAME, NULL); char** papszLines = CSLLoad(pszSrsFileName); if ( NULL == papszLines ) { CPLError( CE_Failure, CPLE_AppDefined, "Loading of '%s' layer failed", GNM_SYSLAYER_META ); return CE_Failure; } m_soSRS = papszLines[0]; CSLDestroy( papszLines ); return CE_None; }
GDALDataset *PAuxDataset::Open( GDALOpenInfo * poOpenInfo ) { if( poOpenInfo->nHeaderBytes < 1 ) return NULL; /* -------------------------------------------------------------------- */ /* If this is an .aux file, fetch out and form the name of the */ /* file it references. */ /* -------------------------------------------------------------------- */ CPLString osTarget = poOpenInfo->pszFilename; if( EQUAL(CPLGetExtension( poOpenInfo->pszFilename ),"aux") && STARTS_WITH_CI((const char *) poOpenInfo->pabyHeader, "AuxilaryTarget: ")) { char szAuxTarget[1024]; const char *pszSrc = reinterpret_cast<const char *>( poOpenInfo->pabyHeader+16 ); int i = 0; for( ; pszSrc[i] != 10 && pszSrc[i] != 13 && pszSrc[i] != '\0' && i < static_cast<int>( sizeof(szAuxTarget) ) - 1; i++ ) { szAuxTarget[i] = pszSrc[i]; } szAuxTarget[i] = '\0'; char *pszPath = CPLStrdup(CPLGetPath(poOpenInfo->pszFilename)); osTarget = CPLFormFilename(pszPath, szAuxTarget, NULL); CPLFree(pszPath); } /* -------------------------------------------------------------------- */ /* Now we need to tear apart the filename to form a .aux */ /* filename. */ /* -------------------------------------------------------------------- */ CPLString osAuxFilename = CPLResetExtension(osTarget,"aux"); /* -------------------------------------------------------------------- */ /* Do we have a .aux file? */ /* -------------------------------------------------------------------- */ char** papszSiblingFiles = poOpenInfo->GetSiblingFiles(); if( papszSiblingFiles != NULL && CSLFindString( papszSiblingFiles, CPLGetFilename(osAuxFilename) ) == -1 ) { return NULL; } VSILFILE *fp = VSIFOpenL( osAuxFilename, "r" ); if( fp == NULL ) { osAuxFilename = CPLResetExtension(osTarget,"AUX"); fp = VSIFOpenL( osAuxFilename, "r" ); } if( fp == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Is this file a PCI .aux file? Check the first line for the */ /* telltale AuxilaryTarget keyword. */ /* */ /* At this point we should be verifying that it refers to our */ /* binary file, but that is a pretty involved test. */ /* -------------------------------------------------------------------- */ const char *pszLine = CPLReadLineL( fp ); CPL_IGNORE_RET_VAL(VSIFCloseL( fp )); if( pszLine == NULL || (!STARTS_WITH_CI(pszLine, "AuxilaryTarget") && !STARTS_WITH_CI(pszLine, "AuxiliaryTarget")) ) { return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ PAuxDataset *poDS = new PAuxDataset(); /* -------------------------------------------------------------------- */ /* Load the .aux file into a string list suitable to be */ /* searched with CSLFetchNameValue(). */ /* -------------------------------------------------------------------- */ poDS->papszAuxLines = CSLLoad( osAuxFilename ); poDS->pszAuxFilename = CPLStrdup(osAuxFilename); /* -------------------------------------------------------------------- */ /* Find the RawDefinition line to establish overall parameters. */ /* -------------------------------------------------------------------- */ pszLine = CSLFetchNameValue(poDS->papszAuxLines, "RawDefinition"); // It seems PCI now writes out .aux files without RawDefinition in // some cases. See bug 947. if( pszLine == NULL ) { delete poDS; return NULL; } char **papszTokens = CSLTokenizeString(pszLine); if( CSLCount(papszTokens) < 3 ) { CPLError( CE_Failure, CPLE_AppDefined, "RawDefinition missing or corrupt in %s.", poOpenInfo->pszFilename ); delete poDS; CSLDestroy( papszTokens ); return NULL; } poDS->nRasterXSize = atoi(papszTokens[0]); poDS->nRasterYSize = atoi(papszTokens[1]); poDS->nBands = atoi(papszTokens[2]); poDS->eAccess = poOpenInfo->eAccess; CSLDestroy( papszTokens ); if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) || !GDALCheckBandCount(poDS->nBands, FALSE)) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Open the file. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { poDS->fpImage = VSIFOpenL( osTarget, "rb+" ); if( poDS->fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "File %s is missing or read-only, check permissions.", osTarget.c_str() ); delete poDS; return NULL; } } else { poDS->fpImage = VSIFOpenL( osTarget, "rb" ); if( poDS->fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "File %s is missing or unreadable.", osTarget.c_str() ); delete poDS; return NULL; } } /* -------------------------------------------------------------------- */ /* Collect raw definitions of each channel and create */ /* corresponding bands. */ /* -------------------------------------------------------------------- */ int iBand = 0; for( int i = 0; i < poDS->nBands; i++ ) { char szDefnName[32]; snprintf( szDefnName, sizeof(szDefnName), "ChanDefinition-%d", i+1 ); pszLine = CSLFetchNameValue(poDS->papszAuxLines, szDefnName); if (pszLine == NULL) { continue; } papszTokens = CSLTokenizeString(pszLine); if( CSLCount(papszTokens) < 4 ) { // Skip the band with broken description CSLDestroy( papszTokens ); continue; } GDALDataType eType; if( EQUAL(papszTokens[0],"16U") ) eType = GDT_UInt16; else if( EQUAL(papszTokens[0],"16S") ) eType = GDT_Int16; else if( EQUAL(papszTokens[0],"32R") ) eType = GDT_Float32; else eType = GDT_Byte; int bNative = TRUE; if( CSLCount(papszTokens) > 4 ) { #ifdef CPL_LSB bNative = EQUAL(papszTokens[4],"Swapped"); #else bNative = EQUAL(papszTokens[4],"Unswapped"); #endif } const vsi_l_offset nBandOffset = CPLScanUIntBig(papszTokens[1], static_cast<int>(strlen(papszTokens[1]))); const int nPixelOffset = atoi(papszTokens[2]); const int nLineOffset = atoi(papszTokens[3]); if (nPixelOffset <= 0 || nLineOffset <= 0) { // Skip the band with broken offsets CSLDestroy( papszTokens ); continue; } poDS->SetBand( iBand+1, new PAuxRasterBand( poDS, iBand+1, poDS->fpImage, nBandOffset, nPixelOffset, nLineOffset, eType, bNative ) ); iBand++; CSLDestroy( papszTokens ); } poDS->nBands = iBand; /* -------------------------------------------------------------------- */ /* Get the projection. */ /* -------------------------------------------------------------------- */ const char *pszMapUnits = CSLFetchNameValue( poDS->papszAuxLines, "MapUnits" ); const char *pszProjParms = CSLFetchNameValue( poDS->papszAuxLines, "ProjParms" ); if( pszMapUnits != NULL ) poDS->pszProjection = poDS->PCI2WKT( pszMapUnits, pszProjParms ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( osTarget ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, osTarget ); poDS->ScanForGCPs(); poDS->bAuxUpdated = FALSE; return( poDS ); }
wxGISSpatialReference wxGxPrjFile::GetSpatialReference(void) { OGRErr err = OGRERR_NONE; if(!m_SpatialReference.IsOk()) { char **papszLines = CSLLoad( m_sPath ); switch(m_eType) { case enumESRIPrjFile: { OGRSpatialReference* pSpaRef = new OGRSpatialReference(); err = pSpaRef->importFromESRI(papszLines); if(err == OGRERR_NONE) m_SpatialReference = wxGISSpatialReference(pSpaRef); else wxDELETE(pSpaRef); } break; case enumSPRfile: case enumQPJfile: { OGRSpatialReference* pSpaRef = new OGRSpatialReference(); err = pSpaRef->importFromWkt(papszLines); if(err == OGRERR_NONE) m_SpatialReference = wxGISSpatialReference(pSpaRef); else wxDELETE(pSpaRef); } break; //case enumSPRfile: // { // char *pszWKT, *pszWKT2; // pszWKT = CPLStrdup(papszLines[0]); // for(int i = 1; papszLines[i] != NULL; ++i ) // { // int npapszLinesSize = CPLStrnlen(papszLines[i], 1000); // int npszWKTSize = CPLStrnlen(pszWKT, 8000); // int nDestSize = npszWKTSize + npapszLinesSize + 1; // pszWKT = (char *)CPLRealloc(pszWKT, npszWKTSize + npapszLinesSize + 1 ); // CPLStrlcat( pszWKT, papszLines[i], nDestSize ); // } // pszWKT2 = pszWKT; // err = m_pOGRSpatialReference->importFromWkt( &pszWKT2 );//.importFromWkt(papszLines); // CPLFree( pszWKT ); // } // break; default: CSLDestroy(papszLines); break; } } //err = m_OGRSpatialReference.importFromProj4("+proj=bonne +a=6371000 +es=0 +lon_0=0 +lat_1=60 +units=m +no_defs"); //0x04e3c368 "+proj=bonne +ellps=sphere +lon_0=0 +lat_1=60 +units=m +no_defs " //0x04e3c368 "+proj=aitoff +lon_0=0 +lat_1=60 +x_0=0 +y_0=0 +a=6371000 +b=6371000 +units=m +no_defs " //if(m_OGRSpatialReference.GetEPSGGeogCS() == -1) // m_OGRSpatialReference.SetWellKnownGeogCS("sphere");//WGS84 // err = m_OGRSpatialReference.Fixup(); //err = m_OGRSpatialReference.Validate(); //m_OGRSpatialReference.set //+over if(err != OGRERR_NONE) { const char* err = CPLGetLastErrorMsg(); wxString sErr = wxString::Format(_("wxGxPrjFile: GDAL error: %s"), wxString(err, wxConvUTF8).c_str()); wxLogError(sErr); } return m_SpatialReference; }
GDALDataset *SAGADataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* We assume the user is pointing to the binary (ie. .sdat) file. */ /* -------------------------------------------------------------------- */ if( !EQUAL(CPLGetExtension( poOpenInfo->pszFilename ), "sdat")) { return NULL; } CPLString osPath = CPLGetPath( poOpenInfo->pszFilename ); CPLString osName = CPLGetBasename( poOpenInfo->pszFilename ); CPLString osHDRFilename; osHDRFilename = CPLFormCIFilename( osPath, osName, ".sgrd" ); VSILFILE *fp; fp = VSIFOpenL( osHDRFilename, "r" ); if( fp == NULL ) { return NULL; } /* -------------------------------------------------------------------- */ /* Is this file a SAGA header file? Read a few lines of text */ /* searching for something starting with nrows or ncols. */ /* -------------------------------------------------------------------- */ const char *pszLine; int nRows = -1, nCols = -1; double dXmin = 0.0, dYmin = 0.0, dCellsize = 0.0, dNoData = 0.0, dZFactor = 0.0; int nLineCount = 0; char szDataFormat[20] = "DOUBLE"; char szByteOrderBig[10] = "FALSE"; char szTopToBottom[10] = "FALSE"; char **papszHDR = NULL; while( (pszLine = CPLReadLineL( fp )) != NULL ) { char **papszTokens; nLineCount++; if( nLineCount > 50 || strlen(pszLine) > 1000 ) break; papszHDR = CSLAddString( papszHDR, pszLine ); papszTokens = CSLTokenizeStringComplex( pszLine, " =", TRUE, FALSE ); if( CSLCount( papszTokens ) < 2 ) { CSLDestroy( papszTokens ); continue; } if( EQUALN(papszTokens[0],"CELLCOUNT_X",strlen("CELLCOUNT_X")) ) nCols = atoi(papszTokens[1]); else if( EQUALN(papszTokens[0],"CELLCOUNT_Y",strlen("CELLCOUNT_Y")) ) nRows = atoi(papszTokens[1]); else if( EQUALN(papszTokens[0],"POSITION_XMIN",strlen("POSITION_XMIN")) ) dXmin = CPLAtofM(papszTokens[1]); else if( EQUALN(papszTokens[0],"POSITION_YMIN",strlen("POSITION_YMIN")) ) dYmin = CPLAtofM(papszTokens[1]); else if( EQUALN(papszTokens[0],"CELLSIZE",strlen("CELLSIZE")) ) dCellsize = CPLAtofM(papszTokens[1]); else if( EQUALN(papszTokens[0],"NODATA_VALUE",strlen("NODATA_VALUE")) ) dNoData = CPLAtofM(papszTokens[1]); else if( EQUALN(papszTokens[0],"DATAFORMAT",strlen("DATAFORMAT")) ) strncpy( szDataFormat, papszTokens[1], sizeof(szDataFormat)-1 ); else if( EQUALN(papszTokens[0],"BYTEORDER_BIG",strlen("BYTEORDER_BIG")) ) strncpy( szByteOrderBig, papszTokens[1], sizeof(szByteOrderBig)-1 ); else if( EQUALN(papszTokens[0],"TOPTOBOTTOM",strlen("TOPTOBOTTOM")) ) strncpy( szTopToBottom, papszTokens[1], sizeof(szTopToBottom)-1 ); else if( EQUALN(papszTokens[0],"Z_FACTOR",strlen("Z_FACTOR")) ) dZFactor = CPLAtofM(papszTokens[1]); CSLDestroy( papszTokens ); } VSIFCloseL( fp ); CSLDestroy( papszHDR ); /* -------------------------------------------------------------------- */ /* 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 ) { return NULL; } if (!GDALCheckDatasetDimensions(nCols, nRows)) { return NULL; } if( EQUALN(szTopToBottom,"TRUE",strlen("TRUE")) ) { CPLError( CE_Failure, CPLE_AppDefined, "Currently the SAGA Binary Grid driver does not support\n" "SAGA grids written TOPTOBOTTOM.\n"); return NULL; } if( dZFactor != 1.0) { CPLError( CE_Warning, CPLE_AppDefined, "Currently the SAGA Binary Grid driver does not support\n" "ZFACTORs other than 1.\n"); } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ SAGADataset *poDS = new SAGADataset(); poDS->eAccess = poOpenInfo->eAccess; if( poOpenInfo->eAccess == GA_ReadOnly ) poDS->fp = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); else poDS->fp = VSIFOpenL( poOpenInfo->pszFilename, "r+b" ); if( poDS->fp == NULL ) { delete poDS; CPLError( CE_Failure, CPLE_OpenFailed, "VSIFOpenL(%s) failed unexpectedly.", poOpenInfo->pszFilename ); return NULL; } poDS->nRasterXSize = nCols; poDS->nRasterYSize = nRows; SAGARasterBand *poBand = new SAGARasterBand( poDS, 1 ); /* -------------------------------------------------------------------- */ /* Figure out the byte order. */ /* -------------------------------------------------------------------- */ if( EQUALN(szByteOrderBig,"TRUE",strlen("TRUE")) ) poBand->m_ByteOrder = 1; else if( EQUALN(szByteOrderBig,"FALSE",strlen("FALSE")) ) poBand->m_ByteOrder = 0; /* -------------------------------------------------------------------- */ /* Figure out the data type. */ /* -------------------------------------------------------------------- */ if( EQUAL(szDataFormat,"BIT") ) { poBand->SetDataType(GDT_Byte); poBand->m_nBits = 8; } else if( EQUAL(szDataFormat,"BYTE_UNSIGNED") ) { poBand->SetDataType(GDT_Byte); poBand->m_nBits = 8; } else if( EQUAL(szDataFormat,"BYTE") ) { poBand->SetDataType(GDT_Byte); poBand->m_nBits = 8; } else if( EQUAL(szDataFormat,"SHORTINT_UNSIGNED") ) { poBand->SetDataType(GDT_UInt16); poBand->m_nBits = 16; } else if( EQUAL(szDataFormat,"SHORTINT") ) { poBand->SetDataType(GDT_Int16); poBand->m_nBits = 16; } else if( EQUAL(szDataFormat,"INTEGER_UNSIGNED") ) { poBand->SetDataType(GDT_UInt32); poBand->m_nBits = 32; } else if( EQUAL(szDataFormat,"INTEGER") ) { poBand->SetDataType(GDT_Int32); poBand->m_nBits = 32; } else if( EQUAL(szDataFormat,"FLOAT") ) { poBand->SetDataType(GDT_Float32); poBand->m_nBits = 32; } else if( EQUAL(szDataFormat,"DOUBLE") ) { poBand->SetDataType(GDT_Float64); poBand->m_nBits = 64; } else { CPLError( CE_Failure, CPLE_NotSupported, "SAGA driver does not support the dataformat %s.", szDataFormat ); delete poBand; delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Save band information */ /* -------------------------------------------------------------------- */ poBand->m_Xmin = dXmin; poBand->m_Ymin = dYmin; poBand->m_NoData = dNoData; poBand->m_Cellsize = dCellsize; poBand->m_Rows = nRows; poBand->m_Cols = nCols; poDS->SetBand( 1, poBand ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for a .prj file. */ /* -------------------------------------------------------------------- */ const char *pszPrjFilename = CPLFormCIFilename( osPath, osName, "prj" ); fp = VSIFOpenL( pszPrjFilename, "r" ); if( fp != NULL ) { char **papszLines; OGRSpatialReference oSRS; VSIFCloseL( fp ); papszLines = CSLLoad( pszPrjFilename ); if( oSRS.importFromESRI( papszLines ) == OGRERR_NONE ) { CPLFree( poDS->pszProjection ); oSRS.exportToWkt( &(poDS->pszProjection) ); } CSLDestroy( papszLines ); } /* -------------------------------------------------------------------- */ /* Check for external overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename, poOpenInfo->papszSiblingFiles ); return poDS; }
int OGRShapeDataSource::OpenFile( const char *pszNewName, int bUpdate, int bTestOpen ) { SHPHandle hSHP; DBFHandle hDBF; const char *pszExtension = CPLGetExtension( pszNewName ); (void) bTestOpen; if( !EQUAL(pszExtension,"shp") && !EQUAL(pszExtension,"shx") && !EQUAL(pszExtension,"dbf") ) return FALSE; /* -------------------------------------------------------------------- */ /* SHPOpen() should include better (CPL based) error reporting, */ /* and we should be trying to distinquish at this point whether */ /* failure is a result of trying to open a non-shapefile, or */ /* whether it was a shapefile and we want to report the error */ /* up. */ /* */ /* Care is taken to suppress the error and only reissue it if */ /* we think it is appropriate. */ /* -------------------------------------------------------------------- */ CPLPushErrorHandler( CPLQuietErrorHandler ); if( bUpdate ) hSHP = SHPOpen( pszNewName, "r+" ); else hSHP = SHPOpen( pszNewName, "r" ); CPLPopErrorHandler(); if( hSHP == NULL && (!EQUAL(CPLGetExtension(pszNewName),"dbf") || strstr(CPLGetLastErrorMsg(),".shp") == NULL) ) { CPLString osMsg = CPLGetLastErrorMsg(); CPLError( CE_Failure, CPLE_OpenFailed, "%s", osMsg.c_str() ); return FALSE; } CPLErrorReset(); /* -------------------------------------------------------------------- */ /* Open the .dbf file, if it exists. To open a dbf file, the */ /* filename has to either refer to a successfully opened shp */ /* file or has to refer to the actual .dbf file. */ /* -------------------------------------------------------------------- */ if( hSHP != NULL || EQUAL(CPLGetExtension(pszNewName),"dbf") ) { if( bUpdate ) hDBF = DBFOpen( pszNewName, "r+" ); else hDBF = DBFOpen( pszNewName, "r" ); } else hDBF = NULL; if( hDBF == NULL && hSHP == NULL ) return FALSE; /* -------------------------------------------------------------------- */ /* Is there an associated .prj file we can read? */ /* -------------------------------------------------------------------- */ OGRSpatialReference *poSRS = NULL; const char *pszPrjFile = CPLResetExtension( pszNewName, "prj" ); FILE *fp = NULL; fp = VSIFOpenL( pszPrjFile, "r" ); #ifndef WIN32 if( NULL == fp ) { pszPrjFile = CPLResetExtension( pszNewName, "PRJ" ); fp = VSIFOpenL( pszPrjFile, "r" ); } #endif if( fp != NULL ) { char **papszLines; VSIFCloseL( fp ); papszLines = CSLLoad( pszPrjFile ); poSRS = new OGRSpatialReference(); if( poSRS->importFromESRI( papszLines ) != OGRERR_NONE ) { delete poSRS; poSRS = NULL; } CSLDestroy( papszLines ); } /* -------------------------------------------------------------------- */ /* Create the layer object. */ /* -------------------------------------------------------------------- */ OGRShapeLayer *poLayer; poLayer = new OGRShapeLayer( pszNewName, hSHP, hDBF, poSRS, bUpdate, wkbNone ); poLayer->InitializeIndexSupport( pszNewName ); /* -------------------------------------------------------------------- */ /* Add layer to data source layer list. */ /* -------------------------------------------------------------------- */ papoLayers = (OGRShapeLayer **) CPLRealloc( papoLayers, sizeof(OGRShapeLayer *) * (nLayers+1) ); papoLayers[nLayers++] = poLayer; return TRUE; }
void PDSDataset::ParseSRS() { const char *pszFilename = GetDescription(); /* ==================================================================== */ /* Get the geotransform. */ /* ==================================================================== */ /*********** Grab Cellsize ************/ //example: //MAP_SCALE = 14.818 <KM/PIXEL> //added search for unit (only checks for CM, KM - defaults to Meters) const char *value; //Georef parameters double dfULXMap=0.5; double dfULYMap = 0.5; double dfXDim = 1.0; double dfYDim = 1.0; double xulcenter = 0.0; double yulcenter = 0.0; value = GetKeyword("IMAGE_MAP_PROJECTION.MAP_SCALE"); if (strlen(value) > 0 ) { dfXDim = atof(value); dfYDim = atof(value) * -1; CPLString unit = GetKeywordUnit("IMAGE_MAP_PROJECTION.MAP_SCALE",2); //KM //value = GetKeywordUnit("IMAGE_MAP_PROJECTION.MAP_SCALE",3); //PIXEL if((EQUAL(unit,"M")) || (EQUAL(unit,"METER")) || (EQUAL(unit,"METERS"))) { // do nothing } else if (EQUAL(unit,"CM")) { // convert from cm to m dfXDim = dfXDim / 100.0; dfYDim = dfYDim / 100.0; } else { //defaults to convert km to m dfXDim = dfXDim * 1000.0; dfYDim = dfYDim * 1000.0; } } /* -------------------------------------------------------------------- */ /* Calculate upper left corner of pixel in meters from the */ /* upper left center pixel sample/line offsets. It doesn't */ /* mean the defaults will work for every PDS image, as these */ /* values are used inconsistantly. Thus we have included */ /* conversion options to allow the user to override the */ /* documented PDS3 default. Jan. 2011, for known mapping issues */ /* see GDAL PDS page or mapping within ISIS3 source (USGS) */ /* $ISIS3DATA/base/translations/pdsProjectionLineSampToXY.def */ /* -------------------------------------------------------------------- */ // defaults should be correct for what is documented in the PDS3 standard double dfSampleOffset_Shift; double dfLineOffset_Shift; double dfSampleOffset_Mult; double dfLineOffset_Mult; dfSampleOffset_Shift = atof(CPLGetConfigOption( "PDS_SampleProjOffset_Shift", "-0.5" )); dfLineOffset_Shift = atof(CPLGetConfigOption( "PDS_LineProjOffset_Shift", "-0.5" )); dfSampleOffset_Mult = atof(CPLGetConfigOption( "PDS_SampleProjOffset_Mult", "-1.0") ); dfLineOffset_Mult = atof( CPLGetConfigOption( "PDS_LineProjOffset_Mult", "1.0") ); /*********** Grab LINE_PROJECTION_OFFSET ************/ value = GetKeyword("IMAGE_MAP_PROJECTION.LINE_PROJECTION_OFFSET"); if (strlen(value) > 0) { yulcenter = atof(value); dfULYMap = ((yulcenter + dfLineOffset_Shift) * -dfYDim * dfLineOffset_Mult); //notice dfYDim is negative here which is why it is again negated here } /*********** Grab SAMPLE_PROJECTION_OFFSET ************/ value = GetKeyword("IMAGE_MAP_PROJECTION.SAMPLE_PROJECTION_OFFSET"); if( strlen(value) > 0 ) { xulcenter = atof(value); dfULXMap = ((xulcenter + dfSampleOffset_Shift) * dfXDim * dfSampleOffset_Mult); } /* ==================================================================== */ /* Get the coordinate system. */ /* ==================================================================== */ 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; OGRSpatialReference oSRS; /*********** Grab TARGET_NAME ************/ /**** This is the planets name i.e. MARS ***/ CPLString target_name = GetKeyword("TARGET_NAME"); CleanString( target_name ); /********** Grab MAP_PROJECTION_TYPE *****/ CPLString map_proj_name = GetKeyword( "IMAGE_MAP_PROJECTION.MAP_PROJECTION_TYPE"); CleanString( map_proj_name ); /****** Grab semi_major & convert to KM ******/ semi_major = atof(GetKeyword( "IMAGE_MAP_PROJECTION.A_AXIS_RADIUS")) * 1000.0; /****** Grab semi-minor & convert to KM ******/ semi_minor = atof(GetKeyword( "IMAGE_MAP_PROJECTION.C_AXIS_RADIUS")) * 1000.0; /*********** Grab CENTER_LAT ************/ center_lat = atof(GetKeyword( "IMAGE_MAP_PROJECTION.CENTER_LATITUDE")); /*********** Grab CENTER_LON ************/ center_lon = atof(GetKeyword( "IMAGE_MAP_PROJECTION.CENTER_LONGITUDE")); /********** Grab 1st std parallel *******/ first_std_parallel = atof(GetKeyword( "IMAGE_MAP_PROJECTION.FIRST_STANDARD_PARALLEL")); /********** Grab 2nd std parallel *******/ second_std_parallel = atof(GetKeyword( "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 = GetKeyword("IMAGE_MAP_PROJECTION.COORDINATE_SYSTEM_NAME"); if (EQUAL( value, "PLANETOCENTRIC" )) bIsGeographic = FALSE; /** Set oSRS projection and parameters --- all PDS supported types added if apparently supported in oSRS "AITOFF", ** Not supported in GDAL?? "ALBERS", "BONNE", "BRIESEMEISTER", ** Not supported in GDAL?? "CYLINDRICAL EQUAL AREA", "EQUIDISTANT", "EQUIRECTANGULAR", "GNOMONIC", "HAMMER", ** Not supported in GDAL?? "HENDU", ** Not supported in GDAL?? "LAMBERT AZIMUTHAL EQUAL AREA", "LAMBERT CONFORMAL", "MERCATOR", "MOLLWEIDE", "OBLIQUE CYLINDRICAL", "ORTHOGRAPHIC", "SIMPLE CYLINDRICAL", "SINUSOIDAL", "STEREOGRAPHIC", "TRANSVERSE MERCATOR", "VAN DER GRINTEN", ** Not supported in GDAL?? "WERNER" ** Not supported in GDAL?? **/ CPLDebug( "PDS","using projection %s\n\n", map_proj_name.c_str()); if ((EQUAL( map_proj_name, "EQUIRECTANGULAR" )) || (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) || (EQUAL( map_proj_name, "EQUIDISTANT" )) ) { oSRS.SetEquirectangular2 ( 0.0, center_lon, center_lat, 0, 0 ); } else if (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) { oSRS.SetOrthographic ( center_lat, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "SINUSOIDAL" )) { oSRS.SetSinusoidal ( center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "MERCATOR" )) { oSRS.SetMercator ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "STEREOGRAPHIC" )) { oSRS.SetStereographic ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC")) { oSRS.SetPS ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "TRANSVERSE_MERCATOR" )) { oSRS.SetTM ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "LAMBERT_CONFORMAL_CONIC" )) { oSRS.SetLCC ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "LAMBERT_AZIMUTHAL_EQUAL_AREA" )) { oSRS.SetLAEA( center_lat, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "CYLINDRICAL_EQUAL_AREA" )) { oSRS.SetCEA ( first_std_parallel, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "MOLLWEIDE" )) { oSRS.SetMollweide ( center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "ALBERS" )) { oSRS.SetACEA ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "BONNE" )) { oSRS.SetBonne ( first_std_parallel, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "GNOMONIC" )) { oSRS.SetGnomonic ( center_lat, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "OBLIQUE_CYLINDRICAL" )) { // hope Swiss Oblique Cylindrical is the same oSRS.SetSOC ( center_lat, center_lon, 0, 0 ); } else { CPLDebug( "PDS", "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/ compatibility //Notice that most PDS projections are spherical based on the fact that ISIS/PICS are spherical //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, "EQUIDISTANT" )) || (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) || (EQUAL( map_proj_name, "STEREOGRAPHIC" )) || (EQUAL( map_proj_name, "SINUSOIDAL" )) ) { //isis uses the spherical 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" )) { //isis uses local radius as a sphere, which is pre-calculated in the PDS label as the semi-major sphere_name += "_localRadius"; oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } 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 ); osProjection = pszResult; CPLFree( pszResult ); } /* ==================================================================== */ /* Check for a .prj and world file to override the georeferencing. */ /* ==================================================================== */ { CPLString osPath, osName; VSILFILE *fp; osPath = CPLGetPath( pszFilename ); osName = CPLGetBasename(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 ); osProjection = pszResult; CPLFree( pszResult ); } CSLDestroy( papszLines ); } } if( dfULYMap != 0.5 || dfULYMap != 0.5 || dfXDim != 1.0 || dfYDim != 1.0 ) { bGotTransform = TRUE; adfGeoTransform[0] = dfULXMap; adfGeoTransform[1] = dfXDim; adfGeoTransform[2] = 0.0; adfGeoTransform[3] = dfULYMap; adfGeoTransform[4] = 0.0; adfGeoTransform[5] = dfYDim; } if( !bGotTransform ) bGotTransform = GDALReadWorldFile( pszFilename, "psw", adfGeoTransform ); if( !bGotTransform ) bGotTransform = GDALReadWorldFile( pszFilename, "wld", adfGeoTransform ); }
COASPMetadataReader::COASPMetadataReader(char *pszFname) : fp(NULL), papszMetadata(NULL), nMetadataCount(0), nCurrentItem(0) { papszMetadata = CSLLoad(pszFname); nMetadataCount = CSLCount(papszMetadata); }
int FindSRS( const char *pszInput, OGRSpatialReference &oSRS, int bDebug ) { int bGotSRS = FALSE; VSILFILE *fp = NULL; GDALDataset *poGDALDS = NULL; OGRDataSource *poOGRDS = NULL; OGRLayer *poLayer = NULL; char *pszProjection = NULL; CPLErrorHandler oErrorHandler = NULL; int bIsFile = FALSE; OGRErr eErr = CE_None; /* temporarily supress error messages we may get from xOpen() */ if ( ! bDebug ) oErrorHandler = CPLSetErrorHandler ( CPLQuietErrorHandler ); /* Test if argument is a file */ fp = VSIFOpenL( pszInput, "r" ); if ( fp ) { bIsFile = TRUE; VSIFCloseL( fp ); CPLDebug( "gdalsrsinfo", "argument is a file" ); } /* try to open with GDAL */ CPLDebug( "gdalsrsinfo", "trying to open with GDAL" ); poGDALDS = (GDALDataset *) GDALOpen( pszInput, GA_ReadOnly ); if ( poGDALDS != NULL && poGDALDS->GetProjectionRef( ) != NULL ) { pszProjection = (char *) poGDALDS->GetProjectionRef( ); if( oSRS.importFromWkt( &pszProjection ) == CE_None ) { CPLDebug( "gdalsrsinfo", "got SRS from GDAL" ); bGotSRS = TRUE; } GDALClose( (GDALDatasetH) poGDALDS ); if ( ! bGotSRS ) CPLDebug( "gdalsrsinfo", "did not open with GDAL" ); } #ifdef OGR_ENABLED /* if unsuccessful, try to open with OGR */ if ( ! bGotSRS ) { CPLDebug( "gdalsrsinfo", "trying to open with OGR" ); poOGRDS = OGRSFDriverRegistrar::Open( pszInput, FALSE, NULL ); if( poOGRDS != NULL ) { poLayer = poOGRDS->GetLayer( 0 ); if ( poLayer != NULL ) { OGRSpatialReference *poSRS = poLayer->GetSpatialRef( ); if ( poSRS != NULL ) { CPLDebug( "gdalsrsinfo", "got SRS from OGR" ); bGotSRS = TRUE; OGRSpatialReference* poSRSClone = poSRS->Clone(); oSRS = *poSRSClone; OGRSpatialReference::DestroySpatialReference( poSRSClone ); } } OGRDataSource::DestroyDataSource( poOGRDS ); poOGRDS = NULL; } if ( ! bGotSRS ) CPLDebug( "gdalsrsinfo", "did not open with OGR" ); } #endif // OGR_ENABLED /* Try ESRI file */ if ( ! bGotSRS && bIsFile && (strstr(pszInput,".prj") != NULL) ) { CPLDebug( "gdalsrsinfo", "trying to get SRS from ESRI .prj file [%s]", pszInput ); char **pszTemp; if ( strstr(pszInput,"ESRI::") != NULL ) pszTemp = CSLLoad( pszInput+6 ); else pszTemp = CSLLoad( pszInput ); if( pszTemp ) { eErr = oSRS.importFromESRI( pszTemp ); CSLDestroy( pszTemp ); } else eErr = OGRERR_UNSUPPORTED_SRS; if( eErr != OGRERR_NONE ) { CPLDebug( "gdalsrsinfo", "did not get SRS from ESRI .prj file" ); } else { CPLDebug( "gdalsrsinfo", "got SRS from ESRI .prj file" ); bGotSRS = TRUE; } } /* Last resort, try OSRSetFromUserInput() */ if ( ! bGotSRS ) { CPLDebug( "gdalsrsinfo", "trying to get SRS from user input [%s]", pszInput ); eErr = oSRS.SetFromUserInput( pszInput ); if( eErr != OGRERR_NONE ) { CPLDebug( "gdalsrsinfo", "did not get SRS from user input" ); } else { CPLDebug( "gdalsrsinfo", "got SRS from user input" ); bGotSRS = TRUE; } } /* restore error messages */ if ( ! bDebug ) CPLSetErrorHandler ( oErrorHandler ); return bGotSRS; }
GDALDataset *LCPDataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Verify that this is a FARSITE LCP file */ /* -------------------------------------------------------------------- */ if( !Identify( poOpenInfo ) ) return NULL; /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The LCP driver does not support update access to existing" " datasets.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ LCPDataset *poDS; VSILFILE *fpImage; fpImage = VSIFOpenL(poOpenInfo->pszFilename, "rb"); if (fpImage == NULL) return NULL; poDS = new LCPDataset(); poDS->fpImage = fpImage; /* -------------------------------------------------------------------- */ /* Read the header and extract some information. */ /* -------------------------------------------------------------------- */ int bHaveCrownFuels, bHaveGroundFuels; int nBands, i; long nWidth = -1, nHeight = -1; int nTemp, nTemp2; char szTemp[32]; char* pszList; VSIFSeekL( poDS->fpImage, 0, SEEK_SET ); if (VSIFReadL( poDS->pachHeader, 1, LCP_HEADER_SIZE, poDS->fpImage ) != LCP_HEADER_SIZE) { CPLError(CE_Failure, CPLE_FileIO, "File too short"); delete poDS; return NULL; } nWidth = CPL_LSBINT32PTR (poDS->pachHeader + 4164); nHeight = CPL_LSBINT32PTR (poDS->pachHeader + 4168); poDS->nRasterXSize = nWidth; poDS->nRasterYSize = nHeight; if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize)) { delete poDS; return NULL; } // crown fuels = canopy height, canopy base height, canopy bulk density // 21 = have them, 20 = don't have them bHaveCrownFuels = ( CPL_LSBINT32PTR (poDS->pachHeader + 0) - 20 ); // ground fuels = duff loading, coarse woody bHaveGroundFuels = ( CPL_LSBINT32PTR (poDS->pachHeader + 4) - 20 ); if( bHaveCrownFuels ) { if( bHaveGroundFuels ) nBands = 10; else nBands = 8; } else { if( bHaveGroundFuels ) nBands = 7; else nBands = 5; } // add dataset-level metadata nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 8); sprintf(szTemp, "%d", nTemp); poDS->SetMetadataItem( "LATITUDE", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 4204); if ( nTemp == 0 ) poDS->SetMetadataItem( "LINEAR_UNIT", "Meters" ); if ( nTemp == 1 ) poDS->SetMetadataItem( "LINEAR_UNIT", "Feet" ); poDS->pachHeader[LCP_HEADER_SIZE-1] = '\0'; poDS->SetMetadataItem( "DESCRIPTION", poDS->pachHeader + 6804 ); /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ int iPixelSize; iPixelSize = nBands * 2; int bNativeOrder; if (nWidth > INT_MAX / iPixelSize) { CPLError( CE_Failure, CPLE_AppDefined, "Int overflow occured"); delete poDS; return NULL; } #ifdef CPL_LSB bNativeOrder = TRUE; #else bNativeOrder = FALSE; #endif pszList = (char*)CPLMalloc(2048); for( int iBand = 1; iBand <= nBands; iBand++ ) { GDALRasterBand *poBand = NULL; poBand = new RawRasterBand( poDS, iBand, poDS->fpImage, LCP_HEADER_SIZE + ((iBand-1)*2), iPixelSize, iPixelSize * nWidth, GDT_Int16, bNativeOrder, TRUE ); poDS->SetBand(iBand, poBand); switch ( iBand ) { case 1: poBand->SetDescription("Elevation"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4224); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ELEVATION_UNIT", szTemp ); if ( nTemp == 0 ) poBand->SetMetadataItem( "ELEVATION_UNIT_NAME", "Meters" ); if ( nTemp == 1 ) poBand->SetMetadataItem( "ELEVATION_UNIT_NAME", "Feet" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 44); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ELEVATION_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 48); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ELEVATION_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 52); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ELEVATION_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 4244 + 255) = '\0'; poBand->SetMetadataItem( "ELEVATION_FILE", poDS->pachHeader + 4244 ); break; case 2: poBand->SetDescription("Slope"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4226); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "SLOPE_UNIT", szTemp ); if ( nTemp == 0 ) poBand->SetMetadataItem( "SLOPE_UNIT_NAME", "Degrees" ); if ( nTemp == 1 ) poBand->SetMetadataItem( "SLOPE_UNIT_NAME", "Percent" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 456); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "SLOPE_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 460); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "SLOPE_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 464); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "SLOPE_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 4500 + 255) = '\0'; poBand->SetMetadataItem( "SLOPE_FILE", poDS->pachHeader + 4500 ); break; case 3: poBand->SetDescription("Aspect"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4228); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ASPECT_UNIT", szTemp ); if ( nTemp == 0 ) poBand->SetMetadataItem( "ASPECT_UNIT_NAME", "Grass categories" ); if ( nTemp == 1 ) poBand->SetMetadataItem( "ASPECT_UNIT_NAME", "Grass degrees" ); if ( nTemp == 2 ) poBand->SetMetadataItem( "ASPECT_UNIT_NAME", "Azimuth degrees" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 868); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ASPECT_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 872); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ASPECT_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 876); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ASPECT_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 4756 + 255) = '\0'; poBand->SetMetadataItem( "ASPECT_FILE", poDS->pachHeader + 4756 ); break; case 4: int nMinFM, nMaxFM; poBand->SetDescription("Fuel models"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4230); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "FUEL_MODEL_OPTION", szTemp ); if ( nTemp == 0 ) poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "no custom models AND no conversion file needed" ); if ( nTemp == 1 ) poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "custom models BUT no conversion file needed" ); if ( nTemp == 2 ) poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "no custom models BUT conversion file needed" ); if ( nTemp == 3 ) poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "custom models AND conversion file needed" ); nMinFM = CPL_LSBINT32PTR (poDS->pachHeader + 1280); sprintf(szTemp, "%d", nMinFM); poBand->SetMetadataItem( "FUEL_MODEL_MIN", szTemp ); nMaxFM = CPL_LSBINT32PTR (poDS->pachHeader + 1284); sprintf(szTemp, "%d", nMaxFM); poBand->SetMetadataItem( "FUEL_MODEL_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1288); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "FUEL_MODEL_NUM_CLASSES", szTemp ); if (nTemp > 0 && nTemp <= 100) { strcpy(pszList, ""); for ( i = 0; i <= nTemp; i++ ) { nTemp2 = CPL_LSBINT32PTR (poDS->pachHeader + (1292+(i*4))) ; if ( nTemp2 >= nMinFM && nTemp2 <= nMaxFM ) { sprintf(szTemp, "%d", nTemp2); strcat(pszList, szTemp); if (i < (nTemp) ) strcat(pszList, ","); } } } poBand->SetMetadataItem( "FUEL_MODEL_VALUES", pszList ); *(poDS->pachHeader + 5012 + 255) = '\0'; poBand->SetMetadataItem( "FUEL_MODEL_FILE", poDS->pachHeader + 5012 ); break; case 5: poBand->SetDescription("Canopy cover"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4232); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_COV_UNIT", szTemp ); if ( nTemp == 0 ) poBand->SetMetadataItem( "CANOPY_COV_UNIT_NAME", "Categories (0-4)" ); if ( nTemp == 1 ) poBand->SetMetadataItem( "CANOPY_COV_UNIT_NAME", "Percent" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1692); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_COV_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1696); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_COV_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1700); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_COV_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 5268 + 255) = '\0'; poBand->SetMetadataItem( "CANOPY_COV_FILE", poDS->pachHeader + 5268 ); break; case 6: if(bHaveCrownFuels) { poBand->SetDescription("Canopy height"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4234); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_HT_UNIT", szTemp ); if ( nTemp == 1 ) poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Meters" ); if ( nTemp == 2 ) poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Feet" ); if ( nTemp == 3 ) poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Meters x 10" ); if ( nTemp == 4 ) poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Feet x 10" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2104); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_HT_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2108); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_HT_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2112); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_HT_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 5524 + 255) = '\0'; poBand->SetMetadataItem( "CANOPY_HT_FILE", poDS->pachHeader + 5524 ); } else { poBand->SetDescription("Duff"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4240); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_UNIT", szTemp ); if ( nTemp == 1 ) poBand->SetMetadataItem( "DUFF_UNIT_NAME", "Mg/ha" ); if ( nTemp == 2 ) poBand->SetMetadataItem( "DUFF_UNIT_NAME", "t/ac" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3340); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3344); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3348); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 6292 + 255) = '\0'; poBand->SetMetadataItem( "DUFF_FILE", poDS->pachHeader + 6292 ); } break; case 7: if(bHaveCrownFuels) { poBand->SetDescription("Canopy base height"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4236); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBH_UNIT", szTemp ); if ( nTemp == 1 ) poBand->SetMetadataItem( "CBH_UNIT_NAME", "Meters" ); if ( nTemp == 2 ) poBand->SetMetadataItem( "CBH_UNIT_NAME", "Feet" ); if ( nTemp == 3 ) poBand->SetMetadataItem( "CBH_UNIT_NAME", "Meters x 10" ); if ( nTemp == 4 ) poBand->SetMetadataItem( "CBH_UNIT_NAME", "Feet x 10" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2516); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBH_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2520); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBH_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2524); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBH_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 5780 + 255) = '\0'; poBand->SetMetadataItem( "CBH_FILE", poDS->pachHeader + 5780 ); } else { poBand->SetDescription("Coarse woody debris"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4242); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_OPTION", szTemp ); //if ( nTemp == 1 ) // poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" ); //if ( nTemp == 2 ) // poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3752); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3756); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3760); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 6548 + 255) = '\0'; poBand->SetMetadataItem( "CWD_FILE", poDS->pachHeader + 6548 ); } break; case 8: poBand->SetDescription("Canopy bulk density"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4238); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBD_UNIT", szTemp ); if ( nTemp == 1 ) poBand->SetMetadataItem( "CBD_UNIT_NAME", "kg/m^3" ); if ( nTemp == 2 ) poBand->SetMetadataItem( "CBD_UNIT_NAME", "lb/ft^3" ); if ( nTemp == 3 ) poBand->SetMetadataItem( "CBD_UNIT_NAME", "kg/m^3 x 100" ); if ( nTemp == 4 ) poBand->SetMetadataItem( "CBD_UNIT_NAME", "lb/ft^3 x 1000" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2928); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBD_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2932); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBD_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2936); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBD_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 6036 + 255) = '\0'; poBand->SetMetadataItem( "CBD_FILE", poDS->pachHeader + 6036 ); break; case 9: poBand->SetDescription("Duff"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4240); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_UNIT", szTemp ); if ( nTemp == 1 ) poBand->SetMetadataItem( "DUFF_UNIT_NAME", "Mg/ha" ); if ( nTemp == 2 ) poBand->SetMetadataItem( "DUFF_UNIT_NAME", "t/ac" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3340); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3344); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3348); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 6292 + 255) = '\0'; poBand->SetMetadataItem( "DUFF_FILE", poDS->pachHeader + 6292 ); break; case 10: poBand->SetDescription("Coarse woody debris"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4242); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_OPTION", szTemp ); //if ( nTemp == 1 ) // poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" ); //if ( nTemp == 2 ) // poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3752); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3756); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3760); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 6548 + 255) = '\0'; poBand->SetMetadataItem( "CWD_FILE", poDS->pachHeader + 6548 ); break; } } /* -------------------------------------------------------------------- */ /* Try to read projection file. */ /* -------------------------------------------------------------------- */ char *pszDirname, *pszBasename; VSIStatBufL sStatBuf; pszDirname = CPLStrdup(CPLGetPath(poOpenInfo->pszFilename)); pszBasename = CPLStrdup(CPLGetBasename(poOpenInfo->pszFilename)); poDS->osPrjFilename = CPLFormFilename( pszDirname, pszBasename, "prj" ); int nRet = VSIStatL( poDS->osPrjFilename, &sStatBuf ); if( nRet != 0 && VSIIsCaseSensitiveFS(poDS->osPrjFilename)) { poDS->osPrjFilename = CPLFormFilename( pszDirname, pszBasename, "PRJ" ); nRet = VSIStatL( poDS->osPrjFilename, &sStatBuf ); } if( nRet == 0 ) { OGRSpatialReference oSRS; char** papszPrj = CSLLoad( poDS->osPrjFilename ); CPLDebug( "LCP", "Loaded SRS from %s", poDS->osPrjFilename.c_str() ); if( oSRS.importFromESRI( papszPrj ) == OGRERR_NONE ) { oSRS.exportToWkt( &(poDS->pszProjection) ); } CSLDestroy(papszPrj); } CPLFree( pszDirname ); CPLFree( pszBasename ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for external overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename, poOpenInfo->papszSiblingFiles ); CPLFree(pszList); return( poDS ); }
GDALDataset *SIGDEMDataset::Open(GDALOpenInfo * poOpenInfo) { VSILFILE* fp = poOpenInfo->fpL; SIGDEMHeader sHeader; if (SIGDEMDataset::Identify(poOpenInfo) != TRUE || fp == nullptr) { return nullptr; } sHeader.Read(poOpenInfo->pabyHeader); if (!GDALCheckDatasetDimensions(sHeader.nCols, sHeader.nRows)) { return nullptr; } OGRSpatialReference oSRS; if (sHeader.nCoordinateSystemId > 0) { if (oSRS.importFromEPSG(sHeader.nCoordinateSystemId) != OGRERR_NONE) { CPLError(CE_Failure, CPLE_NotSupported, "SIGDEM unable to find coordinateSystemId=%d.", sHeader.nCoordinateSystemId); return nullptr; } } else { CPLString osPrjFilename = CPLResetExtension(poOpenInfo->pszFilename, "prj"); VSIStatBufL sStatBuf; int nRet = VSIStatL(osPrjFilename, &sStatBuf); if (nRet != 0 && VSIIsCaseSensitiveFS(osPrjFilename)) { osPrjFilename = CPLResetExtension(poOpenInfo->pszFilename, "PRJ"); nRet = VSIStatL(osPrjFilename, &sStatBuf); } if (nRet == 0) { char** papszPrj = CSLLoad(osPrjFilename); if (oSRS.importFromESRI(papszPrj) != OGRERR_NONE) { CPLError(CE_Failure, CPLE_NotSupported, "SIGDEM unable to read projection from %s.", osPrjFilename.c_str()); CSLDestroy(papszPrj); return nullptr; } CSLDestroy(papszPrj); } else { CPLError(CE_Failure, CPLE_NotSupported, "SIGDEM unable to find projection."); return nullptr; } } if (sHeader.nCols > std::numeric_limits<int>::max() / (CELL_SIZE_MEM)) { CPLError(CE_Failure, CPLE_AppDefined, "Int overflow occurred."); return nullptr; } if( !RAWDatasetCheckMemoryUsage(sHeader.nCols, sHeader.nRows, 1, 4, 4, 4 * sHeader.nCols, 0, 0, poOpenInfo->fpL) ) { return nullptr; } SIGDEMDataset *poDS = new SIGDEMDataset(sHeader); CPLFree(poDS->pszProjection); oSRS.exportToWkt(&(poDS->pszProjection)); poDS->fpImage = poOpenInfo->fpL; poOpenInfo->fpL = nullptr; poDS->eAccess = poOpenInfo->eAccess; poDS->SetDescription(poOpenInfo->pszFilename); poDS->PamInitialize(); poDS->nBands = 1; CPLErrorReset(); SIGDEMRasterBand *poBand = new SIGDEMRasterBand(poDS, poDS->fpImage, sHeader.dfMinZ, sHeader.dfMaxZ); poDS->SetBand(1, poBand); if (CPLGetLastErrorType() != CE_None) { poDS->nBands = 1; delete poDS; return nullptr; } // Initialize any PAM information. poDS->TryLoadXML(); // Check for overviews. poDS->oOvManager.Initialize(poDS, poOpenInfo->pszFilename); return poDS; }
GDALDataset *ISIS3Dataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Does this look like a CUBE dataset? */ /* -------------------------------------------------------------------- */ if( !Identify( poOpenInfo ) ) return NULL; /* -------------------------------------------------------------------- */ /* Open the file using the large file API. */ /* -------------------------------------------------------------------- */ VSILFILE *fpQube = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); if( fpQube == NULL ) return NULL; ISIS3Dataset *poDS; poDS = new ISIS3Dataset(); if( ! poDS->oKeywords.Ingest( fpQube, 0 ) ) { VSIFCloseL( fpQube ); delete poDS; return NULL; } VSIFCloseL( fpQube ); /* -------------------------------------------------------------------- */ /* Assume user is pointing to label (ie .lbl) file for detached option */ /* -------------------------------------------------------------------- */ // Image can be inline or detached and point to an image name // the Format can be Tiled or Raw // Object = Core // StartByte = 65537 // Format = Tile // TileSamples = 128 // TileLines = 128 //OR----- // Object = Core // StartByte = 1 // ^Core = r0200357_detatched.cub // Format = BandSequential //OR----- // Object = Core // StartByte = 1 // ^Core = r0200357_detached_tiled.cub // Format = Tile // TileSamples = 128 // TileLines = 128 /* -------------------------------------------------------------------- */ /* What file contains the actual data? */ /* -------------------------------------------------------------------- */ const char *pszCore = poDS->GetKeyword( "IsisCube.Core.^Core" ); CPLString osQubeFile; if( EQUAL(pszCore,"") ) osQubeFile = poOpenInfo->pszFilename; else { CPLString osPath = CPLGetPath( poOpenInfo->pszFilename ); osQubeFile = CPLFormFilename( osPath, pszCore, NULL ); poDS->osExternalCube = osQubeFile; } /* -------------------------------------------------------------------- */ /* Check if file an ISIS3 header file? Read a few lines of text */ /* searching for something starting with nrows or ncols. */ /* -------------------------------------------------------------------- */ GDALDataType eDataType = GDT_Byte; OGRSpatialReference oSRS; int nRows = -1; int nCols = -1; int nBands = 1; int nSkipBytes = 0; int tileSizeX = 0; int tileSizeY = 0; double dfULXMap=0.5; double dfULYMap = 0.5; double dfXDim = 1.0; double dfYDim = 1.0; double scaleFactor = 1.0; double dfNoData = 0.0; int bNoDataSet = FALSE; char chByteOrder = 'M'; //default to MSB char szLayout[32] = "BandSequential"; //default to band seq. const char *target_name; //planet name //projection parameters const char *map_proj_name; int bProjectionSet = TRUE; char proj_target_name[200]; char geog_name[60]; char datum_name[60]; char sphere_name[60]; char bIsGeographic = TRUE; double semi_major = 0.0; double semi_minor = 0.0; double iflattening = 0.0; float center_lat = 0.0; float center_lon = 0.0; float first_std_parallel = 0.0; float second_std_parallel = 0.0; double radLat, localRadius; VSILFILE *fp; /************* Skipbytes *****************************/ nSkipBytes = atoi(poDS->GetKeyword("IsisCube.Core.StartByte","")) - 1; /******* Grab format type (BandSequential, Tiled) *******/ const char *value; value = poDS->GetKeyword( "IsisCube.Core.Format", "" ); if (EQUAL(value,"Tile") ) { //Todo strcpy(szLayout,"Tiled"); /******* Get Tile Sizes *********/ tileSizeX = atoi(poDS->GetKeyword("IsisCube.Core.TileSamples","")); tileSizeY = atoi(poDS->GetKeyword("IsisCube.Core.TileLines","")); if (tileSizeX <= 0 || tileSizeY <= 0) { CPLError( CE_Failure, CPLE_OpenFailed, "Wrong tile dimensions : %d x %d", tileSizeX, tileSizeY); delete poDS; return NULL; } } else if (EQUAL(value,"BandSequential") ) 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->GetKeyword("IsisCube.Core.Dimensions.Samples","")); nRows = atoi(poDS->GetKeyword("IsisCube.Core.Dimensions.Lines","")); nBands = atoi(poDS->GetKeyword("IsisCube.Core.Dimensions.Bands","")); /****** Grab format type - ISIS3 only supports 8,U16,S16,32 *****/ const char *itype; itype = poDS->GetKeyword( "IsisCube.Core.Pixels.Type" ); if (EQUAL(itype,"UnsignedByte") ) { eDataType = GDT_Byte; dfNoData = NULL1; bNoDataSet = TRUE; } else if (EQUAL(itype,"UnsignedWord") ) { eDataType = GDT_UInt16; dfNoData = NULL1; bNoDataSet = TRUE; } else if (EQUAL(itype,"SignedWord") ) { eDataType = GDT_Int16; dfNoData = NULL2; bNoDataSet = TRUE; } else if (EQUAL(itype,"Real") || EQUAL(value,"") ) { eDataType = GDT_Float32; dfNoData = NULL3; bNoDataSet = TRUE; } else { CPLError( CE_Failure, CPLE_OpenFailed, "%s layout type not supported. Abort\n\n", itype); delete poDS; return NULL; } /*********** Grab samples lines band ************/ value = poDS->GetKeyword( "IsisCube.Core.Pixels.ByteOrder"); if (EQUAL(value,"Lsb")) chByteOrder = 'I'; /*********** Grab Cellsize ************/ value = poDS->GetKeyword("IsisCube.Mapping.PixelResolution"); if (strlen(value) > 0 ) { dfXDim = atof(value); /* values are in meters */ dfYDim = -atof(value); } /*********** Grab UpperLeftCornerY ************/ value = poDS->GetKeyword("IsisCube.Mapping.UpperLeftCornerY"); if (strlen(value) > 0) { dfULYMap = atof(value); } /*********** Grab UpperLeftCornerX ************/ value = poDS->GetKeyword("IsisCube.Mapping.UpperLeftCornerX"); if( strlen(value) > 0 ) { dfULXMap = atof(value); } /*********** Grab TARGET_NAME ************/ /**** This is the planets name i.e. Mars ***/ target_name = poDS->GetKeyword("IsisCube.Mapping.TargetName"); /*********** Grab MAP_PROJECTION_TYPE ************/ map_proj_name = poDS->GetKeyword( "IsisCube.Mapping.ProjectionName"); /*********** Grab SEMI-MAJOR ************/ semi_major = atof(poDS->GetKeyword( "IsisCube.Mapping.EquatorialRadius")); /*********** Grab semi-minor ************/ semi_minor = atof(poDS->GetKeyword( "IsisCube.Mapping.PolarRadius")); /*********** Grab CENTER_LAT ************/ center_lat = atof(poDS->GetKeyword( "IsisCube.Mapping.CenterLatitude")); /*********** Grab CENTER_LON ************/ center_lon = atof(poDS->GetKeyword( "IsisCube.Mapping.CenterLongitude")); /*********** Grab 1st std parallel ************/ first_std_parallel = atof(poDS->GetKeyword( "IsisCube.Mapping.FirstStandardParallel")); /*********** Grab 2nd std parallel ************/ second_std_parallel = atof(poDS->GetKeyword( "IsisCube.Mapping.SecondStandardParallel")); /*********** Grab scaleFactor ************/ scaleFactor = atof(poDS->GetKeyword( "IsisCube.Mapping.scaleFactor")); /*** grab LatitudeType = Planetographic ****/ // 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 value = poDS->GetKeyword("IsisCube.Mapping.LatitudeType"); if (EQUAL( value, "\"Planetocentric\"" )) bIsGeographic = FALSE; //Set oSRS projection and parameters //############################################################ //ISIS3 Projection types // Equirectangular // LambertConformal // Mercator // ObliqueCylindrical //Todo // Orthographic // PolarStereographic // SimpleCylindrical // Sinusoidal // TransverseMercator #ifdef DEBUG CPLDebug( "ISIS3", "using projection %s", map_proj_name); #endif if ((EQUAL( map_proj_name, "Equirectangular" )) || (EQUAL( map_proj_name, "SimpleCylindrical" )) ) { 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" )) { oSRS.OGRSpatialReference::SetSinusoidal ( center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "Mercator" )) { oSRS.OGRSpatialReference::SetMercator ( center_lat, center_lon, scaleFactor, 0, 0 ); } else if (EQUAL( map_proj_name, "PolarStereographic" )) { oSRS.OGRSpatialReference::SetPS ( center_lat, center_lon, scaleFactor, 0, 0 ); } else if (EQUAL( map_proj_name, "TransverseMercator" )) { oSRS.OGRSpatialReference::SetTM ( center_lat, center_lon, scaleFactor, 0, 0 ); } else if (EQUAL( map_proj_name, "LambertConformal" )) { oSRS.OGRSpatialReference::SetLCC ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 ); } else { CPLDebug( "ISIS3", "Dataset projection %s is not supported. Continuing...", map_proj_name ); bProjectionSet = FALSE; } if (bProjectionSet) { //Create projection name, i.e. MERCATOR MARS and set as ProjCS keyword strcpy(proj_target_name, map_proj_name); strcat(proj_target_name, " "); strcat(proj_target_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 strcpy(geog_name, "GCS_"); strcat(geog_name, target_name); //The datum name will be the same basic name as the planet strcpy(datum_name, "D_"); strcat(datum_name, target_name); strcpy(sphere_name, target_name); //strcat(sphere_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, "PolarStereographic" )) ) { 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... strcat(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, "SimpleCylindrical" )) || (EQUAL( map_proj_name, "Orthographic" )) || (EQUAL( map_proj_name, "Stereographic" )) || (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" )) { //Calculate localRadius using ISIS3 simple elliptical method // not the more standard Radius of Curvature method //PI = 4 * atan(1); 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) ); strcat(sphere_name, "_localRadius"); oSRS.SetGeogCS( geog_name, datum_name, sphere_name, localRadius, 0.0, "Reference_Meridian", 0.0 ); } 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 ISIS3 Label Read */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* -------------------------------------------------------------------- */ /* Is the CUB detached - if so, reset name to binary file? */ /* -------------------------------------------------------------------- */ #ifdef notdef // Frank - is this correct? //The extension already added on so don't add another. But is this needed? char *pszPath = CPLStrdup( CPLGetPath( poOpenInfo->pszFilename ) ); char *pszName = CPLStrdup( CPLGetBasename( poOpenInfo->pszFilename ) ); if (bIsDetached) pszCUBFilename = CPLFormCIFilename( pszPath, detachedCub, "" ); #endif /* -------------------------------------------------------------------- */ /* 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( osQubeFile, "r" ); else poDS->fpImage = VSIFOpenL( osQubeFile, "r+" ); if( poDS->fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open %s with write permission.\n%s", osQubeFile.c_str(), VSIStrerror( errno ) ); delete poDS; return NULL; } poDS->eAccess = poOpenInfo->eAccess; /* -------------------------------------------------------------------- */ /* Compute the line offset. */ /* -------------------------------------------------------------------- */ int nItemSize = GDALGetDataTypeSize(eDataType)/8; int nLineOffset=0, nPixelOffset=0, nBandOffset=0; if( EQUAL(szLayout,"BSQ") ) { nPixelOffset = nItemSize; nLineOffset = nPixelOffset * nCols; nBandOffset = nLineOffset * nRows; } else /* Tiled */ { } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ int i; #ifdef CPL_LSB int bNativeOrder = !(chByteOrder == 'M'); #else int bNativeOrder = (chByteOrder == 'M'); #endif for( i = 0; i < nBands; i++ ) { GDALRasterBand *poBand; if( EQUAL(szLayout,"Tiled") ) { poBand = new ISISTiledBand( poDS, poDS->fpImage, i+1, eDataType, tileSizeX, tileSizeY, nSkipBytes, 0, 0, bNativeOrder ); } else { 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 ); } poDS->SetBand( i+1, poBand ); if( bNoDataSet ) ((GDALPamRasterBand *) poBand)->SetNoDataValue( dfNoData ); // Set offset/scale values at the PAM level. poBand->SetOffset( CPLAtofM(poDS->GetKeyword("IsisCube.Core.Pixels.Base","0.0"))); poBand->SetScale( CPLAtofM(poDS->GetKeyword("IsisCube.Core.Pixels.Multiplier","1.0"))); } /* -------------------------------------------------------------------- */ /* Check for a .prj file. For ISIS3 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 ); }
int FindSRS( const char *pszInput, OGRSpatialReference &oSRS ) { int bGotSRS = FALSE; VSILFILE *fp = NULL; GDALDataset *poGDALDS = NULL; OGRLayer *poLayer = NULL; const char *pszProjection = NULL; CPLErrorHandler oErrorHandler = NULL; int bIsFile = FALSE; OGRErr eErr = OGRERR_NONE; int bDebug = FALSE; /* temporarily suppress error messages we may get from xOpen() */ bDebug = CSLTestBoolean(CPLGetConfigOption("CPL_DEBUG", "OFF")); if ( ! bDebug ) oErrorHandler = CPLSetErrorHandler ( CPLQuietErrorHandler ); /* Test if argument is a file */ fp = VSIFOpenL( pszInput, "r" ); if ( fp ) { bIsFile = TRUE; VSIFCloseL( fp ); CPLDebug( "gdalsrsinfo", "argument is a file" ); } /* try to open with GDAL */ if( strncmp(pszInput, "http://spatialreference.org/", strlen("http://spatialreference.org/")) != 0 ) { CPLDebug( "gdalsrsinfo", "trying to open with GDAL" ); poGDALDS = (GDALDataset *) GDALOpenEx( pszInput, 0, NULL, NULL, NULL ); } if ( poGDALDS != NULL ) { pszProjection = poGDALDS->GetProjectionRef( ); if( pszProjection != NULL && pszProjection[0] != '\0' ) { char* pszProjectionTmp = (char*) pszProjection; if( oSRS.importFromWkt( &pszProjectionTmp ) == OGRERR_NONE ) { CPLDebug( "gdalsrsinfo", "got SRS from GDAL" ); bGotSRS = TRUE; } } else if( poGDALDS->GetLayerCount() > 0 ) { poLayer = poGDALDS->GetLayer( 0 ); if ( poLayer != NULL ) { OGRSpatialReference *poSRS = poLayer->GetSpatialRef( ); if ( poSRS != NULL ) { CPLDebug( "gdalsrsinfo", "got SRS from OGR" ); bGotSRS = TRUE; OGRSpatialReference* poSRSClone = poSRS->Clone(); oSRS = *poSRSClone; OGRSpatialReference::DestroySpatialReference( poSRSClone ); } } } GDALClose( (GDALDatasetH) poGDALDS ); if ( ! bGotSRS ) CPLDebug( "gdalsrsinfo", "did not open with GDAL" ); } /* Try ESRI file */ if ( ! bGotSRS && bIsFile && (strstr(pszInput,".prj") != NULL) ) { CPLDebug( "gdalsrsinfo", "trying to get SRS from ESRI .prj file [%s]", pszInput ); char **pszTemp; if ( strstr(pszInput,"ESRI::") != NULL ) pszTemp = CSLLoad( pszInput+6 ); else pszTemp = CSLLoad( pszInput ); if( pszTemp ) { eErr = oSRS.importFromESRI( pszTemp ); CSLDestroy( pszTemp ); } else eErr = OGRERR_UNSUPPORTED_SRS; if( eErr != OGRERR_NONE ) { CPLDebug( "gdalsrsinfo", "did not get SRS from ESRI .prj file" ); } else { CPLDebug( "gdalsrsinfo", "got SRS from ESRI .prj file" ); bGotSRS = TRUE; } } /* Last resort, try OSRSetFromUserInput() */ if ( ! bGotSRS ) { CPLDebug( "gdalsrsinfo", "trying to get SRS from user input [%s]", pszInput ); eErr = oSRS.SetFromUserInput( pszInput ); if( eErr != OGRERR_NONE ) { CPLDebug( "gdalsrsinfo", "did not get SRS from user input" ); } else { CPLDebug( "gdalsrsinfo", "got SRS from user input" ); bGotSRS = TRUE; } } /* restore error messages */ if ( ! bDebug ) CPLSetErrorHandler ( oErrorHandler ); return bGotSRS; }
GDALDataset *FujiBASDataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* We assume the user is pointing to the header (.pcb) file. */ /* Does this appear to be a pcb file? */ /* -------------------------------------------------------------------- */ if( poOpenInfo->nHeaderBytes < 80 || poOpenInfo->fpL == NULL ) return NULL; if( !EQUALN((const char *)poOpenInfo->pabyHeader,"[Raw data]",10) || strstr((const char *)poOpenInfo->pabyHeader, "Fuji BAS") == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Load the header file. */ /* -------------------------------------------------------------------- */ char **papszHeader; int nXSize, nYSize; const char *pszOrgFile; papszHeader = CSLLoad( poOpenInfo->pszFilename ); if( papszHeader == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Munge header information into form suitable for CSL functions. */ /* -------------------------------------------------------------------- */ int i; for( i = 0; papszHeader[i] != NULL; i++ ) { char *pszSep = strstr(papszHeader[i]," = "); if( pszSep != NULL ) { memmove( pszSep + 1, pszSep + 3, strlen(pszSep+3)+1 ); *pszSep = '='; } } /* -------------------------------------------------------------------- */ /* Fetch required fields. */ /* -------------------------------------------------------------------- */ if( CSLFetchNameValue(papszHeader, "width") == NULL || CSLFetchNameValue(papszHeader, "height") == NULL || CSLFetchNameValue(papszHeader, "OrgFile") == NULL ) { CSLDestroy( papszHeader ); return NULL; } nYSize = atoi(CSLFetchNameValue(papszHeader,"width")); nXSize = atoi(CSLFetchNameValue(papszHeader,"height")); pszOrgFile = CSLFetchNameValue(papszHeader,"OrgFile"); if( nXSize < 1 || nYSize < 1 ) { CSLDestroy( papszHeader ); return NULL; } /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The FUJIBAS driver does not support update access to existing" " datasets.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Try to open the original data file. */ /* -------------------------------------------------------------------- */ const char *pszRawFile; char *pszPath = CPLStrdup(CPLGetPath(poOpenInfo->pszFilename)); FILE *fpRaw; pszRawFile = CPLFormCIFilename( pszPath, pszOrgFile, "IMG" ); CPLFree( pszPath ); fpRaw = VSIFOpen( pszRawFile, "rb" ); if( fpRaw == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Trying to open Fuji BAS image with the header file:\n" " Header=%s\n" "but expected raw image file doesn't appear to exist. Trying to open:\n" " Raw File=%s\n" "Perhaps the raw file needs to be renamed to match expected?", poOpenInfo->pszFilename, pszRawFile ); CSLDestroy( papszHeader ); return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ FujiBASDataset *poDS; poDS = new FujiBASDataset(); /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ poDS->nRasterXSize = nXSize; poDS->nRasterYSize = nYSize; poDS->papszHeader = papszHeader; poDS->fpImage = fpRaw; /* -------------------------------------------------------------------- */ /* Create band information object. */ /* -------------------------------------------------------------------- */ int bNativeOrder; #ifdef CPL_MSB bNativeOrder = TRUE; #else bNativeOrder = FALSE; #endif poDS->SetBand( 1, new RawRasterBand( poDS, 1, poDS->fpImage, 0, 2, nXSize * 2, GDT_UInt16, bNativeOrder )); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
int main( int argc, char ** argv ) { GDALDatasetH hDataset, hOutDS; int i; const char *pszSource=NULL, *pszDest=NULL, *pszFormat = "GTiff"; GDALDriverH hDriver; GDALDataType eOutputType = GDT_Unknown; char **papszCreateOptions = NULL; GDALProgressFunc pfnProgress = GDALTermProgress; int nLUTBins = 256; const char *pszMethod = "minmax"; // double dfStdDevMult = 0.0; double *padfScaleMin = NULL; double *padfScaleMax = NULL; int **papanLUTs = NULL; int iBand; const char *pszConfigFile = NULL; /* Check strict compilation and runtime library version as we use C++ API */ if (! GDAL_CHECK_VERSION(argv[0])) exit(1); /* -------------------------------------------------------------------- */ /* Register standard GDAL drivers, and process generic GDAL */ /* command options. */ /* -------------------------------------------------------------------- */ GDALAllRegister(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Handle command line arguments. */ /* -------------------------------------------------------------------- */ for( i = 1; i < argc; i++ ) { if( EQUAL(argv[i], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against GDAL %s\n", argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); return 0; } else if( EQUAL(argv[i],"-of") && i < argc-1 ) pszFormat = argv[++i]; else if( EQUAL(argv[i],"-ot") && i < argc-1 ) { int iType; for( iType = 1; iType < GDT_TypeCount; iType++ ) { if( GDALGetDataTypeName((GDALDataType)iType) != NULL && EQUAL(GDALGetDataTypeName((GDALDataType)iType), argv[i+1]) ) { eOutputType = (GDALDataType) iType; } } if( eOutputType == GDT_Unknown ) { printf( "Unknown output pixel type: %s\n", argv[i+1] ); Usage(); GDALDestroyDriverManager(); exit( 2 ); } i++; } else if( EQUALN(argv[i],"-s_nodata",9) ) { // TODO i += 1; } else if( EQUAL(argv[i],"-co") && i < argc-1 ) { papszCreateOptions = CSLAddString( papszCreateOptions, argv[++i] ); } else if( EQUALN(argv[i],"-src_scale",10) && i < argc-2) { // TODO i += 2; } else if( EQUALN(argv[i],"-dst_scale",10) && i < argc-2 ) { // TODO i += 2; } else if( EQUAL(argv[i],"-config") && i < argc-1 ) { pszConfigFile = argv[++i]; } else if( EQUAL(argv[i],"-equalize") ) { pszMethod = "equalize"; } else if( EQUAL(argv[i],"-quiet") ) { pfnProgress = GDALDummyProgress; } else if( argv[i][0] == '-' ) { printf( "Option %s incomplete, or not recognised.\n\n", argv[i] ); Usage(); GDALDestroyDriverManager(); exit( 2 ); } else if( pszSource == NULL ) { pszSource = argv[i]; } else if( pszDest == NULL ) { pszDest = argv[i]; } else { printf( "Too many command options.\n\n" ); Usage(); GDALDestroyDriverManager(); exit( 2 ); } } if( pszSource == NULL ) { Usage(); GDALDestroyDriverManager(); exit( 10 ); } /* -------------------------------------------------------------------- */ /* Attempt to open source file. */ /* -------------------------------------------------------------------- */ hDataset = GDALOpenShared( pszSource, GA_ReadOnly ); if( hDataset == NULL ) { fprintf( stderr, "GDALOpen failed - %d\n%s\n", CPLGetLastErrorNo(), CPLGetLastErrorMsg() ); GDALDestroyDriverManager(); exit( 1 ); } int nBandCount = GDALGetRasterCount(hDataset); /* -------------------------------------------------------------------- */ /* Find the output driver. */ /* -------------------------------------------------------------------- */ hDriver = GDALGetDriverByName( pszFormat ); if( hDriver == NULL ) { int iDr; printf( "Output driver `%s' not recognised.\n", pszFormat ); printf( "The following format drivers are configured and support output:\n" ); for( iDr = 0; iDr < GDALGetDriverCount(); iDr++ ) { GDALDriverH hDriver = GDALGetDriver(iDr); if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) != NULL || GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATECOPY, NULL ) != NULL ) { printf( " %s: %s\n", GDALGetDriverShortName( hDriver ), GDALGetDriverLongName( hDriver ) ); } } printf( "\n" ); Usage(); GDALClose( hDataset ); GDALDestroyDriverManager(); CSLDestroy( argv ); CSLDestroy( papszCreateOptions ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* If histogram equalization is requested, do it now. */ /* -------------------------------------------------------------------- */ if( EQUAL(pszMethod,"equalize") ) { ComputeEqualizationLUTs( hDataset, nLUTBins, &padfScaleMin, &padfScaleMax, &papanLUTs, pfnProgress ); } /* -------------------------------------------------------------------- */ /* If we have a config file, assume it is for input and read */ /* it. */ /* -------------------------------------------------------------------- */ else if( pszConfigFile != NULL ) { char **papszLines = CSLLoad( pszConfigFile ); if( CSLCount(papszLines) == 0 ) exit( 1 ); if( CSLCount(papszLines) != nBandCount ) { fprintf( stderr, "Did not get %d lines in config file as expected.\n", nBandCount ); exit( 1 ); } padfScaleMin = (double *) CPLCalloc(nBandCount,sizeof(double)); padfScaleMax = (double *) CPLCalloc(nBandCount,sizeof(double)); for( iBand = 0; iBand < nBandCount; iBand++ ) { int iLUT; char **papszTokens = CSLTokenizeString( papszLines[iBand] ); if( CSLCount(papszTokens) < 3 || atoi(papszTokens[0]) != iBand+1 ) { fprintf( stderr, "Line %d seems to be corrupt.\n", iBand+1 ); exit( 1 ); } // Process scale min/max padfScaleMin[iBand] = atof(papszTokens[1]); padfScaleMax[iBand] = atof(papszTokens[2]); if( CSLCount(papszTokens) == 3 ) continue; // process lut if( iBand == 0 ) { nLUTBins = CSLCount(papszTokens) - 3; papanLUTs = (int **) CPLCalloc(sizeof(int*),nBandCount); } papanLUTs[iBand] = (int *) CPLCalloc(nLUTBins,sizeof(int)); for( iLUT = 0; iLUT < nLUTBins; iLUT++ ) papanLUTs[iBand][iLUT] = atoi(papszTokens[iLUT+3]); CSLDestroy( papszTokens ); } } /* -------------------------------------------------------------------- */ /* If there is no destination, just report the scaling values */ /* and luts. */ /* -------------------------------------------------------------------- */ if( pszDest == NULL ) { FILE *fpConfig = stdout; if( pszConfigFile ) fpConfig = fopen( pszConfigFile, "w" ); for( iBand = 0; iBand < nBandCount; iBand++ ) { fprintf( fpConfig, "%d:Band ", iBand+1 ); if( padfScaleMin != NULL ) fprintf( fpConfig, "%g:ScaleMin %g:ScaleMax ", padfScaleMin[iBand], padfScaleMax[iBand] ); if( papanLUTs ) { int iLUT; for( iLUT = 0; iLUT < nLUTBins; iLUT++ ) fprintf( fpConfig, "%d ", papanLUTs[iBand][iLUT] ); } fprintf( fpConfig, "\n" ); } if( pszConfigFile ) fclose( fpConfig ); exit( 0 ); } if (padfScaleMin == NULL || padfScaleMax == NULL) { fprintf( stderr, "-equalize or -config filename command line options must be specified.\n"); exit(1); } /* ==================================================================== */ /* Create a virtual dataset. */ /* ==================================================================== */ VRTDataset *poVDS; EnhanceCBInfo *pasEInfo = (EnhanceCBInfo *) CPLCalloc(nBandCount, sizeof(EnhanceCBInfo)); /* -------------------------------------------------------------------- */ /* Make a virtual clone. */ /* -------------------------------------------------------------------- */ poVDS = new VRTDataset( GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset) ); if( GDALGetGCPCount(hDataset) == 0 ) { const char *pszProjection; double adfGeoTransform[6]; pszProjection = GDALGetProjectionRef( hDataset ); if( pszProjection != NULL && strlen(pszProjection) > 0 ) poVDS->SetProjection( pszProjection ); if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ) poVDS->SetGeoTransform( adfGeoTransform ); } else { poVDS->SetGCPs( GDALGetGCPCount(hDataset), GDALGetGCPs(hDataset), GDALGetGCPProjection( hDataset ) ); } poVDS->SetMetadata( ((GDALDataset*)hDataset)->GetMetadata() ); for( iBand = 0; iBand < nBandCount; iBand++ ) { VRTSourcedRasterBand *poVRTBand; GDALRasterBand *poSrcBand; GDALDataType eBandType; poSrcBand = ((GDALDataset *) hDataset)->GetRasterBand(iBand+1); /* -------------------------------------------------------------------- */ /* Select output data type to match source. */ /* -------------------------------------------------------------------- */ if( eOutputType == GDT_Unknown ) eBandType = GDT_Byte; else eBandType = eOutputType; /* -------------------------------------------------------------------- */ /* Create this band. */ /* -------------------------------------------------------------------- */ poVDS->AddBand( eBandType, NULL ); poVRTBand = (VRTSourcedRasterBand *) poVDS->GetRasterBand( iBand+1 ); /* -------------------------------------------------------------------- */ /* Create a function based source with info on how to apply the */ /* enhancement. */ /* -------------------------------------------------------------------- */ pasEInfo[iBand].poSrcBand = poSrcBand; pasEInfo[iBand].eWrkType = eBandType; pasEInfo[iBand].dfScaleMin = padfScaleMin[iBand]; pasEInfo[iBand].dfScaleMax = padfScaleMax[iBand]; pasEInfo[iBand].nLUTBins = nLUTBins; if( papanLUTs ) pasEInfo[iBand].panLUT = papanLUTs[iBand]; poVRTBand->AddFuncSource( EnhancerCallback, pasEInfo + iBand ); /* -------------------------------------------------------------------- */ /* copy over some other information of interest. */ /* -------------------------------------------------------------------- */ poVRTBand->CopyCommonInfoFrom( poSrcBand ); } /* -------------------------------------------------------------------- */ /* Write to the output file using CopyCreate(). */ /* -------------------------------------------------------------------- */ hOutDS = GDALCreateCopy( hDriver, pszDest, (GDALDatasetH) poVDS, FALSE, papszCreateOptions, pfnProgress, NULL ); if( hOutDS != NULL ) GDALClose( hOutDS ); GDALClose( (GDALDatasetH) poVDS ); GDALClose( hDataset ); /* -------------------------------------------------------------------- */ /* Cleanup and exit. */ /* -------------------------------------------------------------------- */ GDALDumpOpenDatasets( stderr ); GDALDestroyDriverManager(); CSLDestroy( argv ); CSLDestroy( papszCreateOptions ); exit( 0 ); }
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 *AAIGDataset::CommonOpen( GDALOpenInfo *poOpenInfo, GridFormat eFormat ) { if( poOpenInfo->fpL == nullptr ) return nullptr; // Create a corresponding GDALDataset. AAIGDataset *poDS = nullptr; if (eFormat == FORMAT_AAIG) poDS = new AAIGDataset(); else poDS = new GRASSASCIIDataset(); const char *pszDataTypeOption = eFormat == FORMAT_AAIG ? "AAIGRID_DATATYPE" : "GRASSASCIIGRID_DATATYPE"; const char *pszDataType = CPLGetConfigOption(pszDataTypeOption, nullptr); if( pszDataType == nullptr ) pszDataType = CSLFetchNameValue(poOpenInfo->papszOpenOptions, "DATATYPE"); if (pszDataType != nullptr) { poDS->eDataType = GDALGetDataTypeByName(pszDataType); if (!(poDS->eDataType == GDT_Int32 || poDS->eDataType == GDT_Float32 || poDS->eDataType == GDT_Float64)) { CPLError(CE_Warning, CPLE_NotSupported, "Unsupported value for %s : %s", pszDataTypeOption, pszDataType); poDS->eDataType = GDT_Int32; pszDataType = nullptr; } } // Parse the header. if (!poDS->ParseHeader((const char *)poOpenInfo->pabyHeader, pszDataType)) { delete poDS; return nullptr; } poDS->fp = poOpenInfo->fpL; poOpenInfo->fpL = nullptr; // Find the start of real data. int nStartOfData = 0; for( int i = 2; true; i++ ) { if( poOpenInfo->pabyHeader[i] == '\0' ) { CPLError(CE_Failure, CPLE_AppDefined, "Couldn't find data values in ASCII Grid file."); delete poDS; return nullptr; } if( poOpenInfo->pabyHeader[i - 1] == '\n' || poOpenInfo->pabyHeader[i - 2] == '\n' || poOpenInfo->pabyHeader[i - 1] == '\r' || poOpenInfo->pabyHeader[i - 2] == '\r' ) { if( !isalpha(poOpenInfo->pabyHeader[i]) && poOpenInfo->pabyHeader[i] != '\n' && poOpenInfo->pabyHeader[i] != '\r') { nStartOfData = i; // Beginning of real data found. break; } } } // Recognize the type of data. CPLAssert(nullptr != poDS->fp); if( pszDataType == nullptr && poDS->eDataType != GDT_Float32 && poDS->eDataType != GDT_Float64) { // Allocate 100K chunk + 1 extra byte for NULL character. constexpr size_t nChunkSize = 1024 * 100; GByte *pabyChunk = static_cast<GByte *>( VSI_CALLOC_VERBOSE(nChunkSize + 1, sizeof(GByte))); if (pabyChunk == nullptr) { delete poDS; return nullptr; } pabyChunk[nChunkSize] = '\0'; if( VSIFSeekL(poDS->fp, nStartOfData, SEEK_SET) < 0 ) { delete poDS; VSIFree(pabyChunk); return nullptr; } // Scan for dot in subsequent chunks of data. while( !VSIFEofL(poDS->fp) ) { CPL_IGNORE_RET_VAL(VSIFReadL(pabyChunk, nChunkSize, 1, poDS->fp)); for( int i = 0; i < static_cast<int>(nChunkSize); i++) { GByte ch = pabyChunk[i]; if (ch == '.' || ch == ',' || ch == 'e' || ch == 'E') { poDS->eDataType = GDT_Float32; break; } } } // Deallocate chunk. VSIFree(pabyChunk); } // Create band information objects. AAIGRasterBand *band = new AAIGRasterBand(poDS, nStartOfData); poDS->SetBand(1, band); if (band->panLineOffset == nullptr) { delete poDS; return nullptr; } // Try to read projection file. char *const pszDirname = CPLStrdup(CPLGetPath(poOpenInfo->pszFilename)); char *const pszBasename = CPLStrdup(CPLGetBasename(poOpenInfo->pszFilename)); poDS->osPrjFilename = CPLFormFilename(pszDirname, pszBasename, "prj"); int nRet = 0; { VSIStatBufL sStatBuf; nRet = VSIStatL(poDS->osPrjFilename, &sStatBuf); } if( nRet != 0 && VSIIsCaseSensitiveFS(poDS->osPrjFilename) ) { poDS->osPrjFilename = CPLFormFilename(pszDirname, pszBasename, "PRJ"); VSIStatBufL sStatBuf; nRet = VSIStatL(poDS->osPrjFilename, &sStatBuf); } if( nRet == 0 ) { poDS->papszPrj = CSLLoad(poDS->osPrjFilename); CPLDebug("AAIGrid", "Loaded SRS from %s", poDS->osPrjFilename.c_str()); OGRSpatialReference oSRS; if( oSRS.importFromESRI(poDS->papszPrj) == OGRERR_NONE ) { // If geographic values are in seconds, we must transform. // Is there a code for minutes too? if( oSRS.IsGeographic() && EQUAL(OSR_GDS(poDS->papszPrj, "Units", ""), "DS") ) { poDS->adfGeoTransform[0] /= 3600.0; poDS->adfGeoTransform[1] /= 3600.0; poDS->adfGeoTransform[2] /= 3600.0; poDS->adfGeoTransform[3] /= 3600.0; poDS->adfGeoTransform[4] /= 3600.0; poDS->adfGeoTransform[5] /= 3600.0; } CPLFree(poDS->pszProjection); oSRS.exportToWkt(&(poDS->pszProjection)); } } CPLFree(pszDirname); CPLFree(pszBasename); // Initialize any PAM information. poDS->SetDescription(poOpenInfo->pszFilename); poDS->TryLoadXML(); // Check for external overviews. poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename, poOpenInfo->GetSiblingFiles()); return poDS; }
/** * LoadMetadata() */ void GDALMDReaderALOS::LoadMetadata() { if(m_bIsMetadataLoad) return; if(!m_osIMDSourceFilename.empty()) { m_papszIMDMD = CSLLoad(m_osIMDSourceFilename); } if(!m_osHDRSourceFilename.empty()) { if(NULL == m_papszIMDMD) { m_papszIMDMD = CSLLoad(m_osHDRSourceFilename); } else { char** papszHDR = CSLLoad(m_osHDRSourceFilename); m_papszIMDMD = CSLMerge(m_papszIMDMD, papszHDR); CSLDestroy(papszHDR); } } m_papszRPCMD = LoadRPCTxtFile(); m_papszDEFAULTMD = CSLAddNameValue(m_papszDEFAULTMD, MD_NAME_MDTYPE, "ALOS"); m_bIsMetadataLoad = true; const char* pszSatId1 = CSLFetchNameValue(m_papszIMDMD, "Lbi_Satellite"); const char* pszSatId2 = CSLFetchNameValue(m_papszIMDMD, "Lbi_Sensor"); if(NULL != pszSatId1 && NULL != pszSatId2) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE, CPLSPrintf( "%s %s", CPLStripQuotes(pszSatId1).c_str(), CPLStripQuotes(pszSatId2).c_str())); } else if(NULL != pszSatId1 && NULL == pszSatId2) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE, CPLStripQuotes(pszSatId1)); } else if(NULL == pszSatId1 && NULL != pszSatId2) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE, CPLStripQuotes(pszSatId2)); } const char* pszCloudCover = CSLFetchNameValue(m_papszIMDMD, "Img_CloudQuantityOfAllImage"); if(NULL != pszCloudCover) { int nCC = atoi(pszCloudCover); if(nCC >= 99) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, MD_CLOUDCOVER_NA); } else { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, CPLSPrintf("%d", nCC * 10)); } } const char* pszDate = CSLFetchNameValue(m_papszIMDMD, "Img_SceneCenterDateTime"); if(NULL != pszDate) { char buffer[80]; time_t timeMid = GetAcquisitionTimeFromString(CPLStripQuotes(pszDate)); strftime (buffer, 80, MD_DATETIMEFORMAT, localtime(&timeMid)); m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_ACQDATETIME, buffer); } else { pszDate = CSLFetchNameValue(m_papszIMDMD, "Lbi_ObservationDate"); if(NULL != pszDate) { const char* pszTime = "00:00:00.000"; char buffer[80]; time_t timeMid = GetAcquisitionTimeFromString(CPLSPrintf( "%s %s", CPLStripQuotes(pszDate).c_str(), CPLStripQuotes(pszTime).c_str())); strftime (buffer, 80, MD_DATETIMEFORMAT, localtime(&timeMid)); m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_ACQDATETIME, buffer); } } }