00001 /* SimData: Data Infrastructure for Simulations 00002 * Copyright (C) 2002, 2003 Mark Rose <mrose@stm.lbl.gov> 00003 * 00004 * This file is part of SimData. 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00019 */ 00020 00028 #ifndef __SIMDATA_GEOPOS_H__ 00029 #define __SIMDATA_GEOPOS_H__ 00030 00031 #include <string> 00032 #include <SimData/Vector3.h> 00033 #include <SimData/Export.h> 00034 00035 00036 NAMESPACE_SIMDATA 00037 00038 00041 struct SIMDATA_EXPORT ReferenceEllipsoid { 00042 ReferenceEllipsoid(double semi_major, double semi_minor) { 00043 A = semi_major; 00044 B = semi_minor; 00045 R = 6371010.0; 00046 f = (A-B)/A; 00047 e = sqrt(2*f-f*f); 00048 A_B = A/B; 00049 B_A = B/A; 00050 B2_A2 = (B*B)/(A*A); 00051 A2_B2 = 1.0 / B2_A2; 00052 e2 = e*e; 00053 e1 = (A-B)/(A+B); 00054 ep = sqrt(A*A-B*B)/B; 00055 ep2 = ep*ep; 00056 // utm2ll constants 00057 m_0 = 1.0 - 0.25 * e2 - 0.046875*e2*e2 - 0.01953125*e2*e2*e2; 00058 m_1 = -(0.375*e2 + 0.09375*e2*e2 + 0.0439453125*e2*e2*e2); 00059 m_2 = 0.05859375*e2*e2 + 0.0439453125*e2*e2*e2; 00060 m_3 = -0.01139322916667*e2*e2*e2; 00061 // ll2utm constants 00062 m_f = 1.0/(A*(1.0 - e2*(0.25 + e2*(0.046875 + e2*0.01953125)))); 00063 m_a = e1 * (1.5 - 0.84375*e1*e1); 00064 m_b = e1 * e1 * (1.3125 - 1.71875*e1*e1); 00065 m_c = 1.5729166666667*e1*e1*e1; 00066 } 00067 double A; 00068 double B; 00069 double R; 00070 double f; 00071 double e; 00072 double A_B; 00073 double B_A; 00074 double B2_A2; 00075 double A2_B2; 00076 double e2; 00077 double e1; 00078 double ep; 00079 double ep2; 00080 00081 double m_0; 00082 double m_1; 00083 double m_2; 00084 double m_3; 00085 00086 double m_f; 00087 double m_a; 00088 double m_b; 00089 double m_c; 00090 }; 00091 00092 00100 namespace GeoRef { 00103 extern SIMDATA_EXPORT const ReferenceEllipsoid Airy1830; 00106 extern SIMDATA_EXPORT const ReferenceEllipsoid AustralianNational; 00109 extern SIMDATA_EXPORT const ReferenceEllipsoid WGS84; 00112 extern SIMDATA_EXPORT const ReferenceEllipsoid GRS80; 00115 extern SIMDATA_EXPORT const ReferenceEllipsoid WGS72; 00118 extern SIMDATA_EXPORT const ReferenceEllipsoid Clarke1866; 00121 extern SIMDATA_EXPORT const ReferenceEllipsoid NAD27; 00122 } 00123 00124 00125 00143 class SIMDATA_EXPORT GeoPos: public Vector3 { 00144 public: 00145 00151 GeoPos(): Vector3(), _ref(&GeoRef::WGS84) { 00152 _stale_lla = true; 00153 _stale_utm = true; 00154 } 00155 00160 GeoPos(Vector3 const &v): Vector3(), _ref(&GeoRef::WGS84) { *this = v; } 00161 00166 GeoPos(GeoPos const &g): Vector3(), _ref(&GeoRef::WGS84) { *this = g; } 00167 00172 const GeoPos &operator=(Vector3 const &v); 00173 00178 const GeoPos &operator=(GeoPos const &g); 00179 00182 virtual ~GeoPos() {} 00183 00189 double getSlantRange(GeoPos const &) const; 00190 00200 void getSurfaceDistance(GeoPos const &, double &distance, double &bearing) const; 00201 00212 void getShellDistance(GeoPos const &, double &distance, double &bearing) const; 00213 00220 void getLocalFrame(Vector3 &localX, Vector3 &localY, Vector3 &localZ) const; 00221 00228 void getLLA(double &lat, double &lon, double &alt) const; 00229 00236 void setLLA(double lat, double lon, double alt = 0.0); 00237 00242 double getLongitude() const { if (_stale_lla) _updateLLA(); return _lon; } 00243 00248 double getLatitude() const { if (_stale_lla) _updateLLA(); return _lat; } 00249 00254 double getAltitude() const { if (_stale_lla) _updateLLA(); return _alt; } 00255 00260 void _updateLLA() const; 00261 00269 void getUTM(double &northing, double &easting, char &zone, char &designator) const; 00270 00279 void setUTM(double northing, double easting, char zone, char designator, double alt = 0.0); 00280 00288 void setUTM(double northing, double easting, const char *zone, double alt = 0.0); 00289 00292 double getNorthing() const { if (_stale_utm) _updateUTM(); return _northing; } 00293 00296 double getEasting() const { if (_stale_utm) _updateUTM(); return _easting; } 00297 00300 int getZoneNumber() const { if (_stale_utm) _updateUTM(); return _zone; } 00301 00304 char getZoneLetter() const { if (_stale_utm) _updateUTM(); return _designator; } 00305 00310 void _updateUTM() const; 00311 00316 static char _getUTMDesignator(double lat); 00317 00324 void setReferenceEllipsoid(ReferenceEllipsoid const & = GeoRef::WGS84); 00325 00328 ReferenceEllipsoid const &getReferenceEllipsoid() const { return *_ref; } 00329 00335 void setDirty() { _stale_lla = _stale_utm = true; } 00336 00339 virtual std::string asString() const { return Vector3::asString(); } 00340 00343 virtual std::string typeString() const { return "type::GeoPos"; } 00344 00368 void parseXML(const char *); 00369 00372 virtual void serialize(Archive&); 00373 00374 protected: 00375 00377 mutable double _lat; 00379 mutable double _lon; 00381 mutable double _alt; 00383 mutable bool _stale_lla; 00385 mutable bool _stale_utm; 00387 mutable double _northing; 00389 mutable double _easting; 00391 mutable char _zone; 00393 mutable char _designator; 00395 ReferenceEllipsoid const *_ref; 00396 00399 void iterateECEF(double p, double z, double x, double y, int iter=0) const; 00400 }; 00401 00402 00403 class UTM; 00404 class LLA; 00405 class ECEF; 00406 00414 LLA ECEFtoLLA(ECEF const &ecef, ReferenceEllipsoid const &_ref = GeoRef::WGS84); 00415 00423 UTM ECEFtoUTM(ECEF const &ecef, ReferenceEllipsoid const &_ref = GeoRef::WGS84); 00424 00432 ECEF LLAtoECEF(LLA const &lla, ReferenceEllipsoid const &_ref = GeoRef::WGS84); 00433 00441 ECEF UTMtoECEF(UTM const &utm, ReferenceEllipsoid const &_ref = GeoRef::WGS84); 00442 00450 LLA UTMtoLLA(UTM const &utm, ReferenceEllipsoid const &_ref = GeoRef::WGS84); 00451 00460 UTM LLAtoUTM(LLA const &lla, ReferenceEllipsoid const &_ref = GeoRef::WGS84, char _zone=-1); 00461 00474 void SurfaceDistance(LLA const &p, 00475 LLA const &q, 00476 double &distance, 00477 double &bearing, 00478 ReferenceEllipsoid const &_ref = GeoRef::WGS84); 00479 00480 00494 void ShellDistance(LLA const &p, 00495 LLA const &q, 00496 double &distance, 00497 double &bearing, 00498 ReferenceEllipsoid const &_ref = GeoRef::WGS84); 00499 00500 00518 class SIMDATA_EXPORT LLA: public BaseType { 00519 double _lat, _lon, _alt; 00520 public: 00523 LLA(): _lat(0.0), _lon(0.0), _alt(0.0) {} 00524 00531 LLA(double lat, double lon, double alt=0.0): _lat(lat), _lon(lon), _alt(alt) {} 00532 00535 LLA(UTM const &, ReferenceEllipsoid const & = GeoRef::WGS84); 00536 00539 LLA(ECEF const &, ReferenceEllipsoid const & = GeoRef::WGS84); 00540 00543 LLA const &operator = (UTM const &); 00544 00547 LLA const &operator = (ECEF const &); 00548 00549 virtual ~LLA() {} 00550 00553 void set(double lat, double lon, double alt=0.0) { 00554 _lat = lat; 00555 _lon = lon; 00556 _alt = alt; 00557 } 00558 00561 void setDegrees(double lat, double lon, double alt=0.0); 00562 00565 inline double latitude() const { return _lat; } 00566 00569 inline double longitude() const { return _lon; } 00570 00573 inline double altitude() const { return _alt; } 00574 00577 virtual std::string asString() const; 00578 00581 virtual std::string typeString() const { return "type::LLA"; } 00582 00591 void parseXML(const char *); 00592 00595 virtual void serialize(Archive&); 00596 }; 00597 00598 00609 class SIMDATA_EXPORT UTM: public BaseType { 00610 double _E, _N, _alt; 00611 char _zone, _designator; 00612 public: 00615 static char getDesignator(double latitude); 00616 00619 UTM(): _E(0.0), _N(0.0), _alt(0.0), _zone(0), _designator('X') {} 00620 00623 UTM(double easting_, double northing_, char zone_, char designator_, double alt=0.0) { 00624 set(easting_, northing_, zone_, designator_, alt); 00625 } 00626 00629 UTM(LLA const &lla, ReferenceEllipsoid const &ref = GeoRef::WGS84, char zone = -1); 00630 00633 UTM(ECEF const &ecef, ReferenceEllipsoid const &ref = GeoRef::WGS84); 00634 00637 UTM const &operator = (LLA const &lla); 00638 00641 UTM const &operator = (ECEF const &ecef); 00642 00643 virtual ~UTM() {} 00644 00653 void set(double easting_, double northing_, 00654 char zone_, char designator_, double alt=0.0) { 00655 _E = easting_; 00656 _N = northing_; 00657 _zone = zone_; 00658 _designator = designator_; 00659 _alt = alt; 00660 // XXX check values 00661 } 00662 00670 void set(double easting_, double northing_, const char *zone_, double alt = 0.0); 00671 00674 inline double easting() const { return _E; } 00675 00678 inline double northing() const { return _N; } 00679 00682 inline char zone() const { return _zone; } 00683 00686 inline char designator() const { return _designator; } 00687 00690 inline double altitude() const { return _alt; } 00691 00694 virtual std::string asString() const; 00695 00698 virtual std::string typeString() const { return "type::UTM"; } 00699 00707 void parseXML(const char *); 00708 00711 bool valid() const; 00712 00715 virtual void serialize(Archive&); 00716 }; 00717 00727 class SIMDATA_EXPORT ECEF: public Vector3 { 00728 public: 00731 ECEF(): Vector3(0.0, 0.0, 0.0) {} 00732 00735 ECEF(double x_, double y_, double z_): Vector3(x_, y_, z_) {} 00736 00739 ECEF(UTM const &, ReferenceEllipsoid const & = GeoRef::WGS84); 00740 00743 ECEF(LLA const &, ReferenceEllipsoid const & = GeoRef::WGS84); 00744 00747 ECEF const &operator = (UTM const &); 00748 00751 ECEF const &operator = (LLA const &); 00752 00755 virtual std::string typeString() const { return "type::ECEF"; } 00756 00757 virtual ~ECEF() {} 00758 }; 00759 00760 NAMESPACE_SIMDATA_END 00761 00762 00763 #endif //__SIMDATA_GEOPOS_H__ 00764
|
SimData version pre-0.4.0. For more information on SimData, visit the SimData Homepage. Generated on Tue Oct 14 12:06:38 2003, using Doxygen 1.2.18. |