//************************************************************************************************* //! 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; }
//************************************************************************************************* //! 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 }