//*************************************************************************************************
//! Returns a projection corresponding to the group (e.g., "EPSG") and PCS code provided, 
//! or NULL if no entry found.
//*************************************************************************************************
ossimProjection* ossimEpsgProjectionDatabase::findProjection(const ossimString& spec) const
{
   ossimProjection* proj = 0;

   // Use the CRS code to access the database. The spec should be <group>:<code> where <group> is 
   // "EPSG" (the only group handled here):
   ossim_uint32 spec_code;
   ossimString spec_group ("epsg"); // default if only integer code provided
   if (spec.contains(":"))
   {
      spec_group = spec.before(":");
      spec_code = spec.after(":").toUInt32();
      spec_group = spec_group.downcase();
   }
   else
   {
      spec_code = spec.toUInt32();
   }

   // Presently only EPSG database is handled:
   if ((spec_code != 0) && (spec_group == "epsg"))
      return findProjection(spec_code);

   // The spec is probably a projection name. Need to search Db
   // by the projection name. Search database for entry. The spec may use different delimiters than
   // the DB so need to split the strings and compare the words:
   ossimString separators ("_ /()");
   vector<ossimString> split_spec = spec.split(separators, true);
   vector<ossimString> split_db_name;
   ossimRefPtr<ossimMapProjection> map_proj = 0;
   std::multimap<ossim_uint32, ossimRefPtr<ProjDbRecord> >::iterator db_iter = m_projDatabase.begin();
   while ((db_iter != m_projDatabase.end()) && !proj)
   {
      ProjDbRecord* db_record = db_iter->second.get();
      split_db_name.clear();
      split_db_name = db_record->name.split(separators, true);
      if (split_spec == split_db_name)
      {
         // We may already have instantiated this projection, in which case just return its copy.
         // Otherwise, create the projection from the EPSG code that corresponds to the name:
         if (db_record->proj.valid())
            proj = (ossimMapProjection*) db_record->proj->dup();
         else
            proj = findProjection(db_record->code);
         return proj;
      }
      db_iter++;
   }
    
   // No hit? Could be that just a datum was identified, in which case we need a simple 
   // Platte Carree:
   const ossimDatum* datum = ossimDatumFactoryRegistry::instance()->create(spec);
   if (datum)
   {
      ossimEquDistCylProjection* proj = new ossimEquDistCylProjection(*(datum->ellipsoid()));
      proj->setDatum(datum);
      proj->setPcsCode(spec_code);
      return proj;
   }

   return 0;
}
Esempio n. 2
0
//*************************************************************************************************
//! Returns a projection corresponding to the group (e.g., "EPSG") and PCS code provided, 
//! or NULL if no entry found.
//*************************************************************************************************
ossimProjection* ossimEpsgProjectionDatabase::findProjection(const ossimString& spec) const
{
   ossimProjection* proj = 0;

   // Use the CRS code to access the database. The spec should be <group>:<code> where <group> is 
   // "EPSG" (the only group handled here):
   ossim_uint32 spec_code;
   ossimString spec_group ("epsg"); // default if only integer code provided
   if (spec.contains(":"))
   {
      spec_group = spec.before(":");
      spec_code = spec.after(":").toUInt32();
      spec_group = spec_group.downcase();
   }
   else
   {
      spec_code = spec.toUInt32();
   }
   if(spec_code == 4326)
   {
      return new ossimEquDistCylProjection();
   }
   // Presently only EPSG database is handled:
   if (spec_code != 0)
   {
      if (spec_group != "epsg")
         return 0;
      proj = findProjection(spec_code);
      if (proj)
         return proj;
   }

   // spec_code = 0 indicates that the spec is probably a projection name. Need to search Db
   // by the projection name. Search database for entry:
   ossimRefPtr<ossimMapProjection> map_proj = 0;
   ossimMapProjectionFactory* factory = ossimMapProjectionFactory::instance();
   std::vector<ProjRecord>::const_iterator db_iter = m_projDatabase.begin();
   while ((db_iter != m_projDatabase.end()) && !proj)
   {
      if (db_iter->name == spec)
      {
         // We have a match, instantiate the projection from the associated KWL in the DB. Trick
         // the registry into using appropriate factory by setting PCS code temporarily to 0 to
         // avoid infinite recursion:
         checkForUnhandledDatum(*db_iter);
         if (db_iter->kwl.getSize() > 0)
         {
            ossimKeywordlist proj_kwl (db_iter->kwl); // make copy since this is a const method
            proj_kwl.remove(ossimKeywordNames::PCS_CODE_KW);
            map_proj = PTR_CAST(ossimMapProjection, factory->createProjection(proj_kwl));
            if (map_proj.valid())
            {
               map_proj->setPcsCode(db_iter->code);
               proj = (ossimProjection*) map_proj->dup();
            }
         }
         else
         {
            // An empty KWL indicates the record is simply a map to another EPSG Db entry:
            proj = findProjection(db_iter->code);
         }
      }
      db_iter++;
   }
   if (proj)
      return proj;
    
   // No hit? Could be that just a datum was identified, in which case we need a simple 
   // Platte Carrée:
   const ossimDatum* datum = ossimDatumFactoryRegistry::instance()->create(spec);
   if (datum)
   {
      ossimEquDistCylProjection* proj = new ossimEquDistCylProjection(*(datum->ellipsoid()));
      proj->setDatum(datum);
      proj->setPcsCode(spec_code);
      return proj;
   }

   return 0;
}