OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimDtedElevationDatabase.cpp
Go to the documentation of this file.
7 #include <sstream>
8 #include <iomanip>
9 #include <cstdlib> /* for abs(int) */
10 
11 static ossimTrace traceDebug("ossimDtedElevationDatabase:debug");
13 
16  m_extension(""),
17  m_upcase(false),
18  m_lastHandler(0),
19  m_mutex()
20 {
21 }
22 
25  m_extension(rhs.m_extension),
26  m_upcase(rhs.m_upcase),
27  m_lastHandler(0), // Do not copy this to get a unique handler for thread.
28  m_mutex()
29 {
30 }
31 
33 {
34 }
35 
37 {
39  return duped;
40 }
41 
43 {
44  if(!isSourceEnabled())
45  return ossim::nan();
46  std::lock_guard<std::mutex> lock(m_mutex);
47  double result = ossim::nan();
49  {
50  result = m_lastHandler->getHeightAboveMSL(gpt);
51  }
52  else
53  {
55  if(m_lastHandler.valid())
56  result = m_lastHandler->getHeightAboveMSL(gpt);
57  }
58 
59  return result;
60 }
61 
63 {
64  double h = getHeightAboveMSL(gpt);
65  if(h != ossim::nan())
66  {
67  double offset = getOffsetFromEllipsoid(gpt);
68 
69  h += offset;
70  }
71 
72  return h;
73 }
74 bool ossimDtedElevationDatabase::open(const ossimString& connectionString)
75 {
76  bool result = false;
77  ossimFilename file = ossimFilename(connectionString);
78 
79  result = openDtedDirectory(file);
80 
81  return result;
82 }
83 
85 {
86  if(traceDebug())
87  {
89  << "ossimDtedElevationDatabase::open entered ...\n"
90  << "dir: " << dir << "\n";
91  }
92 
93  bool result = dir.isDir();
94  if(result)
95  {
96  if ( m_extension.size() == 0 )
97  {
98  //---
99  // This sets extension by doing a directory scan for files with "dt*".
100  // Use "extension" key in preferences to avoid this. Example:
101  // elevation_manager.elevation_source0.extension: dt2.
102  //---
103  result = inititializeExtension( dir );
104  if ( !result && traceDebug() )
105  {
107  << "ossimDtedElevationDatabase::open: WARNING "
108  << "Scan for dted extension failed!\n"
109  << "Can be set in ossim preferences. Example:\n"
110  << "elevation_manager.elevation_source0.extension: .dt2\n";
111  }
112  }
113 
114  // Set the geoid:
115  if( !m_geoid.valid() )
116  {
118  if(!m_geoid.valid()&&traceDebug())
119  {
121  << "ossimDtedElevationDatabase::open: WARNING "
122  << "Unable to load goeid grid 1996 for DTED database\n";
123  }
124  }
125 
126  }
127 
128  if(traceDebug())
129  {
131  << "ossimDtedElevationDatabase::open result:" << (result?"true":"false") << "\n";
132  }
133  return result;
134 }
135 
137 {
138  bool result = false;
139 
140  m_mutex.lock();
141  ossimDtedElevationDatabase* thisPtr = const_cast<ossimDtedElevationDatabase*>(this);
142  ossimRefPtr<ossimElevCellHandler> tempHandler = thisPtr->getOrCreateCellHandler(gpt);
143  m_mutex.unlock();
144 
145  if(tempHandler.valid())
146  {
147  result = tempHandler->getAccuracyInfo(info, gpt);
148  }
149  return result;
150 }
151 
153 {
154  ossimFilename lon, lat;
155  int ilon = static_cast<int>(floor(gpt.lond()));
156 
157  if (ilon < 0)
158  {
159  lon = m_upcase?"W":"w";
160  }
161  else
162  {
163  lon = m_upcase?"E":"e";
164  }
165 
166  ilon = abs(ilon);
168  s1 << std::setfill('0') << std::setw(3)<< ilon;
169 
170  lon += s1.str().c_str();//ossimString::toString(ilon);
171 
172  int ilat = static_cast<int>(floor(gpt.latd()));
173  if (ilat < 0)
174  {
175  lat += m_upcase?"S":"s";
176  }
177  else
178  {
179  lat += m_upcase?"N":"n";
180  }
181 
182  ilat = abs(ilat);
184 
185  s2<< std::setfill('0') << std::setw(2)<< ilat;
186 
187  lat += s2.str().c_str();
188 
189  file = lon.dirCat(lat+m_extension);
190 }
191 
193 {
195  ossimFilename f;
196  createFullPath(f, gpt);
197  if(f.exists())
198  {
200  if (!(h->getErrorStatus()))
201  {
202  result = h.get();
203  }
204  }
205  return result;
206 }
207 
208 bool ossimDtedElevationDatabase::loadState(const ossimKeywordlist& kwl, const char* prefix )
209 {
210  bool result = ossimElevationCellDatabase::loadState(kwl, prefix);
211  if(result)
212  {
214  {
215  // Look for "extension" keyword.
216  std::string pref = (prefix?prefix:"");
217  std::string key = "extension";
219  if ( val.size() )
220  {
221  if ( val.string()[0] != '.' )
222  {
223  m_extension = ".";
224  m_extension += val;
225 
227  << "\nossimDtedElevationDatabase::loadState: WARNING\n"
228  << "Key value for \"extension\" does not start with a dot!\n"
229  << "Consider changing \"" << val << "\" to \"" << m_extension << "\"\n"
230  << std::endl;
231  }
232  else
233  {
234  m_extension = val;
235  }
236  }
237  else if ( traceDebug() )
238  {
240  << "\nossimDtedElevationDatabase::loadState: NOTICE\n"
241  << "Key lookup for \"extension\" failed!\n"
242  << "Can be set in ossim preferences. Example:\n"
243  << pref << key << ": .dt2\n\n";
244  }
245 
246  key = "upcase";
247  val = ossimPreferences::instance()->preferencesKWL().findKey( pref, key );
248  if ( val.size() )
249  {
250  m_upcase = val.toBool();
251  }
252  else if ( traceDebug() )
253  {
255  << "\nossimDtedElevationDatabase::loadState: NOTICE\n"
256  << "Key lookup for \"upcase\" failed!\n"
257  << "Can be set in ossim preferences. Example:\n"
258  << pref << key << ": false\n\n";
259  }
260 
261 
262  result = open(m_connectionString);
263  }
264  else
265  {
266  // can't open the connection because it does not exists or empty
267  result = false;
268  }
269  }
270 
271  return result;
272 }
273 
274 bool ossimDtedElevationDatabase::saveState(ossimKeywordlist& kwl, const char* prefix)const
275 {
276  kwl.add(prefix, "extension", m_extension, true);
277  kwl.add(prefix, "upcase", m_upcase, true);
278 
279  bool result = ossimElevationCellDatabase::saveState(kwl, prefix);
280 
281  return result;
282 }
283 
285 {
286  ossimKeywordlist kwl;
287  saveState(kwl);
288  out << "\nossimDtedElevationDatabase @ "<< (ossim_uint64) this << "\n"
289  << kwl <<ends;
290  return out;
291 }
292 
294 {
295  ossim_uint32 count = 0;
296  ossim_uint32 maxCount = 10;
297  ossimDirectory od;
298  bool result = od.open(dir);
299  if(result)
300  {
301  result = false;
302  ossimFilename f;
303  // Get the first directory.
305 
306  do
307  {
308  ++count;
309  // Must be a directory.
310  if (f.isDir())
311  {
312  // Discard any full path.
313  ossimFilename fileOnly = f.file();
314 
315  // Downcase it. Note have sites with upper case. (drb)
316  // fileOnly.downcase();
317 
318  //---
319  // Longitude subdir check:
320  // Must start with 'e', 'E', 'w' or 'W'.
321  //---
322  bool foundCell = ( ( (fileOnly.c_str()[0] == 'e') ||
323  (fileOnly.c_str()[0] == 'w') ||
324  (fileOnly.c_str()[0] == 'E') ||
325  (fileOnly.c_str()[0] == 'W') ) &&
326  (fileOnly.size() == 4));
327  if(foundCell)
328  {
329  ossim_uint32 maxCount2 = 10;
330  ossim_uint32 count2 = 0;
331  ossimDirectory d2;
332 
333  // Open the longitude subdir:
334  if(d2.open(f))
335  {
337  do
338  {
339  // The DTED directory may be polluted with cell statistics files and other
340  // non-DEM items. Skip if not of the expected extension (OLK 10/2017):
341  if (f.ext().match("[dD][tT][0-9]").empty())
342  continue;
343 
345  if(dtedHandler->open(f, false))
346  {
347  if(traceDebug())
348  {
350  << "ossimDtedElevationDatabase::open: Found dted file " << f << "\n";
351  }
352  result = true;
353  m_extension = "."+f.ext();
354  m_connectionString = dir;
355  m_meanSpacing = dtedHandler->getMeanSpacingMeters();
356  }
357  dtedHandler->close();
358  dtedHandler = 0;
359  ++count2;
360  } while(!result&&d2.getNext(f)&&(count2 < maxCount2));
361  }
362  }
363  }
364  } while(!result&&(od.getNext(f))&&(count < maxCount));
365  }
366 
367  return result;
368 
369 } // End: ossimDtedElevationDatabase::inititializeExtension( dir )
virtual double getHeightAboveMSL(const ossimGpt &)
Height access methods:
virtual bool isSourceEnabled() const
Definition: ossimSource.cpp:79
virtual bool open(const ossimString &connectionString)
Open a connection to a database.
const ossimKeywordlist & preferencesKWL() const
virtual std::ostream & print(std::ostream &out) const
Outputs theErrorStatus as an ossimErrorCode and an ossimString.
RTTI_DEF1(ossimDtedElevationDatabase, "ossimDtedElevationDatabase", ossimElevationCellDatabase)
virtual double getHeightAboveMSL(const ossimGpt &)=0
Height access methods:
virtual bool open(const ossimFilename &file, bool memoryMapFlag=false)
opens a cell
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
virtual double getMeanSpacingMeters() const
METHOD: meanSpacingMeters() Implements pure virtual for.
virtual ossimRefPtr< ossimElevCellHandler > createCell(const ossimGpt &gpt)
std::basic_ostringstream< char > ostringstream
Class for char output memory streams.
Definition: ossimIosFwd.h:35
ossimString match(const char *regularExpressionPattern) const
Returns from found pattern to end of pattern.
double lond() const
Will convert the radian measure to degrees.
Definition: ossimGpt.h:97
Represents serializable keyword/value map.
const std::string & findKey(const std::string &key) const
Find methods that take std::string(s).
bool valid() const
Definition: ossimRefPtr.h:75
bool getFirst(ossimFilename &filename, int flags=OSSIM_DIR_DEFAULT)
double nan()
Method to return ieee floating point double precision NAN.
Definition: ossimCommon.h:135
virtual void close()
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
virtual double getHeightAboveEllipsoid(const ossimGpt &gpt)
bool inititializeExtension(const ossimFilename &dir)
Scans directory and set m_extension to extension of first dted file found.
#define abs(a)
Definition: auxiliary.h:74
bool isDir() const
double latd() const
Will convert the radian measure to degrees.
Definition: ossimGpt.h:87
bool getNext(ossimFilename &filename) const
virtual bool getAccuracyInfo(ossimElevationAccuracyInfo &info, const ossimGpt &gpt) const
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
virtual ossimRefPtr< ossimElevCellHandler > getOrCreateCellHandler(const ossimGpt &gpt)
virtual bool pointHasCoverage(const ossimGpt &) const
METHOD: pointIsInsideRect() Method to check if the ground point elevation is defined: ...
bool exists() const
bool openDtedDirectory(const ossimFilename &dir)
ossimRefPtr< ossimGeoid > m_geoid
std::string::size_type size() const
Definition: ossimString.h:405
ossimGeoid * findGeoidByShortName(const ossimString &shortName, bool caseSensitive=true)
bool toBool() const
String to numeric methods.
unsigned long long ossim_uint64
unsigned int ossim_uint32
static ossimGeoidManager * instance()
Implements singelton pattern:
virtual bool getAccuracyInfo(ossimElevationAccuracyInfo &info, const ossimGpt &gpt) const
ossimRefPtr< ossimElevCellHandler > m_lastHandler
virtual ossimObject * dup() const
the DTED handler is an elevation source that allows for handling of a single cell of data...
static ossimPreferences * instance()
bool open(const ossimFilename &dir)
The DTED elevation data base is also an elevation source but allows one to point to an file based ele...
virtual ossimErrorCode getErrorStatus() const
virtual double getOffsetFromEllipsoid(const ossimGpt &gpt)
ossimFilename dirCat(const ossimFilename &file) 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
bool empty() const
Definition: ossimString.h:411
ossimFilename file() const
ossimString ext() const
void createRelativePath(ossimFilename &file, const ossimGpt &gpt) const
void createFullPath(ossimFilename &file, const ossimGpt &gpt) const
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
const std::string & string() const
Definition: ossimString.h:414