OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimFgdcTxtDoc.cpp
Go to the documentation of this file.
1 //----------------------------------------------------------------------------
2 //
3 // File ossimFgdcTxtDoc.cpp
4 //
5 // License: LGPL
6 //
7 // See LICENSE.txt file in the top level directory for more details.
8 //
9 // Author: David Burken
10 //
11 // Description: ossimFgdcTxtDoc class definition.
12 //
13 // FGDC = "Federal Geographic Data Committee"
14 //
15 // See: http://www.fgdc.gov/
16 //
17 //----------------------------------------------------------------------------
18 
22 #include <ossim/base/ossimNotify.h>
23 #include <ossim/base/ossimString.h>
25 #include <fstream>
26 #include <iostream>
27 #include <string>
28 #include <vector>
29 
30 static const std::string ALTITUDE_DISTANCE_UNITS_KW = "altitude_distance_units";
31 static const std::string FGDC_FILE_KW = "fgdc_file";
32 static const std::string FGDC_VERSION_KW = "fgdc_version";
33 static const std::string FGDC_VERSION_001_1998 = "FGDC-STD-001-1998";
34 
36  : m_kwl( new ossimKeywordlist() )
37 {
38 }
39 
41 {
42  m_kwl = 0; // Not a leak, m_kwl is a ossimRefPtr.
43 }
44 
46 {
47  bool result = false;
48 
49  // Open the file:
50  std::ifstream str( file.c_str(), std::ios_base::in );
51 
52  if ( str.good() )
53  {
54  std::string key = "Metadata_Standard_Version";
55  std::string value;
56  if ( findKey( str, true, key, value ) )
57  {
58  if ( value == FGDC_VERSION_001_1998 )
59  {
60  result = true;
61  m_kwl->addPair( FGDC_VERSION_KW, value );
62  m_kwl->addPair( FGDC_FILE_KW, file.string() );
63 
64  // Store for getAltitudeDistanceUnits() method if key found.
65  key = "Altitude_Distance_Units";
66  if ( findKey( str, false, key, value ) )
67  {
68  m_kwl->addPair( ALTITUDE_DISTANCE_UNITS_KW, value );
69  }
70  }
71  }
72  }
73 
74  return result;
75 }
76 
78 {
79  m_kwl->clear();
80 }
81 
83 {
84  static const char M[] = "ossimFgdcTxtDoc::getProjection";
85 
86  try
87  {
88  // Get the file name:
89  std::string file = m_kwl->findKey( FGDC_FILE_KW );
90  if ( file.size() )
91  {
92  // Get the version:
93  std::string version = m_kwl->findKey( FGDC_VERSION_KW );
94  if ( version.size() )
95  {
96  // Note: Currently only coded against FGDC-STD-001-1998
97  if ( version == FGDC_VERSION_001_1998)
98  {
99  // Open the file:
100  std::ifstream str( file.c_str(), std::ios_base::in );
101  if ( str.good() )
102  {
103  // Find the Spatial_Reference_Information section:
104  std::string key = "Spatial_Reference_Information:";
105  if ( findKey( str, key ) )
106  {
107  getProjectionV1( str, proj );
108  }
109  }
110  }
111  }
112  }
113  }
114  catch (const ossimException& e)
115  {
116  ossimNotify(ossimNotifyLevel_WARN) << M << " caught exception:\n" << e.what() << std::endl;
117  }
118 }
119 
120 void ossimFgdcTxtDoc::getAltitudeDistanceUnits(std::string& units) const
121 {
122  units = m_kwl->findKey( ALTITUDE_DISTANCE_UNITS_KW );
123 }
124 
126 {
127  static const char M[] = "ossimFgdcTxtDoc::getProjectionV1";
128 
129  std::string fgdcKey;
130  std::string fgdcValue;
131  std::string key;
132  std::string value;
133  ossimKeywordlist projectionKwl;
134 
135  fgdcKey = "Grid_Coordinate_System_Name";
136  if ( findKey( str, true, fgdcKey, fgdcValue ) )
137  {
138  if ( fgdcValue == "Universal Transverse Mercator" )
139  {
140  key = "type";
141  value = "ossimUtmProjection";
142  projectionKwl.addPair(key, value);
143 
144  // Get the zone:
145  fgdcKey = "UTM_Zone_Number";
146  if ( findKey( str, true, fgdcKey, fgdcValue ) )
147  {
148  key = "zone";
149  value = fgdcValue;
150  projectionKwl.addPair(key, value);
151  }
152  else
153  {
154  std::string errMsg = M;
155  errMsg += " ERROR: Could not determine utm zone!";
156  throw ossimException(errMsg);
157  }
158 
159  // Check for Southern hemisphere.
160  fgdcKey = "False_Northing";
161  if ( findKey( str, true, fgdcKey, fgdcValue ) )
162  {
163  key = "hemisphere";
164 
165  // Hemisphere( North false easting = 0.0, South = 10000000):
166  ossim_float64 f = ossimString::toFloat64( fgdcKey.c_str() );
167  if ( f == 0.0 )
168  {
169  value = "N";
170  }
171  else
172  {
173  value = "S";
174  }
175  projectionKwl.addPair(key, value);
176  }
177 
178  } // UTM section:
179  else
180  {
181  // Exception thrown so that we see that we are not handling a projection.
182  std::string errMsg = M;
183  errMsg += "ERROR: Unhandled projection: ";
184  errMsg += fgdcValue;
185  throw ossimException(errMsg);
186  }
187 
188  fgdcKey = "Horizontal_Datum_Name";
189  if ( findKey( str, true, fgdcKey, fgdcValue ) )
190  {
191  getOssimDatum( fgdcValue, value );
192  key = "datum";
193  projectionKwl.addPair(key, value);
194  }
195 
196  } // Matches: findKey( Grid_Coordinate_System_Name )
197 
198  if ( projectionKwl.getSize() )
199  {
200  proj = ossimMapProjectionFactory::instance()->createProjection(projectionKwl);
201  }
202  else
203  {
204  proj = 0;
205  }
206 }
207 
208 bool ossimFgdcTxtDoc::findKey( std::ifstream& str, const std::string& key)
209 {
210  bool result = false;
211  ossimString line;
212  while ( !str.eof() )
213  {
214  // Read line:
215  std::getline( str, line.string() );
216  if ( line.size() )
217  {
218  // Eat white space.
219  line.trim();
220  if ( line.string() == key )
221  {
222  result = true;
223  break;
224  }
225  }
226  }
227  return result;
228 }
229 
231  std::ifstream& str, bool seekBack, const std::string& key, std::string& value)
232 {
233  bool result = false;
234 
235  std::vector<ossimString> fgdcKeyValue;
236  ossimString separator = ":";
237  ossimString line;
238  ossimKeywordlist projectionKwl;
239  std::streampos currentPosition = str.tellg();
240 
241  while ( !str.eof() )
242  {
243  // Read line:
244  std::getline( str, line.string() );
245 
246  if ( line.size() )
247  {
248  // Eat white space.
249  line.trim();
250 
251  // Split between ':'
252  fgdcKeyValue.clear();
253  line.split(fgdcKeyValue, separator, false);
254  if ( fgdcKeyValue.size() == 2 )
255  {
256  fgdcKeyValue[0].trim();
257 
258  if ( fgdcKeyValue[0].size() )
259  {
260  if ( fgdcKeyValue[0] == key )
261  {
262  // Found it. Initialize value and get out.
263  result = true;
264  fgdcKeyValue[1].trim();
265  value = fgdcKeyValue[1].string();
266  break; // from while loop.
267  }
268  }
269  }
270  }
271  }
272 
273  if ( seekBack )
274  {
275  str.seekg(currentPosition);
276  }
277 
278  return result;
279 }
280 
281 // Could be moved to base class for xml and text doc.
282 void ossimFgdcTxtDoc::getOssimDatum( const std::string& fgdcDatumString,
283  std::string& ossimDatumCode ) const
284 {
285  ossimString horizdn = fgdcDatumString;
286  horizdn.downcase();
287  if ( horizdn == "north american datum of 1983" )
288  {
289  ossimDatumCode = "NAR-C";
290  }
291  else if ( horizdn == "north american datum of 1927" )
292  {
293  ossimDatumCode = "NAS-C";
294  }
295  else if ( horizdn == "wgs84")
296  {
297  ossimDatumCode = "WGE";
298  }
299  else
300  {
301  // Exception thrown so that we see that we are not handling a datum.
302  std::string errMsg = "ossimFgdcTxtDoc::getOssimDatum ERROR: Unhandled datum: ";
303  errMsg += horizdn.string();
304  throw ossimException(errMsg);
305  }
306 }
virtual ossimProjection * createProjection(const ossimFilename &filename, ossim_uint32 entryIdx) const
takes a filename.
void clear()
Erases the entire container.
Definition: ossimString.h:432
bool open(const ossimFilename &file)
open method.
Represents serializable keyword/value map.
const std::string & findKey(const std::string &key) const
Find methods that take std::string(s).
std::basic_ifstream< char > ifstream
Class for char input file streams.
Definition: ossimIosFwd.h:44
static ossimMapProjectionFactory * instance()
void split(std::vector< ossimString > &result, const ossimString &separatorList, bool skipBlankFields=false) const
Splits this string into a vector of strings (fields) using the delimiter list specified.
void getProjectionV1(std::ifstream &str, ossimRefPtr< ossimProjection > &proj)
Gets projection from Spatial_Reference_Information block for version FGDC-STD-001-1998.
void addPair(const std::string &key, const std::string &value, bool overwrite=true)
virtual ~ossimFgdcTxtDoc()
virtual destructor
std::istream & getline(std::istream &is, ossimString &str, char delim)
Definition: ossimString.h:916
void close()
Close method.
double ossim_float64
void getOssimDatum(const std::string &fgdcDatumString, std::string &ossimDatumCode) const
Gets ossim datum string from fgdc datum string.
yy_size_t size
virtual const char * what() const
Returns the error message.
std::string::size_type size() const
Definition: ossimString.h:405
ossimFgdcTxtDoc()
default constructor
ossimString trim(const ossimString &valueToTrim=ossimString(" \\)) const
this will strip lead and trailing character passed in.
ossim_float64 toFloat64() const
static ossimString downcase(const ossimString &aString)
Definition: ossimString.cpp:48
void getProjection(ossimRefPtr< ossimProjection > &proj)
Gets projection from Spatial_Reference_Information block.
ossimRefPtr< ossimKeywordlist > m_kwl
ossim_uint32 getSize() const
const char * c_str() const
Returns a pointer to a null-terminated array of characters representing the string&#39;s contents...
Definition: ossimString.h:396
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
bool findKey(std::ifstream &str, const std::string &key)
Finds key and returns true if present.
void getAltitudeDistanceUnits(std::string &units) const
Gets units from Altitude_Distance_Units.
const std::string & string() const
Definition: ossimString.h:414