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