//*************************************************************************************************
//! Given a projection instance, this method determines the corresponding EPSG code. Obviously
//! this is only needed if the projection does not have its PCS code assigned (it is NULL). This
//! happens when the projection was constructed with full parameters instead of the EPSG code.
//! Returns integer EPSG code if match was found or 0 if not found.
//*************************************************************************************************
ossim_uint32 
ossimEpsgProjectionDatabase::findProjectionCode(const ossimMapProjection& lost_proj) const
{
   ossimString lost_type (lost_proj.getClassName());

   // Shortcut for EPSG:4326 (WGS-85 geographic rectangular -- very common):
   if ((lost_type == "ossimEquDistCylProjection") && (lost_proj.getDatum()->epsgCode() == 6326))
      return 4326;

   ossim_uint32 found_code = 0;
   if (lost_type == "ossimUtmProjection")
   {
      found_code = getCodeFromUtmProj(dynamic_cast<const ossimUtmProjection*>(&lost_proj));
      if (found_code)
         return found_code;
   }

   if (m_projDatabase.empty())
      initialize();
   ossimString lookup;
   std::multimap<ossim_uint32, ossimRefPtr<ProjDbRecord> >::iterator db_iter =
      m_projDatabase.begin();
   while ((db_iter != m_projDatabase.end()) && (found_code == 0))
   {
      ossimRefPtr<ProjDbRecord> db_record = db_iter->second;
      if ( db_record.valid() )
      {
         // Has a projection already been created for this db iter?
         if (!db_record->proj.valid())
         {
            // No projection has been created yet for this DB entry. 
            // NOTE: THIS IS VERY SLOW BECAUSE WE ARE INSTANTIATING EVERY PROJECTION IN THE DB!!!
            db_record->proj = dynamic_cast<ossimMapProjection*>(findProjection(db_record->code));
         }
         if (db_record->proj.valid() && (*(db_record->proj.get()) == lost_proj))
         {
            found_code = db_record->code;
            
            // Hack to remap projection code 4087 to 4326 (which is not really a projection 
            // code but other packages like to see 4326 for geographic projections.
            // Hacked under protest (OLK, 08/2010)
            if (found_code == 4087)
               found_code = 4326;
         }
      }
      ++db_iter;
   }
   return found_code;
}
 void findProjection(int varindex, map<Value, Cost> &delta) {
     findProjection(*graph, cost, varindex, delta);
 }
//*************************************************************************************************
//! 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;
}
Example #4
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;
}