CARMA C++
Geoid.h
Go to the documentation of this file.
1 #ifndef SZA_UTIL_GEOID_H
2 #define SZA_UTIL_GEOID_H
3 
11 #include "carma/szautil/Constants.h"
14 #include "carma/szautil/HourAngle.h"
15 #include "carma/szautil/Vector.h"
16 
17 namespace sza {
18  namespace util {
19 
20  //============================================================
21  // An enumeration for specifying a type of coordinate system.
22  //
23  // These types are as follows:
24  //
25  //------------------------------------------------------------
26  // ECF (Earth-centered fixed):
27  //
28  // An absolute coordinate system (absolute XYZ, where Z points
29  // along the North pole, X passes through Greenwich meridian, and
30  // Y passes through longitude +90. (Note that East longitude is
31  // positive, and West longitude is negative.)
32  //
33  //------------------------------------------------------------
34  // ENU (East-North-Up):
35  //
36  // A relative coordinate system, used to specify coordinates
37  // relative to a fiducial point on the Earth's surface.
38  // Throughout this document, the Up axis of ENU always means a
39  // true orthogonal to the surface of the Earth, ie, it is parallel
40  // to the geodetic vector. Note the distinction with ENH below.
41  //
42  //------------------------------------------------------------
43  // ENH (East-North-Height):
44  //
45  // A relative coordinate system, used to specify coordinates
46  // relative to a fiducial point on the Earth's surface. The
47  // Height axis of this coordinate system lies along the geocentric
48  // vector passing through the Earth's surface, as distinct from
49  // the Up axis of ENU above, which lies along the _geodetic_
50  // vector passing through the same point. These coordinate
51  // systems are related to each other by a rotation by the
52  // difference between geodetic and geocentric latitudes about the
53  // East axis.
54  //
55  //------------------------------------------------------------
56  // UTM (Universal Transverse Mercator):
57  //
58  // UTM is a series of transverse secant projections, at reference
59  // longitudes distributed 6 degrees around the globe, and latitude
60  // zero. The UTM projection uses a scale factor of 0.9996, unlike
61  // the transverse Mercator projection, which uses scale factor 1.
62  //
63  //------------------------------------------------------------
64  // UPS (Universal Polar Stereographic):
65  //
66  // UPS is a stereographic projection tangent to the earth at
67  // reference points of longitude=0, latitude= +-90, with a scale
68  // factor of 0.994
69  //
70  //------------------------------------------------------------
71  // XYZ: Thompson, Moran and Swenson (Eq. 4.15, 1st ed.)
72  // describe a coordinate system for specifying relative antenna
73  // locations: they call it (X, Y, Z). In their system, Z lies
74  // along the North Celestial Pole, X lies in the plane passing
75  // through an arbitrary longitude/latitude point (at 0 Hour
76  // Angle), and Y lies at -6h Hour Angle. Thus to convert from a
77  // latitude, longitude point to (X, Y, Z), one has only to perform
78  // a translation and a latitude rotation. I interpret their XYZ
79  // coordinate system to have as its origin the center of the
80  // Earth, but there are differing opinions about this. Some think
81  // it should be taken to be fixed to the surface at some fiducial
82  // point. The two interpretations are simply related by a
83  // translation by the radius of the earth, and the difference is
84  // irrelevant when dealing with baseline coordinates, since those
85  // are always relative.
86  //
87  //------------------------------------------------------------
88  // UVW : Coordinates tied to the source reference frame (e.g.,
89  // TMS, section 4.2). These coordinates are simply related to
90  // (X, Y, Z) by a rotation of 90-dec about the X axis, followed
91  // by a rotation by 90-H about the Z axis, where dec is the
92  // source declination and H the hour angle of the source.
93  //
94  //============================================================
95 
96  enum GeoCoordSystem {
97  COORD_UNKNOWN,
98  COORD_ECF,
99  COORD_ENU,
100  COORD_ENH,
101  COORD_UTM,
102  COORD_UPS,
103  COORD_XYZ,
104  COORD_UVW,
105  COORD_GEODETIC,
106  COORD_GEOCENTRIC
107  };
108 
109  //============================================================
110  // Source distance enumeration
111  //============================================================
112 
113  enum SrcDist {
114  DIST_ACTUAL, // Actual source distance
115  DIST_INF // Source at infinity
116  };
117 
118  //============================================================
119  // Enumeration for specifying what set of parameters (ie,
120  // Geographic Datum) is used to determine the reference ellipsoid
121  //============================================================
122 
123  enum GeoDatum {
124 
125  DATUM_NONE,
126 
127  //------------------------------------------------------------
128  // Spherical model, used for testing
129 
130  DATUM_SPHERE,
131 
132  //------------------------------------------------------------
133  //Clarke reference ellipsoid of 1866, used by NAD27 and others
134 
135  DATUM_CLARKE66,
136 
137  DATUM_NAD27, // North American Datum of 1927
138 
139  //------------------------------------------------------------
140  // Australian National Spheroid parameters used by
141  // both of the entries below:
142 
143  DATUM_ANS,
144 
145  DATUM_AGD66, // Australian Geodetic Datum 1966
146  DATUM_GDA84, // Australian Geodetic Datum 1984
147 
148  //------------------------------------------------------------
149  // Geodetic Reference System 1980
150 
151  DATUM_GRS80,
152 
153  DATUM_GDA94, // Geocentric Datum of Australia 1994
154  DATUM_GDA2000, // Geocentric Datum of Australia 2000
155  DATUM_NAD83, // North American Datum of 1983
156 
157  //------------------------------------------------------------
158  // World Geodetic System 1984, used by GPS and others
159 
160  DATUM_WGS84,
161 
162  DATUM_GPS
163  };
164 
165  //============================================================
166  // Enumerate hemispheres for specifying UTM zones
167  //============================================================
168 
169  enum Hemisphere {
170  HEMI_NONE,
171  HEMI_NORTH,
172  HEMI_SOUTH
173  };
174 
175  //============================================================
176  // An enumeration for specifying a spherical coordinate system
177  //============================================================
178 
179  enum SphericalCoordSystem {
180  COORD_LL, // Longitude & Latitude
181  COORD_RADEC, // Right Ascension & Declination
182  COORD_HADEC, // Hour-angle & Declination
183  COORD_AZEL, // Azimuth & Elevation
184  };
185 
186  //============================================================
187  // A class for managing a vector in a spherical coordinate system
188  //============================================================
189 
190  class PolarLengthVector {
191  public:
192 
193  // We can represent a vector as lng, lat, length
194 
195  Angle longitude_;
196  Angle latitude_;
197 
198  // We can represent a vector as ra, dec, length
199 
200  HourAngle ra_;
201  Declination dec_;
202 
203  // We can represent a vector as ha, dec, length
204 
205  HourAngle ha_;
206 
207  // We can represent a vector as az, el, length
208 
209  Angle az_;
210  Angle el_;
211 
212  Length length_;
213 
214  SphericalCoordSystem coordSystem_;
215 
216  void setCoordSystem(SphericalCoordSystem coordSystem) {
217  coordSystem_ = coordSystem;
218  }
219 
220  PolarLengthVector() {
221  }
222 
223  PolarLengthVector(const PolarLengthVector& sap) {
224  *this = sap;
225  }
226 
227  PolarLengthVector(PolarLengthVector& sap) {
228  *this = sap;
229  }
230 
231  void operator=(const PolarLengthVector& cs) {
232  *this = (PolarLengthVector&)cs;
233  };
234 
235  void operator=(PolarLengthVector& cs) {
236 
237  longitude_ = cs.longitude_;
238  latitude_ = cs.latitude_;
239  ra_ = cs.ra_;
240  ha_ = cs.ha_;
241  dec_ = cs.dec_;
242  az_ = cs.az_;
243  el_ = cs.el_;
244  length_ = cs.length_;
245 
246  coordSystem_ = cs.coordSystem_;
247  };
248 
249  friend std::ostream& operator<<(std::ostream& os, const PolarLengthVector& angles);
250  friend std::ostream& operator<<(std::ostream& os, PolarLengthVector& angles);
251 
252  };
253 
254  std::ostream& operator<<(std::ostream& os, const PolarLengthVector& angles);
255  std::ostream& operator<<(std::ostream& os, PolarLengthVector& angles);
256 
257  //============================================================
258  // A class for managing an unambiguous coordinate triplet that can
259  // nevertheless be used in matrix calculations
260  //============================================================
261 
262  class LengthTriplet {
263  public:
264 
265  Vector<Length> coords_;
266 
267  // Generic form in arbitrary coordinate system
268 
269  Length& x_;
270  Length& y_;
271  Length& z_;
272 
273  // ENU-specific form, so we can unambiguously set the right
274  // element without worrying about which order the parameters
275  // have to be
276 
277  Length& east_;
278  Length& north_;
279  Length& up_;
280  Length& height_;
281 
282  // ECF and XYZ-specific forms
283 
284  Length& X_;
285  Length& Y_;
286  Length& Z_;
287 
288  // UTM-specific elements
289 
290  Length& easting_;
291  Length& northing_;
292  double k_;
293  unsigned zone_;
294  Hemisphere hemisphere_;
295 
296  // UVW form
297 
298  Length& u_;
299  Length& v_;
300  Length& w_;
301 
302  // Coordinate system specifiers
303 
304  GeoDatum datum_;
305  GeoCoordSystem coordSystem_;
306  Length sphericalRadius_;
307 
308  void setCoordSystem(GeoCoordSystem coordSystem) {
309  coordSystem_ = coordSystem;
310  }
311 
312  void setDatum(GeoDatum datum, Length sphericalRadius=Constants::defaultEarthRadius_) {
313  datum_ = datum;
314  sphericalRadius_ = sphericalRadius;
315  }
316 
317  void initialize() {
318  k_ = 1.0;
319  zone_ = 0;
320  hemisphere_ = HEMI_NONE;
321  datum_ = DATUM_NONE;
322  coordSystem_ = COORD_UNKNOWN;
323  sphericalRadius_ = Constants::defaultEarthRadius_;
324  }
325 
326  void zero() {
327  coords_[0].setMeters(0.0);
328  coords_[1].setMeters(0.0);
329  coords_[2].setMeters(0.0);
330  };
331 
332  LengthTriplet() : coords_(3),
333  x_(coords_[0]), y_(coords_[1]), z_(coords_[2]),
334  X_(coords_[0]), Y_(coords_[1]), Z_(coords_[2]),
335  u_(coords_[0]), v_(coords_[1]), w_(coords_[2]),
336  east_(coords_[0]), north_(coords_[1]), up_(coords_[2]),
337  easting_(coords_[0]), northing_(coords_[1]), height_(coords_[2])
338  {
339  initialize();
340  };
341 
342  LengthTriplet(const LengthTriplet& triplet) : coords_(3),
343  x_(coords_[0]), y_(coords_[1]), z_(coords_[2]),
344  X_(coords_[0]), Y_(coords_[1]), Z_(coords_[2]),
345  u_(coords_[0]), v_(coords_[1]), w_(coords_[2]),
346  east_(coords_[0]), north_(coords_[1]), up_(coords_[2]),
347  easting_(coords_[0]), northing_(coords_[1]), height_(coords_[2])
348  {
349  *this = triplet;
350  }
351 
352  LengthTriplet(LengthTriplet& triplet) : coords_(3),
353  x_(coords_[0]), y_(coords_[1]), z_(coords_[2]),
354  X_(coords_[0]), Y_(coords_[1]), Z_(coords_[2]),
355  u_(coords_[0]), v_(coords_[1]), w_(coords_[2]),
356  east_(coords_[0]), north_(coords_[1]), up_(coords_[2]),
357  easting_(coords_[0]), northing_(coords_[1]), height_(coords_[2])
358  {
359  *this = triplet;
360  }
361 
362  LengthTriplet(const Vector<Length>& vec) : coords_(3),
363  x_(coords_[0]), y_(coords_[1]), z_(coords_[2]),
364  X_(coords_[0]), Y_(coords_[1]), Z_(coords_[2]),
365  u_(coords_[0]), v_(coords_[1]), w_(coords_[2]),
366  east_(coords_[0]), north_(coords_[1]), up_(coords_[2]),
367  easting_(coords_[0]), northing_(coords_[1]), height_(coords_[2])
368  {
369  *this = vec;
370  }
371 
372  LengthTriplet(Vector<Length>& vec) : coords_(3),
373  x_(coords_[0]), y_(coords_[1]), z_(coords_[2]),
374  X_(coords_[0]), Y_(coords_[1]), Z_(coords_[2]),
375  u_(coords_[0]), v_(coords_[1]), w_(coords_[2]),
376  east_(coords_[0]), north_(coords_[1]), up_(coords_[2]),
377  easting_(coords_[0]), northing_(coords_[1]), height_(coords_[2])
378  {
379  *this = vec;
380  }
381 
382  virtual ~LengthTriplet() {};
383 
384  Length magnitude() {
385  Vector<double> dVec(3);
386  dVec[0] = coords_[0].meters();
387  dVec[1] = coords_[1].meters();
388  dVec[2] = coords_[2].meters();
389 
390  Length mag;
391  mag.setMeters(dVec.magnitude());
392 
393  return mag;
394  };
395 
396  void operator=(const LengthTriplet& triplet) {
397  *this = (LengthTriplet&)triplet;
398  };
399 
400  void operator=(LengthTriplet& triplet) {
401  initialize();
402  coords_[0] = triplet.coords_[0];
403  coords_[1] = triplet.coords_[1];
404  coords_[2] = triplet.coords_[2];
405  k_ = triplet.k_;
406  zone_ = triplet.zone_;
407  coordSystem_ = triplet.coordSystem_;
408  hemisphere_ = triplet.hemisphere_;
409  datum_ = triplet.datum_;
410  sphericalRadius_ = triplet.sphericalRadius_;
411  };
412 
413  void operator=(const Vector<Length>& vec) {
414  *this = ((Vector<Length>&) vec);
415  }
416 
417  void operator=(Vector<Length>& vec) {
418 
419  if(vec.size() != 3) {
420  ThrowError("Cannot assign a length " << vec.size()
421  << " vector to a LengthTriplet (obviously, \"Triplet\" implies 3)");
422  }
423 
424  initialize();
425  coords_ = vec;
426  };
427 
428  LengthTriplet operator*(double fac) {
429  coords_[0] *= fac;
430  coords_[1] *= fac;
431  coords_[2] *= fac;
432  return *this;
433  };
434 
435  LengthTriplet operator/(double fac) {
436  coords_[0] /= fac;
437  coords_[1] /= fac;
438  coords_[2] /= fac;
439  return *this;
440  };
441 
442  Vector<double> operator/(const Length& length) {
443  return operator/((Length&) length);
444  };
445 
446  Vector<double> operator/(Length& length) {
447  return coords_ / length;
448  };
449 
450  LengthTriplet operator-(const LengthTriplet& triplet) {
451  return operator-((LengthTriplet&) triplet);
452  }
453 
454  LengthTriplet operator-(LengthTriplet& triplet) {
455  LengthTriplet ret = *this;
456  ret.coords_ = coords_ - triplet.coords_;
457  return ret;
458  }
459 
460  friend std::ostream& operator<<(std::ostream& os, const LengthTriplet& triplet);
461  friend std::ostream& operator<<(std::ostream& os, LengthTriplet& triplet);
462 
463  };
464 
465  std::ostream& operator<<(std::ostream& os, const LengthTriplet& triplet);
466  std::ostream& operator<<(std::ostream& os, LengthTriplet& triplet);
467 
468  //============================================================y
469  // Class for managing a commonly-needed set of coordinates:
470  //
471  // Longitude/Latitude/Altitude
472  //============================================================
473 
474  class Lla {
475  public:
476  Angle longitude_;
477  Angle latitude_;
478  Length altitude_;
479 
480  GeoDatum datum_;
481  GeoCoordSystem coordSystem_;
482  Length sphericalRadius_;
483 
484  Lla() {
485  datum_ = DATUM_NONE;
486  coordSystem_ = COORD_UNKNOWN;
487  sphericalRadius_ = Constants::defaultEarthRadius_;
488  }
489 
490  Lla(const Lla& lla) {
491  *this = lla;
492  }
493 
494  Lla(Lla& lla) {
495  *this = (Lla&)lla;
496  }
497 
498  void operator=(const Lla& lla) {
499  *this = (Lla&)lla;
500  }
501 
502  void operator=(Lla& lla) {
503  longitude_ = lla.longitude_;
504  latitude_ = lla.latitude_;
505  altitude_ = lla.altitude_;
506  datum_ = lla.datum_;
507  coordSystem_ = lla.coordSystem_;
508  sphericalRadius_ = lla.sphericalRadius_;
509  }
510 
511  void setCoordSystem(GeoCoordSystem coordSystem) {
512  coordSystem_ = coordSystem;
513  }
514 
515  void setDatum(GeoDatum datum, Length sphericalRadius=Constants::defaultEarthRadius_) {
516  datum_ = datum;
517  sphericalRadius_ = sphericalRadius;
518  }
519 
520  friend std::ostream& operator<<(std::ostream& os, const Lla& lla);
521  friend std::ostream& operator<<(std::ostream& os, Lla& lla);
522  };
523 
524  std::ostream& operator<<(std::ostream& os, const Lla& lla);
525  std::ostream& operator<<(std::ostream& os, Lla& lla);
526 
527  //============================================================
528  // A class for managing real-Earth geometry calculations
529  //============================================================
530 
531  class Geoid : public Ellipsoid {
532  public:
533 
534  // Constructor.
535 
536  Geoid();
537  Geoid(GeoDatum referenceSystem);
538 
539  // Destructor.
540 
541  virtual ~Geoid();
542 
543  //-----------------------------------------------------------------------
544  // Select the Earth ellipsoid reference system (ie, in the
545  // terminology of the NGS, which Datum are we using?)
546  //-----------------------------------------------------------------------
547 
548  void changeDatum(GeoDatum datum, Length sphericalRadius = Constants::defaultEarthRadius_);
549 
550  void setDatum(GeoDatum datum, Length sphericalRadius = Constants::defaultEarthRadius_);
551  void setDefaultDatum(GeoDatum datum, Length sphericalRadius = Constants::defaultEarthRadius_);
552 
553  void restoreDefaultDatum();
554 
555  //-----------------------------------------------------------------------
556  // Return parameters of the current reference system
557  //-----------------------------------------------------------------------
558 
559  Length earthEquatorialRadius();
560  Length earthPolarRadius();
561 
562  //-----------------------------------------------------------------------
563  // Return the length of the radius vector from the center of the
564  // earth to the surface at a given Geocentric latitude, for the
565  // current datum
566  //-----------------------------------------------------------------------
567 
568  Length geocentricRadius(Angle geocentricLatitude);
569 
570  //-----------------------------------------------------------------------
571  // Return the length of the radius vector normal to the surface
572  // at a given Geodetic latitude, for the current datum
573  //-----------------------------------------------------------------------
574 
575  Length geodeticRadius(Angle geodeticLatitude);
576 
577  //-----------------------------------------------------------------------
578  // Return the Geocentric latitude corresponding to a given
579  // geodetic latitude, on the surface of the earth, for the
580  // current datum
581  //-----------------------------------------------------------------------
582 
583  Angle geocentricLatitude(Angle geodeticLatitude);
584 
585  //-----------------------------------------------------------------------
586  // Return the geodetic latitude corresponding to a given
587  // geocentric latitude on the surrface of the earth, for the
588  // curent datum
589  //-----------------------------------------------------------------------
590 
591  Angle geodeticLatitude(Angle geocentricLatitude);
592 
593  //-----------------------------------------------------------------------
594  // Convert from Geocentric LLA and Geocentric ENU in any
595  // input datum to Geodetic coordinates in the current datum
596  //-----------------------------------------------------------------------
597 
598  Lla geocentricLlaAndEnhToGeodeticLla(Lla& geocentricLla, LengthTriplet enh=LengthTriplet());
599 
600  //-----------------------------------------------------------------------
601  // Convert from Geocentric LLA and Geocentric ENU in any
602  // input datum to Geocentric coordinates in the current datum
603  //-----------------------------------------------------------------------
604 
605  Lla geocentricLlaAndEnhToGeocentricLla(Lla& geocentricLla, LengthTriplet enh=LengthTriplet());
606 
607  //-----------------------------------------------------------------------
608  // Convert from Geodetic LLA and Geodetic ENU in any input
609  // datum to Geodetic coordinates in the current datum
610  //-----------------------------------------------------------------------
611 
612  Lla geodeticLlaAndEnuToGeocentricLla(Lla& geodeticLla, LengthTriplet enu=LengthTriplet());
613 
614  //-----------------------------------------------------------------------
615  // Convert from Geodetic LLA and Geodetic ENU in any input
616  // datum to Geocentric coordinates in the current datum
617  //-----------------------------------------------------------------------
618 
619  Lla geodeticLlaAndEnuToGeodeticLla(Lla& geodeticLla, LengthTriplet enu=LengthTriplet());
620 
621  //-----------------------------------------------------------------------
622  // Convert from Geodetic LLA and Geodetic ENU in any input
623  // datum to UTM Northing/Easting in the current datum
624  //-----------------------------------------------------------------------
625 
626  LengthTriplet geodeticLlaAndEnuToUtm(Lla& geodeticLla, LengthTriplet enu=LengthTriplet());
627 
628  //-----------------------------------------------------------------------
629  // Convert from UTM coordinate in any input datum to
630  // Geodetic coordinate in the current datum
631  //-----------------------------------------------------------------------
632 
633  Lla utmToGeodeticLla(LengthTriplet& utm);
634 
635  //-----------------------------------------------------------------------
636  // Convert from UTM coordinate in any input datum to UTM
637  // coordinate in the current datum
638  //-----------------------------------------------------------------------
639 
640  LengthTriplet utmToUtm(LengthTriplet& utm);
641 
642  //-----------------------------------------------------------------------
643  // Convert from Geodetic LLA and Geodetic ENU in any input
644  // datum to UPS Northing/Easting in the current datum
645  //-----------------------------------------------------------------------
646 
647  LengthTriplet geodeticLlaAndEnuToUps(Lla& geodeticLla, LengthTriplet enu=LengthTriplet());
648 
649  //-----------------------------------------------------------------------
650  // Convert from UPS in any input datum to Geodetic LLA in the
651  // current datum
652  //-----------------------------------------------------------------------
653 
654  Lla upsToGeodeticLla(LengthTriplet& ups);
655 
656  //-----------------------------------------------------------------------
657  // Convert from Geodetic LLA and UTM offset relative to that
658  // point, in any input datum, to Geodetic coordinate in the
659  // current datum
660  //-----------------------------------------------------------------------
661 
662  Lla geodeticLlaAndDeltaUtmToGeodeticLla(Lla& geodeticLla, LengthTriplet& deltaUtm);
663 
664  //=======================================================================
665  // Astronomical conversions
666  //=======================================================================
667 
668  //-----------------------------------------------------------------------
669  // Return the (Az, El) coordinates of the specified (HA, Dec)
670  // point.
671  //-----------------------------------------------------------------------
672 
673  PolarLengthVector geodeticLlaAndHaDecToAzEl(Lla& geodeticLla,
674  HourAngle ha, Declination declination,
675  SrcDist type=DIST_INF, Length distance=Length(Length::Meters(), 0.0));
676 
677  //-----------------------------------------------------------------------
678  // Return the UVW coordinates of the specified (HA, Dec) point.
679  //-----------------------------------------------------------------------
680 
681  LengthTriplet geodeticLlaAndHaDecToUvw(Lla& geodeticLla,
682  HourAngle ha,
683  Declination declination);
684 
685  public:
686 
687  //-----------------------------------------------------------------------
688  // Specifies the reference ellipsoid we are using
689  //-----------------------------------------------------------------------
690 
691  GeoDatum datum_;
692  GeoDatum defaultDatum_;
693  Length defaultSphericalRadius_;
694 
695  //-----------------------------------------------------------------------
696  // Convert from Geodetic coordinates to ECF coordinates
697  //-----------------------------------------------------------------------
698 
699  LengthTriplet geodeticLlaAndEnuToEcf(Lla& geodeticLla, LengthTriplet enu=LengthTriplet());
700 
701  //-----------------------------------------------------------------------
702  // Convert from Geocentric coordinates to ECF coordinates
703  //-----------------------------------------------------------------------
704 
705  LengthTriplet geocentricLlaAndEnhToEcf(Lla& geocentricLla, LengthTriplet enh=LengthTriplet());
706 
707  //-----------------------------------------------------------------------
708  // Conversions between Geodetic coordinates and relative XYZ coordinates
709  //-----------------------------------------------------------------------
710 
711  LengthTriplet geodeticLlaAndEnuToXyz(Lla& geodeticLla, LengthTriplet enu=LengthTriplet());
712  LengthTriplet geodeticLlaAndXyzToEnu(Lla& geodeticLla, LengthTriplet xyz=LengthTriplet());
713 
714  //-----------------------------------------------------------------------
715  // Convert from Geocentric coordinates to relative XYZ coordinates
716  //-----------------------------------------------------------------------
717 
718  LengthTriplet geocentricLlaAndEnhToXyz(Lla& geocentricLla, LengthTriplet enh=LengthTriplet());
719 
720  //-----------------------------------------------------------------------
721  // Given a reference geodetic position, and a second geodetic
722  // position, return the ENU coordinates of the second position
723  // w.r.t. the first
724  //-----------------------------------------------------------------------
725 
726  LengthTriplet geodeticLlaAndGeodeticLlaToEnu(Lla& geodeticLlaRef, Lla& geodeticLlaObs);
727 
728  //-----------------------------------------------------------------------
729  // Convert from ECF coordinates to Geocentric coordinates
730  //-----------------------------------------------------------------------
731 
732  Lla ecfToGeocentricLla(LengthTriplet& ecf);
733 
734  //-----------------------------------------------------------------------
735  // Convert from ECF coordinates to Geodetic coordinates
736  //-----------------------------------------------------------------------
737 
738  Lla ecfToGeodeticLla(LengthTriplet& ecf);
739 
740  //=======================================================================
741  // UTM utilities
742  //=======================================================================
743 
744  //-----------------------------------------------------------------------
745  // Convert from Geodetic coordinates to projected cylindrical coordinates
746  //-----------------------------------------------------------------------
747 
748  LengthTriplet transverseSecantProjection(Lla& geodeticLla, Lla& referenceLla, double k0);
749 
750  //-----------------------------------------------------------------------
751  // Convert from projected cylindrical coordinates to Geodetic coordinates
752  //-----------------------------------------------------------------------
753 
754  Lla inverseTransverseSecantProjection(LengthTriplet& xyk, Lla& referenceLla, double k0);
755 
756  //-----------------------------------------------------------------------
757  // Convert from Geodetic coordinates to projected polar
758  // stereographic coordinates
759  //-----------------------------------------------------------------------
760 
761  LengthTriplet polarStereographicProjection(Lla& geodeticLla, Lla& referenceLla, double k0);
762 
763  //-----------------------------------------------------------------------
764  // Convert from projected polar stereographic coordinates to
765  // Geodetic coordinates
766  //-----------------------------------------------------------------------
767 
768  Lla inversePolarStereographicProjection(LengthTriplet& xyk, double k0);
769 
770  //-----------------------------------------------------------------------
771  // Series expansion of term used in above calculations
772  //-----------------------------------------------------------------------
773 
774  double utmSeriesExpansionForM(Angle& lat);
775 
776  //-----------------------------------------------------------------------
777  // Return the UTM zone corresponding to this longitude
778  //-----------------------------------------------------------------------
779 
780  unsigned longitudeToUtmZone(Angle longitude);
781 
782  //-----------------------------------------------------------------------
783  // Convert from UTM zone number to reference longitude
784  //-----------------------------------------------------------------------
785 
786  Angle utmZoneToLongitude(unsigned zone);
787 
788  //-----------------------------------------------------------------------
789  // Return the UTM reference longitude corresponding to this
790  // longitude
791  //-----------------------------------------------------------------------
792 
793  Angle getUtmReferenceLongitude(Angle longitude);
794 
795  //=======================================================================
796  // Astronomical utilities
797  //=======================================================================
798 
799  LengthTriplet haDecDistToXyz(HourAngle ha, Declination dec, Length distance);
800  LengthTriplet haDecDistToXyz2(HourAngle ha, Declination dec, Length distance);
801  Vector<double> haDecToXyzDir(HourAngle ha, Declination dec);
802 
803  // Given XYZ, return the Ha and Dec
804 
805  PolarLengthVector xyzToHaDec(LengthTriplet& xyz);
806 
807  // Given ENU, return the Azimuth and Elevation
808 
809  PolarLengthVector enuToAzEl(LengthTriplet& enu);
810 
811  // Given Azimuth and Elevation, return the ENU
812 
813  LengthTriplet azElToEnu(Angle az, Angle el, Length distance);
814 
815  //=======================================================================
816  // Rotation matrices used by this class
817  //=======================================================================
818 
819  // Return the rotation about the east axis to convert from
820  // Geodetic ENU to Geocentric ENH
821 
822  sza::util::Matrix<double> getEnuToEnhRot(Angle latDiff);
823 
824  sza::util::Matrix<double> getEnhToXyzLatRot(Angle geocentricLatitude);
825  sza::util::Matrix<double> getXyzToEcfLngRot(Angle longitude);
826 
827  sza::util::Matrix<double> getXyzToUvwHaRot(HourAngle ha);
828  sza::util::Matrix<double> getXyzToUvwDecRot(Declination dec);
829 
830  }; // End class Geoid
831 
832  std::ostream& operator<<(std::ostream& os, GeoDatum datum);
833  std::ostream& operator<<(std::ostream& os, GeoCoordSystem coordSystem);
834  GeoDatum stringToDatum(std::string);
835 
836  Vector<Length> operator*(Matrix<double>& mat, LengthTriplet& triplet);
837 
838  } // End namespace util
839 } // End namespace sza
840 
841 
842 
843 #endif // End #ifndef SZA_UTIL_GEOID_H
Tagged: Fri Jun 15 16:44:12 PDT 2007.
Tagged: Wed Aug 25 02:50:06 PDT 2004.