GeographicLib  1.37
GeoCoords.cpp
Go to the documentation of this file.
1 /**
2  * \file GeoCoords.cpp
3  * \brief Implementation for GeographicLib::GeoCoords class
4  *
5  * Copyright (c) Charles Karney (2008-2011) <charles@karney.com> and licensed
6  * under the MIT/X11 License. For more information, see
7  * http://geographiclib.sourceforge.net/
8  **********************************************************************/
9 
11 #include <GeographicLib/MGRS.hpp>
12 #include <GeographicLib/DMS.hpp>
13 
14 namespace GeographicLib {
15 
16  using namespace std;
17 
18  void GeoCoords::Reset(const std::string& s, bool centerp, bool swaplatlong) {
19  vector<string> sa;
20  const char* spaces = " \t\n\v\f\r,"; // Include comma as a space
21  for (string::size_type pos0 = 0, pos1; pos0 != string::npos;) {
22  pos1 = s.find_first_not_of(spaces, pos0);
23  if (pos1 == string::npos)
24  break;
25  pos0 = s.find_first_of(spaces, pos1);
26  sa.push_back(s.substr(pos1, pos0 == string::npos ? pos0 : pos0 - pos1));
27  }
28  if (sa.size() == 1) {
29  int prec;
30  MGRS::Reverse(sa[0], _zone, _northp, _easting, _northing, prec, centerp);
31  UTMUPS::Reverse(_zone, _northp, _easting, _northing,
32  _lat, _long, _gamma, _k);
33  } else if (sa.size() == 2) {
34  DMS::DecodeLatLon(sa[0], sa[1], _lat, _long, swaplatlong);
35  UTMUPS::Forward( _lat, _long,
36  _zone, _northp, _easting, _northing, _gamma, _k);
37  } else if (sa.size() == 3) {
38  unsigned zoneind, coordind;
39  if (sa[0].size() > 0 && isalpha(sa[0][sa[0].size() - 1])) {
40  zoneind = 0;
41  coordind = 1;
42  } else if (sa[2].size() > 0 && isalpha(sa[2][sa[2].size() - 1])) {
43  zoneind = 2;
44  coordind = 0;
45  } else
46  throw GeographicErr("Neither " + sa[0] + " nor " + sa[2]
47  + " of the form UTM/UPS Zone + Hemisphere"
48  + " (ex: 38n, 09s, n)");
49  UTMUPS::DecodeZone(sa[zoneind], _zone, _northp);
50  for (unsigned i = 0; i < 2; ++i)
51  (i ? _northing : _easting) = DMS::Decode(sa[coordind + i]);
52  UTMUPS::Reverse(_zone, _northp, _easting, _northing,
53  _lat, _long, _gamma, _k);
54  FixHemisphere();
55  } else
56  throw GeographicErr("Coordinate requires 1, 2, or 3 elements");
57  CopyToAlt();
58  }
59 
60  string GeoCoords::GeoRepresentation(int prec, bool swaplatlong) const {
61  prec = max(0, min(9 + Math::extra_digits(), prec) + 5);
62  ostringstream os;
63  os << fixed << setprecision(prec);
64  real a = swaplatlong ? _long : _lat;
65  real b = swaplatlong ? _lat : _long;
66  if (!Math::isnan(a))
67  os << a;
68  else
69  os << "nan";
70  os << " ";
71  if (!Math::isnan(b))
72  os << b;
73  else
74  os << "nan";
75  return os.str();
76  }
77 
78  string GeoCoords::DMSRepresentation(int prec, bool swaplatlong,
79  char dmssep) const {
80  prec = max(0, min(10 + Math::extra_digits(), prec) + 5);
81  return DMS::Encode(swaplatlong ? _long : _lat, unsigned(prec),
82  swaplatlong ? DMS::LONGITUDE : DMS::LATITUDE, dmssep) +
83  " " + DMS::Encode(swaplatlong ? _lat : _long, unsigned(prec),
84  swaplatlong ? DMS::LATITUDE : DMS::LONGITUDE, dmssep);
85  }
86 
87  string GeoCoords::MGRSRepresentation(int prec) const {
88  // Max precision is um
89  prec = max(-1, min(6, prec) + 5);
90  string mgrs;
91  MGRS::Forward(_zone, _northp, _easting, _northing, _lat, prec, mgrs);
92  return mgrs;
93  }
94 
95  string GeoCoords::AltMGRSRepresentation(int prec) const {
96  // Max precision is um
97  prec = max(-1, min(6, prec) + 5);
98  string mgrs;
99  MGRS::Forward(_alt_zone, _northp, _alt_easting, _alt_northing, _lat, prec,
100  mgrs);
101  return mgrs;
102  }
103 
104  void GeoCoords::UTMUPSString(int zone, bool northp,
105  real easting, real northing, int prec,
106  bool abbrev, std::string& utm) {
107  ostringstream os;
108  prec = max(-5, min(9 + Math::extra_digits(), prec));
109  real scale = prec < 0 ? pow(real(10), -prec) : real(1);
110  os << UTMUPS::EncodeZone(zone, northp, abbrev) << fixed << setfill('0');
111  if (Math::isfinite(easting)) {
112  os << " " << setprecision(max(0, prec)) << easting / scale;
113  if (prec < 0 && abs(easting / scale) > real(0.5))
114  os << setw(-prec) << 0;
115  } else
116  os << " nan";
117  if (Math::isfinite(northing)) {
118  os << " " << setprecision(max(0, prec)) << northing / scale;
119  if (prec < 0 && abs(northing / scale) > real(0.5))
120  os << setw(-prec) << 0;
121  } else
122  os << " nan";
123  utm = os.str();
124  }
125 
126  string GeoCoords::UTMUPSRepresentation(int prec, bool abbrev) const {
127  string utm;
128  UTMUPSString(_zone, _northp, _easting, _northing, prec, abbrev, utm);
129  return utm;
130  }
131 
132  string GeoCoords::UTMUPSRepresentation(bool northp, int prec, bool abbrev)
133  const {
134  real e, n;
135  int z;
136  UTMUPS::Transfer(_zone, _northp, _easting, _northing,
137  _zone, northp, e, n, z);
138  string utm;
139  UTMUPSString(_zone, northp, e, n, prec, abbrev, utm);
140  return utm;
141  }
142 
143  string GeoCoords::AltUTMUPSRepresentation(int prec, bool abbrev) const {
144  string utm;
145  UTMUPSString(_alt_zone, _northp, _alt_easting, _alt_northing, prec,
146  abbrev, utm);
147  return utm;
148  }
149 
150  string GeoCoords::AltUTMUPSRepresentation(bool northp, int prec, bool abbrev)
151  const {
152  real e, n;
153  int z;
154  UTMUPS::Transfer(_alt_zone, _northp, _alt_easting, _alt_northing,
155  _alt_zone, northp, e, n, z);
156  string utm;
157  UTMUPSString(_alt_zone, northp, e, n, prec, abbrev, utm);
158  return utm;
159  }
160 
161  void GeoCoords::FixHemisphere() {
162  if (_lat == 0 || (_northp && _lat >= 0) || (!_northp && _lat < 0) ||
163  Math::isnan(_lat))
164  // Allow either hemisphere for equator
165  return;
166  if (_zone != UTMUPS::UPS) {
167  _northing += (_northp ? 1 : -1) * UTMUPS::UTMShift();
168  _northp = !_northp;
169  } else
170  throw GeographicErr("Hemisphere mixup");
171  }
172 
173 } // namespace GeographicLib
static std::string EncodeZone(int zone, bool northp, bool abbrev=true)
Definition: UTMUPS.cpp:258
std::string GeoRepresentation(int prec=0, bool swaplatlong=false) const
Definition: GeoCoords.cpp:60
GeographicLib::Math::real real
Definition: GeodSolve.cpp:40
static bool isfinite(T x)
Definition: Math.hpp:445
static bool isnan(T x)
Definition: Math.hpp:477
static void Transfer(int zonein, bool northpin, real xin, real yin, int zoneout, bool northpout, real &xout, real &yout, int &zone)
Definition: UTMUPS.cpp:180
std::string AltUTMUPSRepresentation(int prec=0, bool abbrev=true) const
Definition: GeoCoords.cpp:143
std::string DMSRepresentation(int prec=0, bool swaplatlong=false, char dmssep=char(0)) const
Definition: GeoCoords.cpp:78
Header for GeographicLib::GeoCoords class.
Header for GeographicLib::MGRS class.
static int extra_digits()
Definition: Math.hpp:184
void Reset(const std::string &s, bool centerp=true, bool swaplatlong=false)
Definition: GeoCoords.cpp:18
static void Forward(real lat, real lon, int &zone, bool &northp, real &x, real &y, real &gamma, real &k, int setzone=STANDARD, bool mgrslimits=false)
Definition: UTMUPS.cpp:67
static std::string Encode(real angle, component trailing, unsigned prec, flag ind=NONE, char dmssep=char(0))
Definition: DMS.cpp:265
static void DecodeLatLon(const std::string &dmsa, const std::string &dmsb, real &lat, real &lon, bool swaplatlong=false)
Definition: DMS.cpp:213
static Math::real Decode(const std::string &dms, flag &ind)
Definition: DMS.cpp:28
std::string AltMGRSRepresentation(int prec=0) const
Definition: GeoCoords.cpp:95
Namespace for GeographicLib.
Definition: Accumulator.cpp:12
static void DecodeZone(const std::string &zonestr, int &zone, bool &northp)
Definition: UTMUPS.cpp:214
static void Reverse(int zone, bool northp, real x, real y, real &lat, real &lon, real &gamma, real &k, bool mgrslimits=false)
Definition: UTMUPS.cpp:118
static void Reverse(const std::string &mgrs, int &zone, bool &northp, real &x, real &y, int &prec, bool centerp=true)
Definition: MGRS.cpp:158
Exception handling for GeographicLib.
Definition: Constants.hpp:362
std::string MGRSRepresentation(int prec=0) const
Definition: GeoCoords.cpp:87
static Math::real UTMShift()
Definition: UTMUPS.cpp:302
static void Forward(int zone, bool northp, real x, real y, int prec, std::string &mgrs)
Definition: MGRS.cpp:123
std::string UTMUPSRepresentation(int prec=0, bool abbrev=true) const
Definition: GeoCoords.cpp:126
Header for GeographicLib::DMS class.