//************************************************************************************************* //! Returns a projection corresponding to the group (e.g., "EPSG") and PCS code provided, //! or NULL if no entry found. //************************************************************************************************* ossimProjection* ossimEpsgProjectionDatabase::findProjection(ossim_uint32 epsg_code) const { ossimMapProjection* proj = 0; // Quick check for bogus EPSG: if ((epsg_code == 0) || (epsg_code == 32767)) return 0; // Check for Google projection: else if (epsg_code == 900913) { const ossimDatum* datum = ossimDatumFactory::instance()->create(ossimString("6055")); ossimMercatorProjection* merc_proj = new ossimMercatorProjection(); ossimGpt origin(0.0,0.0,0.0, datum); merc_proj->setFalseEasting(0.0); merc_proj->setFalseNorthing(0.0); merc_proj->setOrigin(origin); // Also sets the projections datum to the origin's datum merc_proj->update(); merc_proj->setPcsCode(900913); proj = merc_proj; } else { // Search database for entry: std::multimap<ossim_uint32, ossimRefPtr<ProjDbRecord> >::iterator db_iter = m_projDatabase.find(epsg_code); if (db_iter != m_projDatabase.end()) { // See if a projection has already been created for this entry: ProjDbRecord* db_record = db_iter->second.get(); if (db_record->proj.valid()) proj = (ossimMapProjection*) db_record->proj->dup(); else { // Try decoding the EPSG code before accessing DB: proj = createProjFromUtmCode(epsg_code); if (proj) { db_record->proj = proj; db_record->datumValid = true; } else if (db_iter->second->csvFormat == FORMAT_A) proj = createProjFromFormatARecord(db_record); else if (db_iter->second->csvFormat == FORMAT_B) proj = createProjFromFormatBRecord(db_record); if (proj) { // To save allocated memory, get rid of the original CSV entry since a real // projection is now represented in the database: db_record->csvRecord.clear(); db_record->csvFormat = NOT_ASSIGNED; } } } } return proj; }
//************************************************************************************************* //! This method is invoked to parse the Db record and produce a projection (or NULL if spec invalid) // // LIMITATION: Currently not parsing the datum info from the EPSG database file due to disconnect // with current ossimDatumFactory. Setting to default WGS84 with warning message. //************************************************************************************************* ossimMapProjection* ossimEpsgProjectionDatabase::createProjFromFormatARecord(const DbEntry& record, bool& datum_valid) const { // Establish EPSG code and test for UTM (full projection is implied in the code itself -- no // accessing the database). Until the database is solidified, it is probably better to do // it this way: datum_valid = true; ossim_uint32 pcs_code = record[A_CODE].toUInt32(); ossimMapProjection* proj = createProjFromUtmCode(pcs_code); if (proj) return proj; // Establish the units in which the easting/northing is provided: double mtrs_per_unit = 1.0; if (record[A_UNITS] == "US survey foot") mtrs_per_unit = US_METERS_PER_FT; else if (record[A_UNITS].contains("foot")) // THIS IS INTERNATIONAL FOOT, NOT EXACT FOR MANY INTERNATIONAL VARIETIES mtrs_per_unit = MTRS_PER_FT; else if (!record[A_UNITS].contains("metre") || (record[A_UNITS] == "kilometre")) { // ### SKIP THIS MESSAGE BUT BE AWARE THAT THIS PROJECTION WON'T BE REPRESENTED IN DB ### //ossimNotify(ossimNotifyLevel_WARN)<<MODULE<<"EPSG:"<<pcs_code<<" units of <" // <<record[A_UNITS]<<"> not presently supported."<<endl; return 0; } // First create a datum given the datum code in the record: ossim_uint32 gcs_code = record[A_DATUM_CODE].toUInt32(); const ossimDatum* datum = ossimEpsgDatumFactory::instance()->create(gcs_code); if (!datum) { // Default to WGS 84 -- this may throw an exception: datum = ossimEpsgDatumFactory::instance()->create(ossimString("EPSG:4326")); datum_valid = false; } const ossimEllipsoid* ellipsoid = datum->ellipsoid(); ossimGpt origin(0,0,0); ossimString proj_type = record[A_PROJ_TYPE]; if (proj_type.contains("Transverse Mercator")) { origin.lat = decodeSexagesimalDms(record[A_NAT_ORG_LAT]); origin.lon = decodeSexagesimalDms(record[A_NAT_ORG_LON]); double fe = mtrs_per_unit*record[A_FALSE_EASTING].toDouble(); double fn = mtrs_per_unit*record[A_FALSE_NORTHING].toDouble(); double sf = record[A_NAT_ORG_SCALE].toDouble(); proj = new ossimTransMercatorProjection(*ellipsoid, origin, fe, fn, sf); } else if (proj_type.contains("Lambert Conic Conformal (1SP)")) { origin.lat = decodeSexagesimalDms(record[A_NAT_ORG_LAT]); origin.lon = decodeSexagesimalDms(record[A_NAT_ORG_LON]); double fe = mtrs_per_unit*record[A_FALSE_EASTING].toDouble(); double fn = mtrs_per_unit*record[A_FALSE_NORTHING].toDouble(); proj = new ossimLambertConformalConicProjection(*ellipsoid, origin, origin.lat, origin.lat, fe, fn); } else if (proj_type.contains("Lambert Conic Conformal (2SP)")) { origin.lat = decodeSexagesimalDms(record[A_FALSE_ORG_LAT]); origin.lon = decodeSexagesimalDms(record[A_FALSE_ORG_LON]); double p1 = decodeSexagesimalDms(record[A_STD_PARL_1_LAT]); double p2 = decodeSexagesimalDms(record[A_STD_PARL_2_LAT]); double fe = mtrs_per_unit*record[A_FALSE_ORG_EASTING].toDouble(); double fn = mtrs_per_unit*record[A_FALSE_ORG_NORTHING].toDouble(); proj = new ossimLambertConformalConicProjection(*ellipsoid, origin, p1, p2, fe, fn); } else if (proj_type.contains("Cassini")) { origin.lat = decodeSexagesimalDms(record[A_NAT_ORG_LAT]); origin.lon = decodeSexagesimalDms(record[A_NAT_ORG_LON]); double fe = mtrs_per_unit*record[A_FALSE_EASTING].toDouble(); double fn = mtrs_per_unit*record[A_FALSE_NORTHING].toDouble(); proj = new ossimCassiniProjection(*ellipsoid, origin, fe, fn); } else if (proj_type.contains("Mercator (1SP)")) { origin.lat = decodeSexagesimalDms(record[A_NAT_ORG_LAT]); origin.lon = decodeSexagesimalDms(record[A_NAT_ORG_LON]); double fe = mtrs_per_unit*record[A_FALSE_EASTING].toDouble(); double fn = mtrs_per_unit*record[A_FALSE_NORTHING].toDouble(); double sf = record[A_NAT_ORG_SCALE].toDouble(); proj = new ossimMercatorProjection(*ellipsoid, origin, fe, fn, sf); } else if (proj_type.contains("Albers")) { origin.lat = decodeSexagesimalDms(record[A_FALSE_ORG_LAT]); origin.lon = decodeSexagesimalDms(record[A_FALSE_ORG_LON]); double p1 = decodeSexagesimalDms(record[A_STD_PARL_1_LAT]); double p2 = decodeSexagesimalDms(record[A_STD_PARL_2_LAT]); double fe = mtrs_per_unit*record[A_FALSE_ORG_EASTING].toDouble(); double fn = mtrs_per_unit*record[A_FALSE_ORG_NORTHING].toDouble(); proj = new ossimAlbersProjection(*ellipsoid, origin, p1, p2, fe, fn); } else if (proj_type.contains("Equidistant Cylindrical")) { origin.lat = decodeSexagesimalDms(record[A_STD_PARL_1_LAT]); origin.lon = decodeSexagesimalDms(record[A_NAT_ORG_LON]); double fe = mtrs_per_unit*record[A_FALSE_EASTING].toDouble(); double fn = mtrs_per_unit*record[A_FALSE_NORTHING].toDouble(); proj = new ossimEquDistCylProjection(*ellipsoid, origin, fe, fn); } else if (proj_type.contains("New Zealand Map Grid")) { origin.lat = decodeSexagesimalDms(record[A_NAT_ORG_LAT]); origin.lon = decodeSexagesimalDms(record[A_NAT_ORG_LON]); double fe = mtrs_per_unit*record[A_FALSE_EASTING].toDouble(); double fn = mtrs_per_unit*record[A_FALSE_NORTHING].toDouble(); ossimNewZealandMapGridProjection* nz_proj = new ossimNewZealandMapGridProjection; nz_proj->setOrigin(origin); nz_proj->setFalseEastingNorthing(fe, fn); proj = nz_proj; } else { // Can't handle it now. //ossimNotify(ossimNotifyLevel_FATAL)<<MODULE<<"EPSG:"<<record[A_CODE]<<" \""<<proj_type<<"\" " // "not presently supported. Returning NULL projection..."<<endl; return 0; } proj->setDatum(datum); proj->setPcsCode(pcs_code); return proj; }