void GRIBDataset::SetGribMetaData(grib_MetaData* meta) { nRasterXSize = meta->gds.Nx; nRasterYSize = meta->gds.Ny; /* -------------------------------------------------------------------- */ /* Image projection. */ /* -------------------------------------------------------------------- */ OGRSpatialReference oSRS; switch(meta->gds.projType) { case GS3_LATLON: case GS3_GAUSSIAN_LATLON: // No projection, only latlon system (geographic) break; case GS3_MERCATOR: oSRS.SetMercator(meta->gds.meshLat, meta->gds.orientLon, 1.0, 0.0, 0.0); break; case GS3_POLAR: oSRS.SetPS(meta->gds.meshLat, meta->gds.orientLon, meta->gds.scaleLat1, 0.0, 0.0); break; case GS3_LAMBERT: oSRS.SetLCC(meta->gds.scaleLat1, meta->gds.scaleLat2, 0.0, meta->gds.orientLon, 0.0, 0.0); // set projection break; case GS3_ORTHOGRAPHIC: //oSRS.SetOrthographic(0.0, meta->gds.orientLon, // meta->gds.lon2, meta->gds.lat2); //oSRS.SetGEOS(meta->gds.orientLon, meta->gds.stretchFactor, meta->gds.lon2, meta->gds.lat2); oSRS.SetGEOS( 0, 35785831, 0, 0 ); // hardcoded for now, I don't know yet how to parse the meta->gds section break; case GS3_EQUATOR_EQUIDIST: break; case GS3_AZIMUTH_RANGE: break; } /* -------------------------------------------------------------------- */ /* Earth model */ /* -------------------------------------------------------------------- */ double a = meta->gds.majEarth * 1000.0; // in meters double b = meta->gds.minEarth * 1000.0; if( a == 0 && b == 0 ) { a = 6377563.396; b = 6356256.910; } if (meta->gds.f_sphere) { oSRS.SetGeogCS( "Coordinate System imported from GRIB file", NULL, "Sphere", a, 0.0 ); } else { double fInv = a/(a-b); oSRS.SetGeogCS( "Coordinate System imported from GRIB file", NULL, "Spheroid imported from GRIB file", a, fInv ); } OGRSpatialReference oLL; // construct the "geographic" part of oSRS oLL.CopyGeogCSFrom( &oSRS ); double rMinX; double rMaxY; double rPixelSizeX; double rPixelSizeY; if (meta->gds.projType == GS3_ORTHOGRAPHIC) { //rMinX = -meta->gds.Dx * (meta->gds.Nx / 2); // This is what should work, but it doesn't .. Dx seems to have an inverse relation with pixel size //rMaxY = meta->gds.Dy * (meta->gds.Ny / 2); const double geosExtentInMeters = 11137496.552; // hardcoded for now, assumption: GEOS projection, full disc (like MSG) rMinX = -(geosExtentInMeters / 2); rMaxY = geosExtentInMeters / 2; rPixelSizeX = geosExtentInMeters / meta->gds.Nx; rPixelSizeY = geosExtentInMeters / meta->gds.Ny; } else if( oSRS.IsProjected() ) { rMinX = meta->gds.lon1; // longitude in degrees, to be transformed to meters (or degrees in case of latlon) rMaxY = meta->gds.lat1; // latitude in degrees, to be transformed to meters OGRCoordinateTransformation *poTransformLLtoSRS = OGRCreateCoordinateTransformation( &(oLL), &(oSRS) ); if ((poTransformLLtoSRS != NULL) && poTransformLLtoSRS->Transform( 1, &rMinX, &rMaxY )) // transform it to meters { if (meta->gds.scan == GRIB2BIT_2) // Y is minY, GDAL wants maxY rMaxY += (meta->gds.Ny - 1) * meta->gds.Dy; // -1 because we GDAL needs the coordinates of the centre of the pixel rPixelSizeX = meta->gds.Dx; rPixelSizeY = meta->gds.Dy; } else { rMinX = 0.0; rMaxY = 0.0; rPixelSizeX = 1.0; rPixelSizeY = -1.0; oSRS.Clear(); CPLError( CE_Warning, CPLE_AppDefined, "Unable to perform coordinate transformations, so the correct\n" "projected geotransform could not be deduced from the lat/long\n" "control points. Defaulting to ungeoreferenced." ); } delete poTransformLLtoSRS; } else { rMinX = meta->gds.lon1; // longitude in degrees, to be transformed to meters (or degrees in case of latlon) rMaxY = meta->gds.lat1; // latitude in degrees, to be transformed to meters if (meta->gds.lat2 > rMaxY) rMaxY = meta->gds.lat2; rPixelSizeX = meta->gds.Dx; rPixelSizeY = meta->gds.Dy; } adfGeoTransform[0] = rMinX; adfGeoTransform[3] = rMaxY; adfGeoTransform[1] = rPixelSizeX; adfGeoTransform[5] = -rPixelSizeY; CPLFree( pszProjection ); pszProjection = NULL; oSRS.exportToWkt( &(pszProjection) ); }
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; }