src/UTMUPS.cpp
Go to the documentation of this file.
1 
10 #include <GeographicLib/UTMUPS.hpp>
11 #include <GeographicLib/MGRS.hpp>
15 
16 namespace GeographicLib {
17 
18  using namespace std;
19 
20  const int UTMUPS::falseeasting_[] =
23  const int UTMUPS::falsenorthing_[] =
26  const int UTMUPS::mineasting_[] =
29  const int UTMUPS::maxeasting_[] =
32  const int UTMUPS::minnorthing_[] =
36  * MGRS::tile_ };
37  const int UTMUPS::maxnorthing_[] =
42 
43  int UTMUPS::StandardZone(real lat, real lon, int setzone) {
44  if (!(setzone >= MINPSEUDOZONE && setzone <= MAXZONE))
45  throw GeographicErr("Illegal zone requested " + Utility::str(setzone));
46  if (setzone >= MINZONE || setzone == INVALID)
47  return setzone;
48  if (Math::isnan(lat) || Math::isnan(lon)) // Check if lat or lon is a NaN
49  return INVALID;
50  if (setzone == UTM || (lat >= -80 && lat < 84)) {
51  int ilon = int(floor(fmod(lon, real(360))));
52  if (ilon >= 180)
53  ilon -= 360;
54  else if (ilon < -180)
55  ilon += 360;
56  int zone = (ilon + 186)/6;
58  if (band == 7 && zone == 31 && ilon >= 3) // The Norway exception
59  zone = 32;
60  else if (band == 9 && ilon >= 0 && ilon < 42) // The Svalbard exception
61  zone = 2 * ((ilon + 183)/12) + 1;
62  return zone;
63  } else
64  return UPS;
65  }
66 
68  int& zone, bool& northp, real& x, real& y,
69  real& gamma, real& k,
70  int setzone, bool mgrslimits) {
71  if (abs(lat) > 90)
72  throw GeographicErr("Latitude " + Utility::str(lat)
73  + "d not in [-90d, 90d]");
74  bool northp1 = lat >= 0;
75  int zone1 = StandardZone(lat, lon, setzone);
76  if (zone1 == INVALID) {
77  zone = zone1;
78  northp = northp1;
79  x = y = gamma = k = Math::NaN();
80  return;
81  }
82  real x1, y1, gamma1, k1;
83  bool utmp = zone1 != UPS;
84  if (utmp) {
85  real
86  lon0 = CentralMeridian(zone1),
87  dlon = lon - lon0;
88  dlon = abs(dlon - 360 * floor((dlon + 180)/360));
89  if (!(dlon <= 60))
90  // Check isn't really necessary because CheckCoords catches this case.
91  // But this allows a more meaningful error message to be given.
92  throw GeographicErr("Longitude " + Utility::str(lon)
93  + "d more than 60d from center of UTM zone "
94  + Utility::str(zone1));
96  } else {
97  if (abs(lat) < 70)
98  // Check isn't really necessary ... (see above).
99  throw GeographicErr("Latitude " + Utility::str(lat)
100  + "d more than 20d from "
101  + (northp1 ? "N" : "S") + " pole");
102  PolarStereographic::UPS().Forward(northp1, lat, lon, x1, y1, gamma1, k1);
103  }
104  int ind = (utmp ? 2 : 0) + (northp1 ? 1 : 0);
105  x1 += falseeasting_[ind];
106  y1 += falsenorthing_[ind];
107  if (! CheckCoords(zone1 != UPS, northp1, x1, y1, mgrslimits, false) )
108  throw GeographicErr("Latitude " + Utility::str(lat)
109  + ", longitude " + Utility::str(lon)
110  + " out of legal range for "
111  + (utmp ? "UTM zone " + Utility::str(zone1) :
112  "UPS"));
113  zone = zone1;
114  northp = northp1;
115  x = x1;
116  y = y1;
117  gamma = gamma1;
118  k = k1;
119  }
120 
121  void UTMUPS::Reverse(int zone, bool northp, real x, real y,
122  real& lat, real& lon, real& gamma, real& k,
123  bool mgrslimits) {
124  if (zone == INVALID || Math::isnan(x) || Math::isnan(y)) {
125  lat = lon = gamma = k = Math::NaN();
126  return;
127  }
128  if (!(zone >= MINZONE && zone <= MAXZONE))
129  throw GeographicErr("Zone " + Utility::str(zone)
130  + " not in range [0, 60]");
131  bool utmp = zone != UPS;
132  CheckCoords(utmp, northp, x, y, mgrslimits);
133  int ind = (utmp ? 2 : 0) + (northp ? 1 : 0);
134  x -= falseeasting_[ind];
135  y -= falsenorthing_[ind];
136  if (utmp)
137  TransverseMercator::UTM().Reverse(CentralMeridian(zone),
138  x, y, lat, lon, gamma, k);
139  else
140  PolarStereographic::UPS().Reverse(northp, x, y, lat, lon, gamma, k);
141  }
142 
143  bool UTMUPS::CheckCoords(bool utmp, bool northp, real x, real y,
144  bool mgrslimits, bool throwp) {
145  // Limits are all multiples of 100km and are all closed on the both ends.
146  // Failure tests are such that NaNs succeed.
147  real slop = mgrslimits ? 0 : MGRS::tile_;
148  int ind = (utmp ? 2 : 0) + (northp ? 1 : 0);
149  if (x < mineasting_[ind] - slop || x > maxeasting_[ind] + slop) {
150  if (!throwp) return false;
151  throw GeographicErr("Easting " + Utility::str(x/1000) + "km not in "
152  + (mgrslimits ? "MGRS/" : "")
153  + (utmp ? "UTM" : "UPS") + " range for "
154  + (northp ? "N" : "S" ) + " hemisphere ["
155  + Utility::str((mineasting_[ind] - slop)/1000)
156  + "km, "
157  + Utility::str((maxeasting_[ind] + slop)/1000)
158  + "km]");
159  }
160  if (y < minnorthing_[ind] - slop || y > maxnorthing_[ind] + slop) {
161  if (!throwp) return false;
162  throw GeographicErr("Northing " + Utility::str(y/1000) + "km not in "
163  + (mgrslimits ? "MGRS/" : "")
164  + (utmp ? "UTM" : "UPS") + " range for "
165  + (northp ? "N" : "S" ) + " hemisphere ["
166  + Utility::str((minnorthing_[ind] - slop)/1000)
167  + "km, "
168  + Utility::str((maxnorthing_[ind] + slop)/1000)
169  + "km]");
170  }
171  return true;
172  }
173 
174  void UTMUPS::Transfer(int zonein, bool northpin, real xin, real yin,
175  int zoneout, bool northpout, real& xout, real& yout,
176  int& zone) {
177  bool northp = northpin;
178  if (zonein != zoneout) {
179  // Determine lat, lon
180  real lat, lon;
181  GeographicLib::UTMUPS::Reverse(zonein, northpin, xin, yin, lat, lon);
182  // Try converting to zoneout
183  real x, y;
184  int zone1;
185  GeographicLib::UTMUPS::Forward(lat, lon, zone1, northp, x, y,
186  zoneout == UTMUPS::MATCH
187  ? zonein : zoneout);
188  if (zone1 == 0 && northp != northpout)
189  throw GeographicErr
190  ("Attempt to transfer UPS coordinates between hemispheres");
191  zone = zone1;
192  xout = x;
193  yout = y;
194  } else {
195  if (zoneout == 0 && northp != northpout)
196  throw GeographicErr
197  ("Attempt to transfer UPS coordinates between hemispheres");
198  zone = zoneout;
199  xout = xin;
200  yout = yin;
201  }
202  if (northp != northpout)
203  // Can't get here if UPS
204  yout += (northpout ? -1 : 1) * MGRS::utmNshift_;
205  return;
206  }
207 
208  void UTMUPS::DecodeZone(const std::string& zonestr, int& zone, bool& northp)
209  {
210  unsigned zlen = unsigned(zonestr.size());
211  if (zlen == 0)
212  throw GeographicErr("Empty zone specification");
213  // Longest zone spec is 32north, 42south, invalid = 7
214  if (zlen > 7)
215  throw GeographicErr("More than 7 characters in zone specification "
216  + zonestr);
217 
218  const char* c = zonestr.c_str();
219  char* q;
220  int zone1 = strtol(c, &q, 10);
221  // if (zone1 == 0) zone1 = UPS; (not necessary)
222 
223  if (zone1 == UPS) {
224  if (!(q == c))
225  // Don't allow 0n as an alternative to n for UPS coordinates
226  throw GeographicErr("Illegal zone 0 in " + zonestr +
227  ", use just the hemisphere for UPS");
228  } else if (!(zone1 >= MINUTMZONE && zone1 <= MAXUTMZONE))
229  throw GeographicErr("Zone " + Utility::str(zone1)
230  + " not in range [1, 60]");
231  else if (!isdigit(zonestr[0]))
232  throw GeographicErr("Must use unsigned number for zone "
233  + Utility::str(zone1));
234  else if (q - c > 2)
235  throw GeographicErr("More than 2 digits use to specify zone "
236  + Utility::str(zone1));
237 
238  string hemi(zonestr, q - c);
239  for (std::string::iterator p = hemi.begin(); p != hemi.end(); ++p)
240  *p = char(std::tolower(*p));
241  if (q == c && (hemi == "inv" || hemi == "invalid")) {
242  zone = INVALID;
243  northp = false;
244  return;
245  }
246  bool northp1 = hemi == "north" || hemi == "n";
247  if (!(northp1 || hemi == "south" || hemi == "s"))
248  throw GeographicErr(string("Illegal hemisphere ") + hemi + " in "
249  + zonestr + ", specify north or south");
250  zone = zone1;
251  northp = northp1;
252  }
253 
254  std::string UTMUPS::EncodeZone(int zone, bool northp, bool abbrev) {
255  if (zone == INVALID)
256  return string(abbrev ? "inv" : "invalid");
257  if (!(zone >= MINZONE && zone <= MAXZONE))
258  throw GeographicErr("Zone " + Utility::str(zone)
259  + " not in range [0, 60]");
260  ostringstream os;
261  if (zone != UPS)
262  os << setfill('0') << setw(2) << zone;
263  if (abbrev)
264  os << (northp ? 'n' : 's');
265  else
266  os << (northp ? "north" : "south");
267  return os.str();
268  }
269 
270  void UTMUPS::DecodeEPSG(int epsg, int& zone, bool& northp) {
271  northp = false;
272  if (epsg >= epsg01N && epsg <= epsg60N) {
273  zone = (epsg - epsg01N) + MINUTMZONE;
274  northp = true;
275  } else if (epsg == epsgN) {
276  zone = UPS;
277  northp = true;
278  } else if (epsg >= epsg01S && epsg <= epsg60S) {
279  zone = (epsg - epsg01S) + MINUTMZONE;
280  } else if (epsg == epsgS) {
281  zone = UPS;
282  } else {
283  zone = INVALID;
284  }
285  }
286 
287  int UTMUPS::EncodeEPSG(int zone, bool northp) {
288  int epsg = -1;
289  if (zone == UPS)
290  epsg = epsgS;
291  else if (zone >= MINUTMZONE && zone <= MAXUTMZONE)
292  epsg = (zone - MINUTMZONE) + epsg01S;
293  if (epsg >= 0 && northp)
294  epsg += epsgN - epsgS;
295  return epsg;
296  }
297 
299 
300 } // namespace GeographicLib
ind
std::vector< int > ind
Definition: Slicing_stdvector_cxx11.cpp:1
gtsam.examples.DogLegOptimizerExample.int
int
Definition: DogLegOptimizerExample.py:111
PolarStereographic.hpp
Header for GeographicLib::PolarStereographic class.
GeographicLib::Math::NaN
static T NaN()
Definition: Math.hpp:830
GeographicLib::MGRS::maxupsNind_
@ maxupsNind_
Definition: MGRS.hpp:152
GeographicLib::Utility::str
static std::string str(T x, int p=-1)
Definition: Utility.hpp:276
GeographicLib::UTMUPS::mineasting_
static const int mineasting_[4]
Definition: UTMUPS.hpp:80
GeographicLib
Namespace for GeographicLib.
Definition: JacobiConformal.hpp:15
c
Scalar Scalar * c
Definition: benchVecAdd.cpp:17
GeographicLib::MGRS::LatitudeBand
static int LatitudeBand(real lat)
Definition: MGRS.hpp:109
x
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy x
Definition: gnuplot_common_settings.hh:12
GeographicLib::TransverseMercator::UTM
static const TransverseMercator & UTM()
Definition: src/TransverseMercator.cpp:277
GeographicLib::UTMUPS::EncodeZone
static std::string EncodeZone(int zone, bool northp, bool abbrev=true)
Definition: src/UTMUPS.cpp:254
real
float real
Definition: datatypes.h:10
GeographicLib::MGRS::minutmSrow_
@ minutmSrow_
Definition: MGRS.hpp:145
GeographicLib::UTMUPS::maxnorthing_
static const int maxnorthing_[4]
Definition: UTMUPS.hpp:83
GeographicLib::UTMUPS::maxeasting_
static const int maxeasting_[4]
Definition: UTMUPS.hpp:81
GeographicLib::UTMUPS::MATCH
@ MATCH
Definition: UTMUPS.hpp:122
os
ofstream os("timeSchurFactors.csv")
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: src/UTMUPS.cpp:174
GeographicLib::MGRS::maxupsSind_
@ maxupsSind_
Definition: MGRS.hpp:150
GeographicLib::UTMUPS::DecodeEPSG
static void DecodeEPSG(int epsg, int &zone, bool &northp)
Definition: src/UTMUPS.cpp:270
GeographicLib::MGRS::minupsSind_
@ minupsSind_
Definition: MGRS.hpp:149
GeographicLib::GeographicErr
Exception handling for GeographicLib.
Definition: Constants.hpp:389
GeographicLib::PolarStereographic::Reverse
void Reverse(bool northp, real x, real y, real &lat, real &lon, real &gamma, real &k) const
Definition: src/PolarStereographic.cpp:81
UTMUPS.hpp
Header for GeographicLib::UTMUPS class.
GeographicLib::UTMUPS::minnorthing_
static const int minnorthing_[4]
Definition: UTMUPS.hpp:82
GeographicLib::Math::real
double real
Definition: Math.hpp:129
GeographicLib::PolarStereographic::UPS
static const PolarStereographic & UPS()
Definition: src/PolarStereographic.cpp:33
y1
double y1(double x)
Definition: j1.c:199
GeographicLib::MGRS::utmNshift_
@ utmNshift_
Definition: MGRS.hpp:156
Eigen::bfloat16_impl::fmod
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 fmod(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:567
TransverseMercator.hpp
Header for GeographicLib::TransverseMercator class.
Eigen::numext::q
EIGEN_DEVICE_FUNC const Scalar & q
Definition: SpecialFunctionsImpl.h:1984
example::lon0
const double lon0
Definition: testGPSFactor.cpp:41
x1
Pose3 x1
Definition: testPose3.cpp:663
k1
double k1(double x)
Definition: k1.c:133
GeographicLib::TransverseMercator::Forward
void Forward(real lon0, real lat, real lon, real &x, real &y, real &gamma, real &k) const
Definition: src/TransverseMercator.cpp:350
Utility.hpp
Header for GeographicLib::Utility class.
GeographicLib::UTMUPS::EncodeEPSG
static int EncodeEPSG(int zone, bool northp)
Definition: src/UTMUPS.cpp:287
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: src/UTMUPS.cpp:67
MGRS.hpp
Header for GeographicLib::MGRS class.
GeographicLib::MGRS::maxutmSrow_
@ maxutmSrow_
Definition: MGRS.hpp:146
GeographicLib::MGRS::maxutmcol_
@ maxutmcol_
Definition: MGRS.hpp:144
gamma
#define gamma
Definition: mconf.h:85
GeographicLib::MGRS::maxutmNrow_
@ maxutmNrow_
Definition: MGRS.hpp:148
GeographicLib::UTMUPS::falsenorthing_
static const int falsenorthing_[4]
Definition: UTMUPS.hpp:79
GeographicLib::UTMUPS::DecodeZone
static void DecodeZone(const std::string &zonestr, int &zone, bool &northp)
Definition: src/UTMUPS.cpp:208
GeographicLib::Math::isnan
static bool isnan(T x)
Definition: Math.hpp:853
y
Scalar * y
Definition: level1_cplx_impl.h:124
GeographicLib::UTMUPS::UTMShift
static Math::real UTMShift()
Definition: src/UTMUPS.cpp:298
GeographicLib::MGRS::utmeasting_
@ utmeasting_
Definition: MGRS.hpp:154
GeographicLib::MGRS::minutmNrow_
@ minutmNrow_
Definition: MGRS.hpp:147
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: src/UTMUPS.cpp:121
std
Definition: BFloat16.h:88
p
float * p
Definition: Tutorial_Map_using.cpp:9
GeographicLib::TransverseMercator::Reverse
void Reverse(real lon0, real x, real y, real &lat, real &lon, real &gamma, real &k) const
Definition: src/TransverseMercator.cpp:516
GeographicLib::UTMUPS::StandardZone
static int StandardZone(real lat, real lon, int setzone=STANDARD)
Definition: src/UTMUPS.cpp:43
GeographicLib::MGRS::upseasting_
@ upseasting_
Definition: MGRS.hpp:153
GeographicLib::PolarStereographic::Forward
void Forward(bool northp, real lat, real lon, real &x, real &y, real &gamma, real &k) const
Definition: src/PolarStereographic.cpp:61
abs
#define abs(x)
Definition: datatypes.h:17
lon
static const double lon
Definition: testGeographicLib.cpp:34
INVALID
#define INVALID
Definition: gtsam/3rdparty/Eigen/blas/common.h:45
GeographicLib::MGRS::minutmcol_
@ minutmcol_
Definition: MGRS.hpp:143
real
Definition: main.h:100
GeographicLib::MGRS::minupsNind_
@ minupsNind_
Definition: MGRS.hpp:151
Eigen::internal::band
EIGEN_ALWAYS_INLINE void band(PacketBlock< Packet, 4 > &acc, const Packet &pMask)
Definition: MatrixProduct.h:1188
GeographicLib::MGRS::tile_
@ tile_
Definition: MGRS.hpp:142
GeographicLib::UTMUPS::CheckCoords
static bool CheckCoords(bool utmp, bool northp, real x, real y, bool msgrlimits=false, bool throwp=true)
Definition: src/UTMUPS.cpp:143
floor
const EIGEN_DEVICE_FUNC FloorReturnType floor() const
Definition: ArrayCwiseUnaryOps.h:481
lat
static const double lat
Definition: testGeographicLib.cpp:34
GeographicLib::UTMUPS::falseeasting_
static const int falseeasting_[4]
Definition: UTMUPS.hpp:78


gtsam
Author(s):
autogenerated on Tue Jun 25 2024 03:07:55