//*************************************************************************************************
//! 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;
}
Exemple #2
0
//*************************************************************************************************
//! Populates the database with contents of DB files as specified in ossim_preferences.
//*************************************************************************************************
void ossimEpsgProjectionDatabase::initialize()
{
   // Fetch filenames of all projection DB files specified in ossim_preferences:
   ossimString regEx =  ossimString("^epsg_database_file[0-9]+");
   std::vector<ossimString> keys = 
      ossimPreferences::instance()->preferencesKWL().getSubstringKeyList(regEx);
   std::vector<ossimString>::const_iterator i = keys.begin();

   // Create only once outside the loop:
   ossimFilename db_name;
   ossimString group_id;
   ossimString format_id;
   ossimString line;
   DbEntry file_record;

   // Loop over each file and read contents into memory:
   while ( i != keys.end() )
   {
      db_name = ossimPreferences::instance()->preferencesKWL().find( (*i).c_str() );
      ++i;
      if (!db_name.isReadable())
         continue;

      // Open the DB file:
      std::ifstream db_stream (db_name.chars());
      bool good_file = false;
      if (db_stream.good())
      {
         // Format specification implied in file's magic number:
         std::getline(db_stream, format_id);
         format_id.trim();
         if ((format_id == EPSG_DB_FORMAT_A) || 
             (format_id == STATE_PLANE_FORMAT_B) ||
             (format_id == SPCS_EPSG_MAP_FORMAT_C) ||
             (format_id == WKT_PCS_FORMAT_D))
            good_file = true;
      }
      if (!good_file)
      {
         ossimNotify(ossimNotifyLevel_WARN)<<"ossimEpsgProjectionDatabase::initialize() -- "
            "Encountered bad database file <"<<db_name<<">. Skipping this file."<<endl;
         db_stream.close();
         continue;
      }

      // The file is good. Skip over the column descriptor line:
      std::getline(db_stream, line);
      file_record.clear();

      // Loop to read all data records:
      while (!db_stream.eof())
      {
         std::getline(db_stream, line);
         file_record = line.explode(","); // ONLY CSV FILES CONSIDERED HERE
         if (file_record.size())
         {
            ossimRefPtr<ossimMapProjection> proj;
            ProjRecord proj_record;

            // Check if primary EPSG database format A:
            if (format_id == EPSG_DB_FORMAT_A)
            {
               proj = createProjFromFormatARecord(file_record, proj_record.datumValid);
               proj_record.code = file_record[A_CODE].toUInt32();
               proj_record.name = file_record[A_NAME];
            }

            // Check if State Plane (subset of EPSG but handled differently until projection 
            // geotrans-EPSG disconnect is resolved. 
            else if (format_id == STATE_PLANE_FORMAT_B)
            {
               proj = createProjFromFormatBRecord(file_record);
               proj_record.code = file_record[B_CODE].toUInt32();
               proj_record.name = file_record[B_NAME];
               proj_record.datumValid = true;
            }

            // This format is for Ming-special State Plane Coordinate System coded format.
            // This format is simply a mapping from SPCS spec name (OSSIM-specific) to EPSG code.
            // Note that no proj is instantiated and no KWL is populated. Only name and EPSG mapped
            // code is saved.
            else if (format_id == SPCS_EPSG_MAP_FORMAT_C)
            {
               proj_record.code = file_record[C_CODE].toUInt32();
               proj_record.name = file_record[C_NAME];
               m_projDatabase.push_back(proj_record);
            }

            // This format is for alternate projection naming scheme database CSV file format.
            // WKT_PCS coding is an alternate naming scheme that maps to EPSG.
            // Note that no proj is instantiated and no KWL is populated. Only name and EPSG mapped
            // code is saved.
            else if (format_id == WKT_PCS_FORMAT_D)
            {
               proj_record.code = file_record[D_CODE].toUInt32();
               proj_record.name = file_record[D_NAME];
               m_projDatabase.push_back(proj_record);
            }

            if (proj.valid() && proj_record.datumValid)
            {
               // Serialize the projection to a KWL and stick it in the in-memory database:
               proj->saveState(proj_record.kwl);
               m_projDatabase.push_back(proj_record);
            }
         }
      }

      db_stream.close();
   } // end of while loop over all DB files
}