OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimDatum.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 //
3 // License: See top level LICENSE.txt file.
4 //
5 // Author: Garrett Potts (gpotts@imagelinks.com)
6 //
7 // Description:
8 //
9 //*******************************************************************
10 // $Id: ossimDatum.cpp 19795 2011-06-30 15:04:48Z gpotts $
11 #include <ossim/base/ossimDatum.h>
12 #include <ossim/base/ossimGpt.h>
14 #include <ossim/base/ossimEpsgDatumFactory.h> // For accessing the EPSG codes
15 
16 RTTI_DEF1(ossimDatum, "ossimDatum", ossimObject);
17 
18 ossimDatum::ossimDatum(const ossimString &alpha_code, const ossimString &name,
19  const ossimEllipsoid* anEllipsoid,
20  ossim_float64 sigmaX, ossim_float64 sigmaY, ossim_float64 sigmaZ,
21  ossim_float64 westLongitude, ossim_float64 eastLongitude,
22  ossim_float64 southLatitude, ossim_float64 northLatitude)
23 :
24 theCode(alpha_code),
25 theName(name),
26 theEllipsoid(anEllipsoid),
27 theSigmaX(sigmaX),
28 theSigmaY(sigmaY),
29 theSigmaZ(sigmaZ),
30 theWestLongitude(westLongitude),
31 theEastLongitude(eastLongitude),
32 theSouthLatitude(southLatitude),
33 theNorthLatitude(northLatitude)
34 {
36 };
37 
39  double da,
40  double f,
41  double df,
42  double dx,
43  double dy,
44  double dz,
45  double Lat_in,
46  double Lon_in,
47  double Hgt_in,
48  double &Lat_out,
49  double &Lon_out,
50  double &Hgt_out
51 )const
52 {
53  /* Begin Molodensky_Shift */
54  /*
55  * This function shifts geodetic coordinates using the Molodensky method.
56  *
57  * a : Semi-major axis of source ellipsoid in meters (input)
58  * da : Destination a minus source a (input)
59  * f : Flattening of source ellipsoid (input)
60  * df : Destination f minus source f (input)
61  * dx : X coordinate shift in meters (input)
62  * dy : Y coordinate shift in meters (input)
63  * dz : Z coordinate shift in meters (input)
64  * Lat_in : Latitude in radians. (input)
65  * Lon_in : Longitude in radians. (input)
66  * Hgt_in : Height in meters. (input)
67  * Lat_out : Calculated latitude in radians. (output)
68  * Lon_out : Calculated longitude in radians. (output)
69  * Hgt_out : Calculated height in meters. (output)
70  */
71  double tLon_in; /* temp longitude */
72  double e2; /* Intermediate calculations for dp, dl */
73  double ep2; /* Intermediate calculations for dp, dl */
74  double sin_Lat; /* sin(Latitude_1) */
75  double sin2_Lat; /* (sin(Latitude_1))^2 */
76  double sin_Lon; /* sin(Longitude_1) */
77  double cos_Lat; /* cos(Latitude_1) */
78  double cos_Lon; /* cos(Longitude_1) */
79  double w2; /* Intermediate calculations for dp, dl */
80  double w; /* Intermediate calculations for dp, dl */
81  double w3; /* Intermediate calculations for dp, dl */
82  double m; /* Intermediate calculations for dp, dl */
83  double n; /* Intermediate calculations for dp, dl */
84  double dp; /* Delta phi */
85  double dp1; /* Delta phi calculations */
86  double dp2; /* Delta phi calculations */
87  double dp3; /* Delta phi calculations */
88  double dl; /* Delta lambda */
89  double dh; /* Delta height */
90  double dh1; /* Delta height calculations */
91  double dh2; /* Delta height calculations */
92 
93  if(ossim::isnan(Hgt_in))
94  {
95  Hgt_in = 0.0;
96  }
97 
98  if (Lon_in > M_PI)
99  tLon_in = Lon_in - (2*M_PI);
100  else
101  tLon_in = Lon_in;
102 
103  e2 = 2 * f - f * f;
104  ep2 = e2 / (1 - e2);
105  sin_Lat = sin(Lat_in);
106  cos_Lat = cos(Lat_in);
107  sin_Lon = sin(tLon_in);
108  cos_Lon = cos(tLon_in);
109  sin2_Lat = sin_Lat * sin_Lat;
110  w2 = 1.0 - e2 * sin2_Lat;
111  w = sqrt(w2);
112  w3 = w * w2;
113  m = (a * (1.0 - e2)) / w3;
114  n = a / w;
115  dp1 = cos_Lat * dz - sin_Lat * cos_Lon * dx - sin_Lat * sin_Lon * dy;
116  dp2 = ((e2 * sin_Lat * cos_Lat) / w) * da;
117  dp3 = sin_Lat * cos_Lat * (2.0 * n + ep2 * m * sin2_Lat) * (1.0 - f) * df;
118  dp = (dp1 + dp2 + dp3) / (m + Hgt_in);
119  dl = (-sin_Lon * dx + cos_Lon * dy) / ((n + Hgt_in) * cos_Lat);
120  dh1 = (cos_Lat * cos_Lon * dx) + (cos_Lat * sin_Lon * dy) + (sin_Lat * dz);
121  dh2 = -(w * da) + ((a * (1 - f)) / w) * sin2_Lat * df;
122  dh = dh1 + dh2;
123 
124  Lat_out = Lat_in + dp;
125  Lon_out = Lon_in + dl;
126  Hgt_out = Hgt_in + dh;
127 
128  if (Lon_out > (M_PI * 2))
129  Lon_out -= 2*M_PI;
130  if (Lon_out < (- M_PI))
131  Lon_out += 2*M_PI;
132 }
133 
134 bool ossimDatum::operator==(const ossimDatum& rhs) const
135 {
136  // This method is complicated by the fact that some datums are represented by a precomputed
137  // grid version of the parametric datum.cpp Need to consider these cases. (OLK 02/11)
138  if (theCode == "NAR") // This is the code for gridded NADCON datum
139  {
140  if (!rhs.theCode.contains("NAR"))
141  return false;
142  }
143  else if (rhs.theCode == "NAR")
144  {
145  if (!theCode.contains("NAR"))
146  return false;
147  }
148  else if (theCode == "NAS")
149  {
150  if (!rhs.theCode.contains("NAS"))
151  return false;
152  }
153  else if (rhs.theCode == "NAS")
154  {
155  if (!theCode.contains("NAS"))
156  return false;
157  }
158 
159  // Not a grid, so codes must match:
160  else if (theCode != rhs.theCode)
161  return false;
162 
163  // Additional EPSG code check after HARN v. parametric caused false positives (OLK 05/11):
164  if ((theEpsgCode != 0) && (rhs.theEpsgCode !=0) && (theEpsgCode != rhs.theEpsgCode))
165  return false;
166 
167  // Don't need to check the name since 1:1 relationship with code, code check is sufficient.
168  // This saves the tedium of filtering for NADCON datums as done above.
169  return ((*theEllipsoid == *rhs.theEllipsoid)&&
170  (theSigmaX == rhs.theSigmaX)&&
171  (theSigmaY == rhs.theSigmaY)&&
172  (theSigmaZ == rhs.theSigmaZ)&&
177 }
178 
179 bool ossimDatum::isEqualTo(const ossimObject& obj, ossimCompareType compareType)const
180 {
181  const ossimDatum* rhs = dynamic_cast<const ossimDatum*> (&obj);
182  bool result = rhs&&ossimObject::isEqualTo(obj, compareType);
183  if(result)
184  {
185  result = ((theCode == rhs->theCode)&&
186  (theEpsgCode == rhs->theEpsgCode)&&
187  (theName == rhs->theName)&&
195 
196  if(result)
197  {
198  if(theEllipsoid&&rhs->theEllipsoid)
199  {
200  if(compareType == OSSIM_COMPARE_FULL)
201  {
202  result = theEllipsoid->isEqualTo(*rhs->theEllipsoid, compareType);
203  }
204  else
205  {
206  result = theEllipsoid == rhs->theEllipsoid;
207  }
208  }
209  else if(reinterpret_cast<ossim_uint64>(theEllipsoid) | reinterpret_cast<ossim_uint64>(rhs->theEllipsoid)) // one is null
210  {
211  result = false;
212  }
213  }
214  }
215  return result;
216 }
ossim_float64 theWestLongitude
Definition: ossimDatum.h:142
virtual bool isEqualTo(const ossimObject &obj, ossimCompareType compareType=OSSIM_COMPARE_FULL) const
const ossimEllipsoid * theEllipsoid
Definition: ossimDatum.h:136
ossim_float64 theEastLongitude
Definition: ossimDatum.h:143
ossim_float64 theSouthLatitude
Definition: ossimDatum.h:144
bool almostEqual(T x, T y, T tolerance=FLT_EPSILON)
Definition: ossimCommon.h:53
virtual bool isEqualTo(const ossimObject &obj, ossimCompareType compareType=OSSIM_COMPARE_FULL) const
Definition: ossimDatum.cpp:179
bool contains(char aChar) const
Definition: ossimString.h:58
ossim_float64 theSigmaX
Definition: ossimDatum.h:138
ossimCompareType
double ossim_float64
virtual bool isEqualTo(const ossimEllipsoid &rhs, ossimCompareType compareType=OSSIM_COMPARE_FULL) const
#define M_PI
os2<< "> n<< " > nendobj n
ossimDatum(const ossimString &alpha_code, const ossimString &name, const ossimEllipsoid *anEllipsoid, ossim_float64 sigmaX, ossim_float64 sigmaY, ossim_float64 sigmaZ, ossim_float64 westLongitude, ossim_float64 eastLongitude, ossim_float64 southLatitude, ossim_float64 northLatitude)
Definition: ossimDatum.cpp:18
ossim_float64 theNorthLatitude
Definition: ossimDatum.h:145
static ossimEpsgDatumFactory * instance()
Singleton implementation.
ossim_float64 theSigmaY
Definition: ossimDatum.h:139
bool operator==(const ossimDatum &rhs) const
Definition: ossimDatum.cpp:134
RTTI_DEF1(ossimDatum, "ossimDatum", ossimObject)
virtual void molodenskyShift(double a, double da, double f, double df, double dx, double dy, double dz, double Lat_in, double Lon_in, double Hgt_in, double &Lat_out, double &Lon_out, double &Hgt_out) const
Definition: ossimDatum.cpp:38
ossim_uint32 findEpsgCode(const ossimString &alpha_code) const
Specific to this factory only.
ossimString theName
Definition: ossimDatum.h:135
ossim_float64 theSigmaZ
Definition: ossimDatum.h:140
ossimString theCode
Definition: ossimDatum.h:133
ossim_uint32 theEpsgCode
Definition: ossimDatum.h:134
bool isnan(const float &v)
isnan Test for floating point Not A Number (NAN) value.
Definition: ossimCommon.h:91