GeographicLib 1.52
Loading...
Searching...
No Matches
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-2020) <charles@karney.com> and licensed
6 * under the MIT/X11 License. For more information, see
7 * https://geographiclib.sourceforge.io/
8 **********************************************************************/
9
12#include <GeographicLib/DMS.hpp>
14
15namespace 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 using std::isnan; // Needed for Centos 7, ubuntu 14
64 prec = max(0, min(9 + Math::extra_digits(), prec) + 5);
65 ostringstream os;
66 os << fixed << setprecision(prec);
67 real a = longfirst ? _long : _lat;
68 real b = longfirst ? _lat : _long;
69 if (!isnan(a))
70 os << a;
71 else
72 os << "nan";
73 os << " ";
74 if (!isnan(b))
75 os << b;
76 else
77 os << "nan";
78 return os.str();
79 }
80
81 string GeoCoords::DMSRepresentation(int prec, bool longfirst,
82 char dmssep) const {
83 prec = max(0, min(10 + Math::extra_digits(), prec) + 5);
84 return DMS::Encode(longfirst ? _long : _lat, unsigned(prec),
85 longfirst ? DMS::LONGITUDE : DMS::LATITUDE, dmssep) +
86 " " + DMS::Encode(longfirst ? _lat : _long, unsigned(prec),
87 longfirst ? DMS::LATITUDE : DMS::LONGITUDE, dmssep);
88 }
89
90 string GeoCoords::MGRSRepresentation(int prec) const {
91 // Max precision is um
92 prec = max(-1, min(6, prec) + 5);
93 string mgrs;
94 MGRS::Forward(_zone, _northp, _easting, _northing, _lat, prec, mgrs);
95 return mgrs;
96 }
97
98 string GeoCoords::AltMGRSRepresentation(int prec) const {
99 // Max precision is um
100 prec = max(-1, min(6, prec) + 5);
101 string mgrs;
102 MGRS::Forward(_alt_zone, _northp, _alt_easting, _alt_northing, _lat, prec,
103 mgrs);
104 return mgrs;
105 }
106
107 void GeoCoords::UTMUPSString(int zone, bool northp,
108 real easting, real northing, int prec,
109 bool abbrev, string& utm) {
110 ostringstream os;
111 prec = max(-5, min(9 + Math::extra_digits(), prec));
112 // Need extra real because, since C++11, pow(float, int) returns double
113 real scale = prec < 0 ? real(pow(real(10), -prec)) : real(1);
114 os << UTMUPS::EncodeZone(zone, northp, abbrev) << fixed << setfill('0');
115 if (isfinite(easting)) {
116 os << " " << Utility::str(easting / scale, max(0, prec));
117 if (prec < 0 && abs(easting / scale) > real(0.5))
118 os << setw(-prec) << 0;
119 } else
120 os << " nan";
121 if (isfinite(northing)) {
122 os << " " << Utility::str(northing / scale, max(0, prec));
123 if (prec < 0 && abs(northing / scale) > real(0.5))
124 os << setw(-prec) << 0;
125 } else
126 os << " nan";
127 utm = os.str();
128 }
129
130 string GeoCoords::UTMUPSRepresentation(int prec, bool abbrev) const {
131 string utm;
132 UTMUPSString(_zone, _northp, _easting, _northing, prec, abbrev, utm);
133 return utm;
134 }
135
136 string GeoCoords::UTMUPSRepresentation(bool northp, int prec,
137 bool abbrev) const {
138 real e, n;
139 int z;
140 UTMUPS::Transfer(_zone, _northp, _easting, _northing,
141 _zone, northp, e, n, z);
142 string utm;
143 UTMUPSString(_zone, northp, e, n, prec, abbrev, utm);
144 return utm;
145 }
146
147 string GeoCoords::AltUTMUPSRepresentation(int prec, bool abbrev) const {
148 string utm;
149 UTMUPSString(_alt_zone, _northp, _alt_easting, _alt_northing, prec,
150 abbrev, utm);
151 return utm;
152 }
153
154 string GeoCoords::AltUTMUPSRepresentation(bool northp, int prec,
155 bool abbrev) const {
156 real e, n;
157 int z;
158 UTMUPS::Transfer(_alt_zone, _northp, _alt_easting, _alt_northing,
159 _alt_zone, northp, e, n, z);
160 string utm;
161 UTMUPSString(_alt_zone, northp, e, n, prec, abbrev, utm);
162 return utm;
163 }
164
165 void GeoCoords::FixHemisphere() {
166 using std::isnan; // Needed for Centos 7, ubuntu 14
167 if (_lat == 0 || (_northp && _lat >= 0) || (!_northp && _lat < 0) ||
168 isnan(_lat))
169 // Allow either hemisphere for equator
170 return;
171 if (_zone != UTMUPS::UPS) {
172 _northing += (_northp ? 1 : -1) * UTMUPS::UTMShift();
173 _northp = !_northp;
174 } else
175 throw GeographicErr("Hemisphere mixup");
176 }
177
178} // namespace GeographicLib
Header for GeographicLib::DMS class.
Header for GeographicLib::GeoCoords class.
GeographicLib::Math::real real
Definition: GeodSolve.cpp:31
Header for GeographicLib::MGRS class.
Header for GeographicLib::Utility class.
static std::string Encode(real angle, component trailing, unsigned prec, flag ind=NONE, char dmssep=char(0))
Definition: DMS.cpp:403
static void DecodeLatLon(const std::string &dmsa, const std::string &dmsb, real &lat, real &lon, bool longfirst=false)
Definition: DMS.cpp:356
std::string DMSRepresentation(int prec=0, bool longfirst=false, char dmssep=char(0)) const
Definition: GeoCoords.cpp:81
void Reset(const std::string &s, bool centerp=true, bool longfirst=false)
Definition: GeoCoords.cpp:19
std::string AltMGRSRepresentation(int prec=0) const
Definition: GeoCoords.cpp:98
std::string UTMUPSRepresentation(int prec=0, bool abbrev=true) const
Definition: GeoCoords.cpp:130
std::string GeoRepresentation(int prec=0, bool longfirst=false) const
Definition: GeoCoords.cpp:62
std::string AltUTMUPSRepresentation(int prec=0, bool abbrev=true) const
Definition: GeoCoords.cpp:147
std::string MGRSRepresentation(int prec=0) const
Definition: GeoCoords.cpp:90
Exception handling for GeographicLib.
Definition: Constants.hpp:315
static void Reverse(const std::string &mgrs, int &zone, bool &northp, real &x, real &y, int &prec, bool centerp=true)
Definition: MGRS.cpp:157
static void Forward(int zone, bool northp, real x, real y, int prec, std::string &mgrs)
Definition: MGRS.cpp:122
static T AngNormalize(T x)
Definition: Math.hpp:420
static int extra_digits()
Definition: Math.cpp:51
static std::string EncodeZone(int zone, bool northp, bool abbrev=true)
Definition: UTMUPS.cpp:253
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:65
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:119
static Math::real UTMShift()
Definition: UTMUPS.cpp:297
static void Transfer(int zonein, bool northpin, real xin, real yin, int zoneout, bool northpout, real &xout, real &yout, int &zone)
Definition: UTMUPS.cpp:173
static void DecodeZone(const std::string &zonestr, int &zone, bool &northp)
Definition: UTMUPS.cpp:207
static std::string str(T x, int p=-1)
Definition: Utility.hpp:276
Namespace for GeographicLib.
Definition: Accumulator.cpp:12