OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimWgs72Datum.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 // Wgs72Datum. Special hardcoded datum. It will create a static
10 // instance of a Wgs72Ellipsoid and set the initial defaults for
11 // that are specific to a Wgs72Datum
12 //*******************************************************************
13 // $Id: ossimWgs72Datum.cpp 22321 2013-07-22 11:40:45Z gpotts $
14 
15 #include <iostream>
16 using namespace std;
18 
23 #include <ossim/base/ossimGpt.h>
25 
26 /***************************************************************************/
27 /*
28  * DEFINES FROM GEOTRANS
29  */
30 
33  :ossimThreeParamDatum("WGD",
34  "World Geodetic System 1972",
35  ossimEllipsoidFactory::instance()->wgs72(),
36  0.0,
37  0.0,
38  0.0,
39  -180,
40  180,
41  -90,
42  90,
43  0.0,
44  0.0,
45  0.0)
46 {
47  if(!ellipsoid())
48  {
49  //ERROR
50  }
51 }
52 
54 {
55  const ossimDatum *aDatum = aPt.datum();
56 
57  if( (ellipsoid()->getA()== aPt.datum()->ellipsoid()->getA())&&
58  (ellipsoid()->getB()== aPt.datum()->ellipsoid()->getB()))
59  {
60  return ossimGpt(aPt.latd(), aPt.lond(), aPt.height(), this);
61  }
62 
63  if(aDatum)
64  {
65  return shiftFromWgs84(aDatum->shiftToWgs84(aPt));
66  }
67 
68  return aPt;
69 }
70 
72 {
73 /* Begin Geodetic_Shift_WGS72_To_WGS84 */
74  /*
75  * This function shifts a geodetic coordinate (latitude, longitude in radians
76  * and height in meters) relative to WGS72 to a geodetic coordinate
77  * (latitude, longitude in radians and height in meters) relative to WGS84.
78  *
79  * WGS72_Lat : Latitude in radians relative to WGS72 (input)
80  * WGS72_Lon : Longitude in radians relative to WGS72 (input)
81  * WGS72_Hgt : Height in meters relative to WGS72 (input)
82  * WGS84_Lat : Latitude in radians relative to WGS84 (output)
83  * WGS84_Lon : Longitude in radians relative to WGS84 (output)
84  * WGS84_Hgt : Height in meters relative to WGS84 (output)
85  */
86  double Delta_Lat;
87  double Delta_Lon;
88  double Delta_Hgt;
89  double WGS84_a; /* Semi-major axis of WGS84 ellipsoid */
90  double WGS84_f; /* Flattening of WGS84 ellipsoid */
91  double WGS72_a; /* Semi-major axis of WGS72 ellipsoid */
92  double WGS72_f; /* Flattening of WGS72 ellipsoid */
93  double da; /* WGS84_a - WGS72_a */
94  double df; /* WGS84_f - WGS72_f */
95  double Q;
96  double sin_Lat;
97  double sin2_Lat;
98 
99  const ossimDatum *wgs84 = ossimDatumFactory::instance()->wgs84();
100  const ossimDatum *wgs72 = ossimDatumFactory::instance()->wgs72();
101  const ossimEllipsoid *wgs84Ellipsoid = ossimEllipsoidFactory::instance()->wgs84();
102  const ossimEllipsoid *wgs72Ellipsoid = ossimEllipsoidFactory::instance()->wgs72();
103 
104  if(!wgs84 || !wgs72 || !wgs72Ellipsoid || !wgs84Ellipsoid)
105  {
106  ossimNotify(ossimNotifyLevel_WARN) << "ossimWgs72Datum::shiftToWgs84, NULL pointer found and no shift will be performed\n";
107  return (aPt);
108  }
109 
110  WGS84_a = wgs84Ellipsoid->a();
111  WGS84_f = wgs84Ellipsoid->flattening();
112  WGS72_a = wgs72Ellipsoid->a();
113  WGS72_f = wgs72Ellipsoid->flattening();
114  da = WGS84_a - WGS72_a;
115  df = WGS84_f - WGS72_f;
116  Q = M_PI / 648000;
117  sin_Lat = sin(aPt.latr());
118  sin2_Lat = sin_Lat * sin_Lat;
119 
120  Delta_Lat = (4.5 * cos(aPt.latr())) / (WGS72_a*Q) + (df * sin(2*aPt.latr())) / Q;
121  Delta_Lat /= SEC_PER_RAD;
122  Delta_Lon = 0.554 / SEC_PER_RAD;
123  Delta_Hgt = 4.5 * sin_Lat + WGS72_a * df * sin2_Lat - da + 1.4;
124 
125  if(aPt.isHgtNan())
126  {
127  return ossimGpt(aPt.latd() + Delta_Lat*DEG_PER_RAD,
128  aPt.lond() + Delta_Lon*DEG_PER_RAD,
129  Delta_Hgt,
130  wgs84);
131  }
132  return ossimGpt(aPt.latd() + Delta_Lat*DEG_PER_RAD,
133  aPt.lond() + Delta_Lon*DEG_PER_RAD,
134  aPt.height() + Delta_Hgt,
135  wgs84);
136  /* End Geodetic_Shift_WGS72_To_WGS84 */
137 }
138 
140 {
141  /* Begin Geodetic_Shift_WGS84_To_WGS72 */
142  /*
143  * This function shifts a geodetic coordinate (latitude, longitude in radians
144  * and height in meters) relative to WGS84 to a geodetic coordinate
145  * (latitude, longitude in radians and height in meters) relative to WGS72.
146  *
147  * WGS84_Lat : Latitude in radians relative to WGS84 (input)
148  * WGS84_Lon : Longitude in radians relative to WGS84 (input)
149  * WGS84_Hgt : Height in meters relative to WGS84 (input)
150  * WGS72_Lat : Latitude in radians relative to WGS72 (output)
151  * WGS72_Lon : Longitude in radians relative to WGS72 (output)
152  * WGS72_Hgt : Height in meters relative to WGS72 (output)
153  */
154  double Delta_Lat;
155  double Delta_Lon;
156  double Delta_Hgt;
157  double WGS84_a; /* Semi-major axis of WGS84 ellipsoid */
158  double WGS84_f; /* Flattening of WGS84 ellipsoid */
159  double WGS72_a; /* Semi-major axis of WGS72 ellipsoid */
160  double WGS72_f; /* Flattening of WGS72 ellipsoid */
161  double da; /* WGS72_a - WGS84_a */
162  double df; /* WGS72_f - WGS84_f */
163  double Q;
164  double sin_Lat;
165  double sin2_Lat;
166  const ossimDatum *wgs84 = ossimDatumFactory::instance()->wgs84();
167  const ossimDatum *wgs72 = ossimDatumFactory::instance()->wgs72();
168  const ossimEllipsoid *wgs84Ellipsoid = ossimEllipsoidFactory::instance()->wgs84();
169  const ossimEllipsoid *wgs72Ellipsoid = ossimEllipsoidFactory::instance()->wgs72();
170 
171  if(!wgs84 || !wgs72 || !wgs72Ellipsoid || !wgs84Ellipsoid)
172  {
173  ossimNotify(ossimNotifyLevel_WARN) << "ossimWgs72Datum::shiftFromWgs84, NULL pointer found and no shift will be performed\n";
174 
175  return (aPt);
176  }
177 
178  WGS84_a = wgs84Ellipsoid->a();
179  WGS84_f = wgs84Ellipsoid->flattening();
180  WGS72_a = wgs72Ellipsoid->a();
181  WGS72_f = wgs72Ellipsoid->flattening();
182 
183  da = WGS72_a - WGS84_a;
184  df = WGS72_f - WGS84_f;
185  Q = M_PI / 648000;
186  sin_Lat = sin(aPt.latr());
187  sin2_Lat = sin_Lat * sin_Lat;
188 
189  Delta_Lat = (-4.5 * cos(aPt.latr())) / (WGS84_a*Q)
190  + (df * sin(2*aPt.latr())) / Q;
191  Delta_Lat /= SEC_PER_RAD;
192  Delta_Lon = -0.554 / SEC_PER_RAD;
193  Delta_Hgt = -4.5 * sin_Lat + WGS84_a * df * sin2_Lat - da - 1.4;
194 
195  if(aPt.isHgtNan())
196  {
197 
198  return ossimGpt(aPt.latd() + Delta_Lat*DEG_PER_RAD,
199  aPt.lond() + Delta_Lon*DEG_PER_RAD,
200  Delta_Hgt,
201  this);
202  }
203  return ossimGpt(aPt.latd() + Delta_Lat*DEG_PER_RAD,
204  aPt.lond() + Delta_Lon*DEG_PER_RAD,
205  aPt.height() + Delta_Hgt,
206  this);
207 }
virtual ossimGpt shift(const ossimGpt &aPt) const
const ossimEllipsoid * wgs72() const
virtual ossimGpt shiftToWgs84(const ossimGpt &aPt) const =0
static ossimEllipsoidFactory * instance()
double lond() const
Will convert the radian measure to degrees.
Definition: ossimGpt.h:97
#define DEG_PER_RAD
double flattening() const
#define SEC_PER_RAD
virtual ossimGpt shiftToWgs84(const ossimGpt &aPt) const
double latd() const
Will convert the radian measure to degrees.
Definition: ossimGpt.h:87
const ossimDatum * wgs72() const
bool isHgtNan() const
Definition: ossimGpt.h:143
const ossimDatum * datum() const
datum().
Definition: ossimGpt.h:196
const ossimEllipsoid * wgs84() const
#define M_PI
const double & a() const
const double & getA() const
virtual const ossimEllipsoid * ellipsoid() const
Definition: ossimDatum.h:60
double height() const
Definition: ossimGpt.h:107
static ossimDatumFactory * instance()
const double & getB() const
double latr() const
latr().
Definition: ossimGpt.h:66
const ossimDatum * wgs84() const
virtual ossimGpt shiftFromWgs84(const ossimGpt &aPt) const
RTTI_DEF1(ossimWgs72Datum, "ossimWgs72Datum", ossimThreeParamDatum)
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)