OGRSpatialReference* OGRGetGeomediaSRS(OGRFeature* poFeature) { if (poFeature == NULL) return NULL; int nGeodeticDatum = poFeature->GetFieldAsInteger("GeodeticDatum"); int nEllipsoid = poFeature->GetFieldAsInteger("Ellipsoid"); int nProjAlgorithm = poFeature->GetFieldAsInteger("ProjAlgorithm"); if (nGeodeticDatum == 17 && nEllipsoid == 22) { if (nProjAlgorithm == 12) { OGRSpatialReference* poSRS = new OGRSpatialReference(); const char* pszDescription = poFeature->GetFieldAsString("Description"); if (pszDescription && pszDescription[0] != 0) poSRS->SetNode( "PROJCS", pszDescription ); poSRS->SetWellKnownGeogCS("WGS84"); double dfStdP1 = poFeature->GetFieldAsDouble("StandPar1"); double dfStdP2 = poFeature->GetFieldAsDouble("StandPar2"); double dfCenterLat = poFeature->GetFieldAsDouble("LatOfOrigin"); double dfCenterLong = poFeature->GetFieldAsDouble("LonOfOrigin"); double dfFalseEasting = poFeature->GetFieldAsDouble("FalseX"); double dfFalseNorthing = poFeature->GetFieldAsDouble("FalseY"); poSRS->SetACEA( dfStdP1, dfStdP2, dfCenterLat, dfCenterLong, dfFalseEasting, dfFalseNorthing ); return poSRS; } } return NULL; }
void IDADataset::ProcessGeoref() { OGRSpatialReference oSRS; if( nProjection == 3 ) { oSRS.SetWellKnownGeogCS( "WGS84" ); } else if( nProjection == 4 ) { oSRS.SetLCC( dfParallel1, dfParallel2, dfLatCenter, dfLongCenter, 0.0, 0.0 ); oSRS.SetGeogCS( "Clarke 1866", "Clarke 1866", "Clarke 1866", 6378206.4, 293.97869821389662 ); } else if( nProjection == 6 ) { oSRS.SetLAEA( dfLatCenter, dfLongCenter, 0.0, 0.0 ); oSRS.SetGeogCS( "Sphere", "Sphere", "Sphere", 6370997.0, 0.0 ); } else if( nProjection == 8 ) { oSRS.SetACEA( dfParallel1, dfParallel2, dfLatCenter, dfLongCenter, 0.0, 0.0 ); oSRS.SetGeogCS( "Clarke 1866", "Clarke 1866", "Clarke 1866", 6378206.4, 293.97869821389662 ); } else if( nProjection == 9 ) { oSRS.SetGH( dfLongCenter, 0.0, 0.0 ); oSRS.SetGeogCS( "Sphere", "Sphere", "Sphere", 6370997.0, 0.0 ); } if( oSRS.GetRoot() != NULL ) { CPLFree( pszProjection ); pszProjection = NULL; oSRS.exportToWkt( &pszProjection ); } adfGeoTransform[0] = 0 - dfDX * dfXCenter; adfGeoTransform[1] = dfDX; adfGeoTransform[2] = 0.0; adfGeoTransform[3] = dfDY * dfYCenter; adfGeoTransform[4] = 0.0; adfGeoTransform[5] = -dfDY; if( nProjection == 3 ) { adfGeoTransform[0] += dfLongCenter; adfGeoTransform[3] += dfLatCenter; } }
std::string AlbersConEqArea::wkt() { OGRSpatialReference sr; int epsg = DATUM2EPSG[datum()]; char **wkt = 0; std::string output = ""; OGRErr err; sr.SetProjCS("Albers Conic Equal Area"); if (epsg != -1) { sr.importFromEPSG(epsg); sr.SetACEA(param(2), param(3), param(5), param(4), param(6), param(7)); err = sr.exportToPrettyWkt(wkt); } else { return output; } if (err == OGRERR_NONE) { output = *wkt; OGRFree(wkt); } return output; }
void clsRasterData::outputGTiff(map<string,float> header,int nValidCells,float** position, float* value,string filename) { float noDataValue = header["NODATA_VALUE"]; int nCols = header["NCOLS"]; int nRows = header["NROWS"]; float xll = header["XLLCENTER"]; float yll = header["YLLCENTER"]; float dx = header["CELLSIZE"]; int n = nRows * nCols; float *data = new float[n]; int index = 0; for (int i = 0; i < nRows; ++i) { for (int j = 0; j < nCols; ++j) { if(index < nValidCells) { if(position[index][0] == i && position[index][1] == j) { data[i*nCols+j] = value[index]; index++; } else data[i*nCols+j] = noDataValue; } else data[i*nCols+j] = noDataValue; } } const char *pszFormat = "GTiff"; GDALDriver *poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat); char **papszOptions = poDriver->GetMetadata(); GDALDataset *poDstDS = poDriver->Create(filename.c_str(), nCols, nRows, 1, GDT_Float32, papszOptions ); //write the data to new file GDALRasterBand *poDstBand= poDstDS->GetRasterBand(1); poDstBand->RasterIO(GF_Write, 0, 0, nCols, nRows, data, nCols, nRows, GDT_Float32, 0, 0); poDstBand->SetNoDataValue(noDataValue); double geoTrans[6]; geoTrans[0] = xll; geoTrans[1] = dx; geoTrans[2] = 0; geoTrans[3] = yll + nRows*dx; geoTrans[4] = 0; geoTrans[5] = -dx; poDstDS->SetGeoTransform(geoTrans); OGRSpatialReference srs; srs.SetACEA(25, 47, 0, 105, 0, 0); srs.SetWellKnownGeogCS("WGS84"); char *pSrsWkt = NULL; srs.exportToWkt(&pSrsWkt); poDstDS->SetProjection(pSrsWkt); CPLFree(pSrsWkt); GDALClose(poDstDS); delete[] data; }
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 ); }
GDALDataset *VICARDataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Does this look like a VICAR 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; VICARDataset *poDS = new VICARDataset(); if( ! poDS->oKeywords.Ingest( fpQube, poOpenInfo->pabyHeader ) ) { VSIFCloseL( fpQube ); delete poDS; return NULL; } VSIFCloseL( fpQube ); /***** CHECK ENDIANNESS **************/ const char *value = poDS->GetKeyword( "INTFMT" ); if (!EQUAL(value,"LOW") ) { CPLError( CE_Failure, CPLE_OpenFailed, "%s layout not supported. Abort\n\n", value); delete poDS; return FALSE; } value = poDS->GetKeyword( "REALFMT" ); if (!EQUAL(value,"RIEEE") ) { CPLError( CE_Failure, CPLE_OpenFailed, "%s layout not supported. Abort\n\n", value); delete poDS; return FALSE; } char chByteOrder = 'M'; value = poDS->GetKeyword( "BREALFMT" ); if (EQUAL(value,"VAX") ) { chByteOrder = 'I'; } /************ CHECK INSTRUMENT *****************/ /************ ONLY HRSC TESTED *****************/ bool bIsDTM = false; value = poDS->GetKeyword( "DTM.DTM_OFFSET" ); if (!EQUAL(value,"") ) { bIsDTM = true; } value = poDS->GetKeyword( "BLTYPE" ); if (!EQUAL(value,"M94_HRSC") && !bIsDTM ) { CPLError( CE_Failure, CPLE_OpenFailed, "%s instrument not tested. Continue with caution!\n\n", value); } /*********** Grab layout type (BSQ, BIP, BIL) ************/ char szLayout[10] = "BSQ"; //default to band seq. value = poDS->GetKeyword( "ORG" ); if (!EQUAL(value,"BSQ") ) { CPLError( CE_Failure, CPLE_OpenFailed, "%s layout not supported. Abort\n\n", value); delete poDS; return FALSE; } strcpy(szLayout,"BSQ"); const int nCols = atoi(poDS->GetKeyword("NS")); const int nRows = atoi(poDS->GetKeyword("NL")); const int nBands = atoi(poDS->GetKeyword("NB")); /*********** Grab record bytes **********/ int nSkipBytes = atoi(poDS->GetKeyword("NBB")); GDALDataType eDataType = GDT_Byte; double dfNoData = 0.0; if (EQUAL( poDS->GetKeyword( "FORMAT" ), "BYTE" )) { eDataType = GDT_Byte; dfNoData = NULL1; } else if (EQUAL( poDS->GetKeyword( "FORMAT" ), "HALF" )) { eDataType = GDT_Int16; dfNoData = NULL2; chByteOrder = 'I'; } else if (EQUAL( poDS->GetKeyword( "FORMAT" ), "FULL" )) { eDataType = GDT_UInt32; dfNoData = 0; } else if (EQUAL( poDS->GetKeyword( "FORMAT" ), "REAL" )) { eDataType = GDT_Float32; dfNoData = NULL3; chByteOrder = 'I'; } else { CPLError( CE_Failure, CPLE_AppDefined, "Could not find known VICAR label entries!\n"); delete poDS; return NULL; } if( nRows < 1 || nCols < 1 || nBands < 1 ) { CPLError( CE_Failure, CPLE_AppDefined, "File %s appears to be a VICAR file, but failed to find some " "required keywords.", poDS->GetDescription() ); return FALSE; } /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ poDS->nRasterXSize = nCols; poDS->nRasterYSize = nRows; 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 = poDS->GetKeyword("MAP.MAP_SCALE"); if (strlen(value) > 0 ) { dfXDim = CPLAtof(value); dfYDim = CPLAtof(value) * -1; dfXDim = dfXDim * 1000.0; dfYDim = dfYDim * 1000.0; } double dfSampleOffset_Shift = CPLAtof(CPLGetConfigOption( "PDS_SampleProjOffset_Shift", "-0.5" )); double dfLineOffset_Shift = CPLAtof(CPLGetConfigOption( "PDS_LineProjOffset_Shift", "-0.5" )); double dfSampleOffset_Mult = CPLAtof(CPLGetConfigOption( "PDS_SampleProjOffset_Mult", "-1.0") ); double dfLineOffset_Mult = CPLAtof( CPLGetConfigOption( "PDS_LineProjOffset_Mult", "1.0") ); /*********** Grab LINE_PROJECTION_OFFSET ************/ value = poDS->GetKeyword("MAP.LINE_PROJECTION_OFFSET"); if (strlen(value) > 0) { yulcenter = CPLAtof(value); dfULYMap = ((yulcenter + dfLineOffset_Shift) * -dfYDim * dfLineOffset_Mult); } /*********** Grab SAMPLE_PROJECTION_OFFSET ************/ value = poDS->GetKeyword("MAP.SAMPLE_PROJECTION_OFFSET"); if( strlen(value) > 0 ) { xulcenter = CPLAtof(value); dfULXMap = ((xulcenter + dfSampleOffset_Shift) * dfXDim * dfSampleOffset_Mult); } /* ==================================================================== */ /* Get the coordinate system. */ /* ==================================================================== */ bool bProjectionSet = true; /*********** Grab TARGET_NAME ************/ /**** This is the planets name i.e. MARS ***/ const CPLString target_name = poDS->GetKeyword("MAP.TARGET_NAME"); /********** Grab MAP_PROJECTION_TYPE *****/ const CPLString map_proj_name = poDS->GetKeyword( "MAP.MAP_PROJECTION_TYPE"); /****** Grab semi_major & convert to KM ******/ const double semi_major = CPLAtof(poDS->GetKeyword( "MAP.A_AXIS_RADIUS")) * 1000.0; /****** Grab semi-minor & convert to KM ******/ const double semi_minor = CPLAtof(poDS->GetKeyword( "MAP.C_AXIS_RADIUS")) * 1000.0; /*********** Grab CENTER_LAT ************/ const double center_lat = CPLAtof(poDS->GetKeyword( "MAP.CENTER_LATITUDE")); /*********** Grab CENTER_LON ************/ const double center_lon = CPLAtof(poDS->GetKeyword( "MAP.CENTER_LONGITUDE")); /********** Grab 1st std parallel *******/ const double first_std_parallel = CPLAtof(poDS->GetKeyword( "MAP.FIRST_STANDARD_PARALLEL")); /********** Grab 2nd std parallel *******/ const double second_std_parallel = CPLAtof(poDS->GetKeyword( "MAP.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 bool bIsGeographic = true; value = poDS->GetKeyword("MAP.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()); OGRSpatialReference oSRS; 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( "VICAR", "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) double iflattening = 0.0; 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 ); poDS->osProjection = pszResult; CPLFree( pszResult ); } { 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; } CPLString osQubeFile = poOpenInfo->pszFilename; if( !poDS->bGotTransform ) poDS->bGotTransform = GDALReadWorldFile( osQubeFile, "psw", poDS->adfGeoTransform ); if( !poDS->bGotTransform ) poDS->bGotTransform = GDALReadWorldFile( osQubeFile, "wld", poDS->adfGeoTransform ); /* -------------------------------------------------------------------- */ /* 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 offsets. */ /* -------------------------------------------------------------------- */ const long int nItemSize = GDALGetDataTypeSize(eDataType)/8; const long int nPixelOffset = nItemSize; const long int nLineOffset = nPixelOffset * nCols + atoi(poDS->GetKeyword("NBB")) ; const long int nBandOffset = nLineOffset * nRows; nSkipBytes = atoi(poDS->GetKeyword("LBLSIZE")); /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ for( int i = 0; i < nBands; i++ ) { GDALRasterBand *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 ); poBand->SetNoDataValue( dfNoData ); if (bIsDTM) { poBand->SetScale( (double) CPLAtof(poDS->GetKeyword( "DTM.DTM_SCALING_FACTOR") ) ); poBand->SetOffset( (double) CPLAtof(poDS->GetKeyword( "DTM.DTM_OFFSET") ) ); const char* pszMin = poDS->GetKeyword( "DTM.DTM_MINIMUM_DN", NULL ); const char* pszMax = poDS->GetKeyword( "DTM.DTM_MAXIMUM_DN", NULL ); if (pszMin != NULL && pszMax != NULL ) poBand->SetStatistics(CPLAtofM(pszMin),CPLAtofM(pszMax),0,0); const char* pszNoData = poDS->GetKeyword( "DTM.DTM_MISSING_DN", NULL ); if (pszNoData != NULL ) poBand->SetNoDataValue( CPLAtofM(pszNoData) ); } else if (EQUAL( poDS->GetKeyword( "BLTYPE"), "M94_HRSC" )) { float scale=CPLAtof(poDS->GetKeyword("DLRTO8.REFLECTANCE_SCALING_FACTOR","-1.")); if (scale < 0.) { scale = CPLAtof(poDS->GetKeyword( "HRCAL.REFLECTANCE_SCALING_FACTOR","1.")); } poBand->SetScale( scale ); float offset=CPLAtof(poDS->GetKeyword("DLRTO8.REFLECTANCE_OFFSET","-1.")); if (offset < 0.) { offset = CPLAtof(poDS->GetKeyword( "HRCAL.REFLECTANCE_OFFSET","0.")); } poBand->SetOffset( offset ); } const char* pszMin = poDS->GetKeyword( "STATISTICS.MINIMUM", NULL ); const char* pszMax = poDS->GetKeyword( "STATISTICS.MAXIMUM", NULL ); const char* pszMean = poDS->GetKeyword( "STATISTICS.MEAN", NULL ); const char* pszStdDev = poDS->GetKeyword( "STATISTICS.STANDARD_DEVIATION", NULL ); if (pszMin != NULL && pszMax != NULL && pszMean != NULL && pszStdDev != NULL ) poBand->SetStatistics(CPLAtofM(pszMin),CPLAtofM(pszMax),CPLAtofM(pszMean),CPLAtofM(pszStdDev)); } /* -------------------------------------------------------------------- */ /* Instrument-specific keywords as metadata. */ /* -------------------------------------------------------------------- */ /****************** HRSC ******************************/ if (EQUAL( poDS->GetKeyword( "BLTYPE"), "M94_HRSC" ) ) { poDS->SetMetadataItem( "SPACECRAFT_NAME", poDS->GetKeyword( "M94_INSTRUMENT.INSTRUMENT_HOST_NAME") ); poDS->SetMetadataItem( "PRODUCT_TYPE", poDS->GetKeyword( "TYPE")); if (EQUAL( poDS->GetKeyword( "M94_INSTRUMENT.DETECTOR_ID"), "MEX_HRSC_SRC" )) { static const char *apszKeywords[] = { "M94_ORBIT.IMAGE_TIME", "FILE.EVENT_TYPE", "FILE.PROCESSING_LEVEL_ID", "M94_INSTRUMENT.DETECTOR_ID", "M94_CAMERAS.EXPOSURE_DURATION", "HRCONVER.INSTRUMENT_TEMPERATURE", NULL }; for( int i = 0; apszKeywords[i] != NULL; i++ ) { const char *pszKeywordValue = poDS->GetKeyword( apszKeywords[i] ); if( pszKeywordValue != NULL ) poDS->SetMetadataItem( apszKeywords[i], pszKeywordValue ); } } else { static const char *apszKeywords[] = { "M94_ORBIT.START_TIME", "M94_ORBIT.STOP_TIME", "M94_INSTRUMENT.DETECTOR_ID", "M94_CAMERAS.MACROPIXEL_SIZE", "FILE.EVENT_TYPE", "M94_INSTRUMENT.MISSION_PHASE_NAME", "HRORTHO.SPICE_FILE_NAME", "HRCONVER.MISSING_FRAMES", "HRCONVER.OVERFLOW_FRAMES", "HRCONVER.ERROR_FRAMES", "HRFOOT.BEST_GROUND_SAMPLING_DISTANCE", "DLRTO8.RADIANCE_SCALING_FACTOR", "DLRTO8.RADIANCE_OFFSET", "DLRTO8.REFLECTANCE_SCALING_FACTOR", "DLRTO8.REFLECTANCE_OFFSET", "HRCAL.RADIANCE_SCALING_FACTOR", "HRCAL.RADIANCE_OFFSET", "HRCAL.REFLECTANCE_SCALING_FACTOR", "HRCAL.REFLECTANCE_OFFSET", "HRORTHO.DTM_NAME", "HRORTHO.EXTORI_FILE_NAME", "HRORTHO.GEOMETRIC_CALIB_FILE_NAME", NULL }; for( int i = 0; apszKeywords[i] != NULL; i++ ) { const char *pszKeywordValue = poDS->GetKeyword( apszKeywords[i], NULL ); if( pszKeywordValue != NULL ) poDS->SetMetadataItem( apszKeywords[i], pszKeywordValue ); } } } if (bIsDTM && EQUAL( poDS->GetKeyword( "MAP.TARGET_NAME"), "MARS" )) { poDS->SetMetadataItem( "SPACECRAFT_NAME", "MARS_EXPRESS" ); poDS->SetMetadataItem( "PRODUCT_TYPE", "DTM"); static const char *apszKeywords[] = { "DTM.DTM_MISSING_DN", "DTM.DTM_OFFSET", "DTM.DTM_SCALING_FACTOR", "DTM.DTM_A_AXIS_RADIUS", "DTM.DTM_B_AXIS_RADIUS", "DTM.DTM_C_AXIS_RADIUS", "DTM.DTM_DESC", "DTM.DTM_MINIMUM_DN", "DTM.DTM_MAXIMUM_DN", NULL }; for( int i = 0; apszKeywords[i] != NULL; i++ ) { const char *pszKeywordValue = poDS->GetKeyword( apszKeywords[i] ); if( pszKeywordValue != NULL ) poDS->SetMetadataItem( apszKeywords[i], pszKeywordValue ); } } /****************** DAWN ******************************/ else if (EQUAL( poDS->GetKeyword( "INSTRUMENT_ID"), "FC2" )) { poDS->SetMetadataItem( "SPACECRAFT_NAME", "DAWN" ); static const char *apszKeywords[] = {"ORBIT_NUMBER","FILTER_NUMBER", "FRONT_DOOR_STATUS", "FIRST_LINE", "FIRST_LINE_SAMPLE", "PRODUCER_INSTITUTION_NAME", "SOURCE_FILE_NAME", "PROCESSING_LEVEL_ID", "TARGET_NAME", "LIMB_IN_IMAGE", "POLE_IN_IMAGE", "REFLECTANCE_SCALING_FACTOR", "SPICE_FILE_NAME", "SPACECRAFT_CENTRIC_LATITUDE", "SPACECRAFT_EASTERN_LONGITUDE", "FOOTPRINT_POSITIVE_LONGITUDE", NULL }; for( int i = 0; apszKeywords[i] != NULL; i++ ) { const char *pszKeywordValue = poDS->GetKeyword( apszKeywords[i] ); if( pszKeywordValue != NULL ) poDS->SetMetadataItem( apszKeywords[i], pszKeywordValue ); } } else if (bIsDTM && EQUAL( poDS->GetKeyword( "TARGET_NAME"), "VESTA" )) { poDS->SetMetadataItem( "SPACECRAFT_NAME", "DAWN" ); poDS->SetMetadataItem( "PRODUCT_TYPE", "DTM"); static const char *apszKeywords[] = { "DTM_MISSING_DN", "DTM_OFFSET", "DTM_SCALING_FACTOR", "DTM_A_AXIS_RADIUS", "DTM_B_AXIS_RADIUS", "DTM_C_AXIS_RADIUS", "DTM_MINIMUM_DN", "DTM_MAXIMUM_DN", "MAP_PROJECTION_TYPE", "COORDINATE_SYSTEM_NAME", "POSITIVE_LONGITUDE_DIRECTION", "MAP_SCALE", "CENTER_LONGITUDE", "LINE_PROJECTION_OFFSET", "SAMPLE_PROJECTION_OFFSET", NULL }; for( int i = 0; apszKeywords[i] != NULL; i++ ) { const char *pszKeywordValue = poDS->GetKeyword( apszKeywords[i] ); if( pszKeywordValue != NULL ) poDS->SetMetadataItem( apszKeywords[i], pszKeywordValue ); } } /* -------------------------------------------------------------------- */ /* END Instrument-specific keywords as metadata. */ /* -------------------------------------------------------------------- */ if (EQUAL(poDS->GetKeyword( "EOL"), "1" )) poDS->SetMetadataItem( "END-OF-DATASET_LABEL", "PRESENT" ); poDS->SetMetadataItem( "CONVERSION_DETAILS", "http://www.lpi.usra.edu/meetings/lpsc2014/pdf/1088.pdf" ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
IRaster* ingestGDALRaster() { GDALDataset* ds = gdalDataset; cout << "Reading raster metadata..."; GDALRasterBand* band = ds->GetRasterBand(bandNum); int xSize = band->GetXSize(); int ySize = band->GetYSize(); int hasNoDataValue; double noDataValue = band->GetNoDataValue(&hasNoDataValue); if (hasNoDataValue != 0) noDataValue = NULL_DOUBLE_; double xForm[6]; ds->GetGeoTransform(xForm); double minX = xForm[0]; double cellSizeX = xForm[1]; double skewX = xForm[2]; double minY = xForm[3]; double skewY = xForm[4]; double cellSizeY = xForm[5]; string* spatialRef = new string(ds->GetProjectionRef()); if( ds->GetMetadataItem("NC_GLOBAL#IOAPI_VERSION", "") != NULL) { // Get georeference from IOAPI metadata // See: http://www.baronams.com/products/ioapi/GRIDS.html#horiz // Build the affine transform from metadata minX = atof(ds->GetMetadataItem("NC_GLOBAL#XORIG", "")); minY = atof(ds->GetMetadataItem("NC_GLOBAL#YORIG", "")); cellSizeX = atof(ds->GetMetadataItem("NC_GLOBAL#XCELL", "")); cellSizeY = atof(ds->GetMetadataItem("NC_GLOBAL#YCELL", "")); skewX = 0; skewY = 0; // Build the SpatialReference double xcent, ycent, p_alp, p_bet, p_gam; char *gdnam; OGRSpatialReference* sref = new OGRSpatialReference(""); // Assume datum is WGS84 (may not be, but IO/API files don't (can't?) say...) sref->SetWellKnownGeogCS("WGS84"); int gdtyp = atoi(ds->GetMetadataItem("NC_GLOBAL#GDTYP", "")); switch(gdtyp) { case 0: // Unknown projection (we assume lat-lon) break; case 1: // LATGRD3 -- Latitude/longitude break; case 2: // LAMGRD3 -- Lambert Conformal Conic (two standard parallels) xcent = atof(ds->GetMetadataItem("NC_GLOBAL#XCENT", "")); ycent = atof(ds->GetMetadataItem("NC_GLOBAL#YCENT", "")); p_alp = atof(ds->GetMetadataItem("NC_GLOBAL#P_ALP", "")); p_bet = atof(ds->GetMetadataItem("NC_GLOBAL#P_BET", "")); sref->SetLCC(p_alp, p_bet, ycent, xcent, 0, 0); gdnam = (char *)ds->GetMetadataItem("NC_GLOBAL#GDNAM", ""); sref->SetProjCS(gdnam); break; case 9: // ALBGRD3 -- Albers Equal-Area Conic xcent = atof(ds->GetMetadataItem("NC_GLOBAL#XCENT", "")); ycent = atof(ds->GetMetadataItem("NC_GLOBAL#YCENT", "")); p_alp = atof(ds->GetMetadataItem("NC_GLOBAL#P_ALP", "")); p_bet = atof(ds->GetMetadataItem("NC_GLOBAL#P_BET", "")); sref->SetACEA(p_alp, p_bet, ycent, xcent, 0, 0); gdnam = (char *)ds->GetMetadataItem("NC_GLOBAL#GDNAM", ""); sref->SetProjCS(gdnam); break; case 10: // LEQGRID3 -- Lambert Azimuthal Equal-Area p_alp = atof(ds->GetMetadataItem("NC_GLOBAL#P_ALP", "")); // Correct for bad metadata on some files if(p_alp == 0.0) { xcent = atof(ds->GetMetadataItem("NC_GLOBAL#XCENT", "")); ycent = atof(ds->GetMetadataItem("NC_GLOBAL#YCENT", "")); p_alp = ycent; p_gam = xcent; } else { p_gam = atof(ds->GetMetadataItem("NC_GLOBAL#P_GAM", "")); } sref->SetLAEA(p_alp, p_gam, 0, 0); gdnam = (char *)ds->GetMetadataItem("NC_GLOBAL#GDNAM", ""); sref->SetProjCS(gdnam); break; default: throw new runtime_error("ERROR: Unable to parse IO/API GDTYP variable"); } char* wktSrStr = new char[spatialRef->length()]; strcpy((char *)spatialRef->c_str(), wktSrStr); sref->exportToWkt(&wktSrStr); //CPLFree(sref); spatialRef->assign(wktSrStr); } cout << "...Done.\nReading raster band " << bandNum << "..."; IRaster* result = NULL; CPLErr retval; switch (band->GetRasterDataType()) { //retval = band->RasterIO(GF_Read, 0, 0, band->XSize, band->YSize, floatArray, band->XSize, band->YSize, 0, 0); case GDT_Float32: { float* floatArray = new float[xSize * ySize]; retval = band->RasterIO(GF_Read, 0, 0, xSize, ySize, floatArray, xSize, ySize, band->GetRasterDataType(), 0, 0); if (retval != CE_None) throw new runtime_error("GDALRasterBand::ReadBlock() returned error"); result = new Raster<float>(floatArray, xSize, ySize, cellSizeX, cellSizeY, minX, minY, skewX, skewY, spatialRef, noDataValue); cout << " -- Pixel type: Float32 -- ...Done\n"; } break; case GDT_Float64: { double* doubleArray = new double[xSize * ySize]; retval = band->RasterIO(GF_Read, 0, 0, xSize, ySize, doubleArray, xSize, ySize, band->GetRasterDataType(), 0, 0); if (retval != CE_None) throw new runtime_error("GDALRasterBand::ReadBlock() returned error"); result = new Raster<double>(doubleArray, xSize, ySize, cellSizeX, cellSizeY, minX, minY, skewX, skewY, spatialRef, noDataValue); cout << " -- Pixel type: Float64 -- ...Done\n"; } break; case GDT_Int32: { int* intArray = new int[xSize * ySize]; retval = band->RasterIO(GF_Read, 0, 0, xSize, ySize, intArray, xSize, ySize, band->GetRasterDataType(), 0, 0); if (retval != CE_None) throw new runtime_error("GDALRasterBand::ReadBlock() returned error"); result = new Raster<int>(intArray, xSize, ySize, cellSizeX, cellSizeY, minX, minY, skewX, skewY, spatialRef, noDataValue); cout << " -- Pixel type: Int32 -- ...Done\n"; } break; case GDT_Int16: { short* shortArray = new short[xSize * ySize]; retval = band->RasterIO(GF_Read, 0, 0, xSize, ySize, shortArray, xSize, ySize, band->GetRasterDataType(), 0, 0); if (retval != CE_None) throw new runtime_error("GDALRasterBand::ReadBlock() returned error"); result = new Raster<short>(shortArray, xSize, ySize, cellSizeX, cellSizeY, minX, minY, skewX, skewY, spatialRef, noDataValue); cout << " -- Pixel type: Int32 -- ...Done\n"; } break; case GDT_Byte: { char* byteArray = new char[xSize * ySize]; retval = band->RasterIO(GF_Read, 0, 0, xSize, ySize, byteArray, xSize, ySize, band->GetRasterDataType(), 0, 0); if (retval != CE_None) throw new runtime_error("GDALRasterBand::ReadBlock() returned error"); result = new Raster<char>(byteArray, xSize, ySize, cellSizeX, cellSizeY, minX, minY, skewX, skewY, spatialRef, noDataValue); cout << " -- Pixel type: Byte -- ...Done\n"; } break; default: throw new runtime_error("Unsupported pixel type"); } return result; }
rspfString rspfOgcWktTranslator::fromOssimKwl(const rspfKeywordlist &kwl, const char *prefix)const { rspfString projType = kwl.find(rspfKeywordNames::TYPE_KW); rspfString datumType = kwl.find(rspfKeywordNames::DATUM_KW); rspfString wktString; OGRSpatialReference oSRS; if(projType == "") { return wktString; } rspfString zone = kwl.find(prefix, rspfKeywordNames::ZONE_KW); rspfString hemisphere = kwl.find(prefix, rspfKeywordNames::HEMISPHERE_KW); rspfString parallel1 = kwl.find(prefix, rspfKeywordNames::STD_PARALLEL_1_KW); rspfString parallel2 = kwl.find(prefix, rspfKeywordNames::STD_PARALLEL_2_KW); rspfString originLat = kwl.find(prefix, rspfKeywordNames::ORIGIN_LATITUDE_KW); rspfString centralMeridian = kwl.find(prefix, rspfKeywordNames::CENTRAL_MERIDIAN_KW); rspfString scale = kwl.find(prefix, rspfKeywordNames::SCALE_FACTOR_KW); rspfString pcsCode = kwl.find(prefix, rspfKeywordNames::PCS_CODE_KW); rspfDpt falseEastingNorthing; falseEastingNorthing.x = 0.0; falseEastingNorthing.y = 0.0; const char *lookup = kwl.find(prefix, rspfKeywordNames::FALSE_EASTING_NORTHING_UNITS_KW); if (lookup) { rspfUnitType units = static_cast<rspfUnitType>(rspfUnitTypeLut::instance()-> getEntryNumber(lookup)); lookup = kwl.find(prefix, rspfKeywordNames::FALSE_EASTING_NORTHING_KW); if (lookup) { rspfDpt eastingNorthing; eastingNorthing.toPoint(std::string(lookup)); switch (units) { case RSPF_METERS: { falseEastingNorthing = eastingNorthing; break; } case RSPF_FEET: case RSPF_US_SURVEY_FEET: { rspfUnitConversionTool ut; ut.setValue(eastingNorthing.x, units); falseEastingNorthing.x = ut.getValue(RSPF_METERS); ut.setValue(eastingNorthing.y, units); falseEastingNorthing.y = ut.getValue(RSPF_METERS); break; } default: { rspfNotify(rspfNotifyLevel_WARN) << "rspfOgcWktTranslator::fromOssimKwl WARNING!" << "Unhandled unit type for " << rspfKeywordNames::FALSE_EASTING_NORTHING_UNITS_KW << ": " << ( rspfUnitTypeLut::instance()-> getEntryString(units).c_str() ) << endl; break; } } // End of switch (units) } // End of if (FALSE_EASTING_NORTHING_KW) } // End of if (FALSE_EASTING_NORTHING_UNITS_KW) else { lookup = kwl.find(prefix, rspfKeywordNames::FALSE_EASTING_KW); if(lookup) { falseEastingNorthing.x = fabs(rspfString(lookup).toFloat64()); } lookup = kwl.find(prefix, rspfKeywordNames::FALSE_NORTHING_KW); if(lookup) { falseEastingNorthing.y = fabs(rspfString(lookup).toFloat64()); } } oSRS.SetLinearUnits("Meter", 1.0); int pcsCodeVal = (pcsCode.empty() == false) ? pcsCode.toInt() : EPSG_CODE_MAX; if(pcsCodeVal < EPSG_CODE_MAX) { rspfEpsgProjectionDatabase* proj_db = rspfEpsgProjectionDatabase::instance(); rspfString pcsCodeName = proj_db->findProjectionName(pcsCodeVal); if ( pcsCodeName.contains("HARN") && pcsCodeName.contains("_Feet") ) { rspfString feetStr("_Feet"); rspfString newPcsCodeName( pcsCodeName.before(feetStr).c_str() ); rspfString epsg_spec = proj_db->findProjectionCode(newPcsCodeName); rspf_uint32 new_code = epsg_spec.after(":").toUInt32(); if (new_code) pcsCodeVal = new_code; } oSRS.importFromEPSG( pcsCodeVal ); } else if(projType == "rspfUtmProjection") { #if 0 hemisphere = hemisphere.trim().upcase(); if(hemisphere != "") { oSRS.SetUTM(zone.toLong(), hemisphere != "S"); } else { oSRS.SetUTM(zone.toLong(), true); } #else short gcs = USER_DEFINED; if (datumType == "WGE") gcs = GCS_WGS_84; else if (datumType == "WGD") gcs = GCS_WGS_72; else if (datumType == "NAR-C") gcs = GCS_NAD83; else if (datumType == "NAR") gcs = GCS_NAD83; else if (datumType == "NAS-C") gcs = GCS_NAD27; else if (datumType == "NAS") gcs = GCS_NAD27; else if (datumType == "ADI-M") gcs = GCS_Adindan; else if (datumType == "ARF-M") gcs = GCS_Arc_1950; else if (datumType == "ARS-M") gcs = GCS_Arc_1960; else if (datumType == "EUR-7" || datumType == "EUR-M") gcs = GCS_ED50; else if ((datumType == "OGB-7") || (datumType == "OGB-M") || (datumType == "OGB-A") || (datumType == "OGB-B") || (datumType == "OGB-C") || (datumType == "OGB-D")) gcs = GCS_OSGB_1936; else if (datumType == "TOY-M") gcs = GCS_Tokyo; else { if(traceDebug()) { rspfNotify(rspfNotifyLevel_DEBUG) << "DATUM = " << datumType << " tag not written " << std::endl << "Please let us know so we can add it" << std::endl; } } int mapZone = zone.toInt(); hemisphere = hemisphere.trim().upcase(); bool bDoImportFromEPSG = false; switch ( gcs ) { case GCS_WGS_84: { if (hemisphere == "N") // Northern hemisphere. { pcsCodeVal = 32600 + mapZone; } else // Southern hemisphere. { pcsCodeVal = 32700 + mapZone; } bDoImportFromEPSG = true; break; } case GCS_WGS_72: { if (hemisphere == "N") // Northern hemisphere. { pcsCodeVal = 32200 + mapZone; } else // Southern hemisphere. { pcsCodeVal = 32300 + mapZone; } bDoImportFromEPSG = true; break; } case GCS_NAD27: { if (hemisphere == "N") // Northern hemisphere. { pcsCodeVal = 26700 + mapZone; } else // Southern hemisphere. { pcsCodeVal = 32000 + mapZone; } bDoImportFromEPSG = true; break; } case GCS_NAD83: { if (hemisphere == "N") // Northern hemisphere. { pcsCodeVal = 26900 + mapZone; } else // Southern hemisphere. { pcsCodeVal = 32100 + mapZone; } bDoImportFromEPSG = true; break; } default: { if (mapZone > 0) // Northern hemisphere. { pcsCodeVal = 16000 + mapZone; } else if (mapZone < 0) // Southern hemisphere. { hemisphere = "S"; pcsCodeVal = 16100 + abs(mapZone); } break; } } // End of "switch ( gcs )" if ( bDoImportFromEPSG == true ) oSRS.importFromEPSG( pcsCodeVal ); else { if(hemisphere != "") { oSRS.SetUTM(zone.toLong(), hemisphere != "S"); } else { oSRS.SetUTM(zone.toLong(), true); } } #endif } else if(projType == "rspfLlxyProjection") { OGRSpatialReference oGeogCS; oGeogCS.SetEquirectangular(0.0, 0.0, 0.0, 0.0); oGeogCS.SetAngularUnits(SRS_UA_DEGREE, atof(SRS_UA_DEGREE_CONV)); oSRS.CopyGeogCSFrom( &oGeogCS ); } else if(projType == "rspfEquDistCylProjection") { OGRSpatialReference oGeogCS; oGeogCS.SetEquirectangular(originLat.toDouble(), centralMeridian.toDouble(), falseEastingNorthing.x, falseEastingNorthing.y); oGeogCS.SetAngularUnits(SRS_UA_DEGREE, atof(SRS_UA_DEGREE_CONV)); oSRS.CopyGeogCSFrom( &oGeogCS ); } else if(projType == "rspfSinusoidalProjection") { oSRS.SetSinusoidal(centralMeridian.toDouble(), falseEastingNorthing.x, falseEastingNorthing.y); } else if(projType == "rspfCylEquAreaProjection") { oSRS.SetCEA(originLat.toDouble(), centralMeridian.toDouble(), falseEastingNorthing.x, falseEastingNorthing.y); } else if(projType == "rspfCassiniProjection") { oSRS.SetCS(originLat.toDouble(), centralMeridian.toDouble(), falseEastingNorthing.x, falseEastingNorthing.y); } else if(projType == "rspfAlbersProjection") { oSRS.SetACEA(parallel1.toDouble(), parallel2.toDouble(), originLat.toDouble(), centralMeridian.toDouble(), falseEastingNorthing.x, falseEastingNorthing.y); } else if(projType == "rspfAzimEquDistProjection") { oSRS.SetAE(originLat.toDouble(), centralMeridian.toDouble(), falseEastingNorthing.x, falseEastingNorthing.y); } else if(projType == "rspfEckert4Projection") { oSRS.SetEckertIV(centralMeridian.toDouble(), falseEastingNorthing.x, falseEastingNorthing.y); } else if(projType == "rspfEckert6Projection") { oSRS.SetEckertVI(centralMeridian.toDouble(), falseEastingNorthing.x, falseEastingNorthing.y); } else if(projType == "rspfGnomonicProjection") { oSRS.SetGnomonic(originLat.toDouble(), centralMeridian.toDouble(), falseEastingNorthing.x, falseEastingNorthing.y); } else if(projType == "rspfLambertConformalConicProjection") { oSRS.SetLCC(parallel1.toDouble(), parallel2.toDouble(), originLat.toDouble(), centralMeridian.toDouble(), falseEastingNorthing.x, falseEastingNorthing.y); } else if(projType == "rspfVanDerGrintenProjection") { oSRS.SetVDG(centralMeridian.toDouble(), falseEastingNorthing.x, falseEastingNorthing.y); } else if(projType == "rspfMillerProjection") { oSRS.SetMC(originLat.toDouble(), centralMeridian.toDouble(), falseEastingNorthing.x, falseEastingNorthing.y); } else if(projType == "rspfMercatorProjection") { oSRS.SetMercator(originLat.toDouble(), centralMeridian.toDouble(), scale.toDouble(), falseEastingNorthing.x, falseEastingNorthing.y); } else if(projType == "rspfMollweidProjection") { oSRS.SetMollweide(centralMeridian.toDouble(), falseEastingNorthing.x, falseEastingNorthing.y); } else if(projType == "rspfNewZealandMapGridProjection") { oSRS.SetNZMG(originLat.toDouble(), centralMeridian.toDouble(), falseEastingNorthing.x, falseEastingNorthing.y); } else if(projType == "rspfOrthoGraphicProjection") { oSRS.SetOrthographic(originLat.toDouble(), centralMeridian.toDouble(), falseEastingNorthing.x, falseEastingNorthing.y); } else if(projType == "rspfPolarStereoProjection") { oSRS.SetPS(originLat.toDouble(), centralMeridian.toDouble(), scale.toDouble(), falseEastingNorthing.x, falseEastingNorthing.y); } else if(projType == "rspfPolyconicProjectio") { oSRS.SetPolyconic(originLat.toDouble(), centralMeridian.toDouble(), falseEastingNorthing.x, falseEastingNorthing.y); } else if(projType == "rspfStereographicProjection") { oSRS.SetStereographic(originLat.toDouble(), centralMeridian.toDouble(), scale.toDouble(), falseEastingNorthing.x, falseEastingNorthing.y); } else if(projType == "rspfTransMercatorProjection") { oSRS.SetTM(originLat.toDouble(), centralMeridian.toDouble(), scale.toDouble(), falseEastingNorthing.x, falseEastingNorthing.y); } else { cerr << "rspfOgcWktTranslator::fromOssimKwl:\n" << "Projection translation for " << projType << " not supported " << endl; } if(pcsCodeVal >= EPSG_CODE_MAX) { datumType = datumType.upcase(); if(datumType == "WGE") { oSRS.SetWellKnownGeogCS("WGS84"); } else if(datumType == "WGD") { oSRS.SetWellKnownGeogCS("WGS72"); } else if(datumType == "NAS-C") //1927 { oSRS.SetWellKnownGeogCS("NAD27"); } else if(datumType == "NAS") //1927 { oSRS.SetWellKnownGeogCS("NAD27"); } else if(datumType == "NAR-C") // 1983 { oSRS.SetWellKnownGeogCS("NAD83"); } else if(datumType == "NAR") // 1983 { oSRS.SetWellKnownGeogCS("NAD83"); } else if(datumType == "NTF") { oSRS.SetWellKnownGeogCS("EPSG:4275"); } else { cerr << "rspfOgcWktTranslator::fromOssimKwl: Datum translation for " << datumType <<" not supported" << endl; } } char* exportString = NULL; oSRS.exportToWkt(&exportString); if(exportString) { wktString = exportString; OGRFree(exportString); } return wktString; }