OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimGeoidNgsHeader.cpp
Go to the documentation of this file.
2 #include <fstream>
4 #include <cmath>
7 
8 using namespace std;
9 
11 {
12  out << "Filename: " << data.theFilename << endl
13  << "Southern lat: " << data.theSouthernMostLatitude << endl
14  << "Western lon: " << data.theWesternMostLongitude << endl
15  << "Lat spacing: " << data.theLatDelta << endl
16  << "Lon spacing: " << data.theLonDelta << endl
17  << "rows: " << data.theRows << endl
18  << "cols: " << data.theCols << endl
19  << "Datatype: " << data.theDataType << endl;
20 
21  return out;
22 }
23 
24 
26  :theFilename(""),
27  theByteOrder(OSSIM_LITTLE_ENDIAN),
28  theSouthernMostLatitude(0.0),
29  theWesternMostLongitude(0.0),
30  theLatDelta(0.0),
31  theLonDelta(0.0),
32  theRows(0),
33  theCols(0),
34  theDataType(0)
35 {
36 }
37 
40 {
41  initialize(fileName, byteOrder);
42 }
43 
46 {
47  ifstream input(fileName.c_str(), ios::in|ios::binary);
48  if(!input)
49  {
50 // cerr << MODULE << " Cannot open geoid file in " << fileName.c_str()
51 // << endl;
52  return false;
53  }
54 
56  double latOrigin = 0.0;
57  double lonOrigin = 0.0;
58  double latSpacing = 0.0;
59  double lonSpacing = 0.0;
60  int rows = 0;
61  int cols = 0;
62  int type = 0;
63 
64  input.read((char*)&latOrigin, 8);
65  input.read((char*)&lonOrigin, 8);
66  input.read((char*)&latSpacing, 8);
67  input.read((char*)&lonSpacing, 8);
68  input.read((char*)&rows, 4);
69  input.read((char*)&cols, 4);
70  input.read((char*)&type, 4);
71 
72  ossimEndian endian;
73 
74  if(endian.getSystemEndianType() != byteOrder)
75  {
76  endian.swap(latOrigin);
77  endian.swap(lonOrigin);
78  endian.swap(latSpacing);
79  endian.swap(lonSpacing);
80  endian.swap(rows);
81  endian.swap(cols);
82  endian.swap(type);
83  }
84 
85  theFilename = fileName;
86  theSouthernMostLatitude = latOrigin;
87  theWesternMostLongitude = lonOrigin;
88  theLatDelta = latSpacing;
89  theLonDelta = lonSpacing;
90  theRows = rows;
91  theCols = cols;
92  theDataType = type;
93 
94  return ((theSouthernMostLatitude >= -FLT_EPSILON)&&
95  (theSouthernMostLatitude <= 90.0)&&
97  (theWesternMostLongitude <= 360.0));
98 }
99 
100 bool ossimGeoidNgsHeader::pointWithin(double lat, double lon)const
101 {
102  return( (lat >= theSouthernMostLatitude) &&
104  (lon >= theWesternMostLongitude) &&
106 }
107 
109  double lon)const
110 {
111  float result=0.0;
112 
113  // note the headers go from 0 to 360 degrees starting at the prime meridian.
114  // ours goes from -180 to 180 degrees. We will need to shift
115  //
116  if(lon < 0.0) lon += 360;
117  double latSpaces = (lat - theSouthernMostLatitude)/theLatDelta;
118  double lonSpaces = (lon - theWesternMostLongitude)/theLonDelta;
119 
120  if(latSpaces < -FLT_EPSILON) return ossim::nan();
121  if(lonSpaces < -FLT_EPSILON) return ossim::nan();
122 
123  long latSpace0 = (long)std::floor(latSpaces);
124  long latSpace1 = latSpace0 + 1;
125  long lonSpace0 = (long)std::floor(lonSpaces);
126  long lonSpace1 = lonSpace0 + 1;
127 
128  ifstream input(filename().c_str(), ios::in|ios::binary);
129  if(!input)
130  {
131  ossimNotify(ossimNotifyLevel_FATAL) << "FATAL: " << "ossimGeoidNgsHeader::getGeoidHeight, " << "unable to open file: " << theFilename << "\n";
132  return 0;
133  }
134 
135  long offset00 = (long)(headerSize() + (latSpace0*theCols + lonSpace0)*dataTypeSize());
136  long offset01 = (long)(headerSize() + (latSpace0*theCols + lonSpace1)*dataTypeSize());
137  long offset11 = (long)(headerSize() + (latSpace1*theCols + lonSpace1)*dataTypeSize());
138  long offset10 = (long)(headerSize() + (latSpace1*theCols + lonSpace0)*dataTypeSize());
139 
140  double tLat = latSpaces - floor(latSpaces);
141  double tLon = lonSpaces - floor(lonSpaces);
142 
143 
144  float v00;
145  float v01;
146  float v11;
147  float v10;
148 
149  input.seekg(offset00,ios::beg);
150  input.read((char*)&v00, 4);
151 
152  input.seekg(offset01,ios::beg);
153  input.read((char*)&v01, 4);
154 
155  input.seekg(offset11,ios::beg);
156  input.read((char*)&v11, 4);
157 
158  input.seekg(offset10,ios::beg);
159  input.read((char*)&v10, 4);
160  ossimEndian endian;
161  if(endian.getSystemEndianType() != theByteOrder)
162  {
163  endian.swap(v00);
164  endian.swap(v01);
165  endian.swap(v11);
166  endian.swap(v10);
167  }
168  double bottom = (v00 + (v01 - v00)*tLat);
169  double top = (v10 + (v11 - v10)*tLat);
170  result = bottom + (top - bottom)*tLon;
171 
172  return result;
173 
174 }
ostream & operator<<(ostream &out, const ossimGeoidNgsHeader &data)
std::basic_ifstream< char > ifstream
Class for char input file streams.
Definition: ossimIosFwd.h:44
double nan()
Method to return ieee floating point double precision NAN.
Definition: ossimCommon.h:135
bool pointWithin(double lat, double lon) const
const ossimFilename & filename() const
OSSIM_DLL ossimByteOrder byteOrder()
Definition: ossimCommon.cpp:54
#define FLT_EPSILON
ossimByteOrder
ossimByteOrder getSystemEndianType() const
Definition: ossimEndian.h:78
double getHeightDelta(double lat, double lon) 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 initialize(const ossimFilename &fileName, ossimByteOrder byteOrder=OSSIM_LITTLE_ENDIAN)
void swap(ossim_sint8 &)
Definition: ossimEndian.h:26
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
ossimByteOrder theByteOrder