//*************************************************************************************************
//! 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;
}
Пример #2
0
//*************************************************************************************************
//! 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;
}