18 const char*
const MGRS::utmcols_[] = {
"ABCDEFGH",
"JKLMNPQR",
"STUVWXYZ" };
21 {
"JKLPQRSTUXYZ",
"ABCFGHJKLPQR",
"RSTUXYZ",
"ABCFGHJ" };
23 {
"ABCDEFGHJKLMNPQRSTUVWXYZ",
"ABCDEFGHJKLMNP" };
29 { minupsSind_, minupsNind_, minutmcol_, minutmcol_ };
31 { maxupsSind_, maxupsNind_, maxutmcol_, maxutmcol_ };
33 { minupsSind_, minupsNind_,
34 minutmSrow_, minutmSrow_ - (maxutmSrow_ - minutmNrow_) };
36 { maxupsSind_, maxupsNind_,
37 maxutmNrow_ + (maxutmSrow_ - minutmNrow_), maxutmNrow_ };
40 int prec, std::string& mgrs) {
49 bool utmp = zone != 0;
50 CheckCoords(utmp, northp, x, y);
53 if (!(prec >= -1 && prec <= maxprec_))
59 char mgrs1[2 + 3 + 2 * maxprec_];
63 mlen = z + 3 + 2 * prec;
65 mgrs1[0] = digits_[ zone / base_ ];
66 mgrs1[1] = digits_[ zone % base_ ];
72 GEOGRAPHICLIB_STATIC_ASSERT(numeric_limits<long long>::digits >= 44,
73 "long long not wide enough to store 10e12");
75 ix = (
long long)(
floor(x * mult_)),
76 iy = (
long long)(
floor(y * mult_)),
77 m = (
long long)(mult_) * (
long long)(tile_);
78 int xh =
int(ix /
m), yh =
int(iy /
m);
82 iband =
abs(lat) > angeps ? LatitudeBand(lat) : (northp ? 0 : -1),
83 icol = xh - minutmcol_,
84 irow = UTMRow(iband, icol, yh % utmrowperiod_);
85 if (irow != yh - (northp ? minutmNrow_ : maxutmSrow_))
87 +
" is inconsistent with UTM coordinates");
88 mgrs1[z++] = latband_[10 + iband];
89 mgrs1[z++] = utmcols_[zone1 % 3][icol];
90 mgrs1[z++] = utmrow_[(yh + (zone1 & 1 ? utmevenrowshift_ : 0))
93 bool eastp = xh >= upseasting_;
94 int iband = (northp ? 2 : 0) + (eastp ? 1 : 0);
95 mgrs1[z++] = upsband_[iband];
96 mgrs1[z++] = upscols_[iband][xh - (eastp ? upseasting_ :
97 (northp ? minupsNind_ :
99 mgrs1[z++] = upsrows_[northp][yh - (northp ? minupsNind_ : minupsSind_)];
102 ix -=
m * xh; iy -=
m * yh;
103 long long d = (
long long)(
pow(
real(base_), maxprec_ - prec));
105 for (
int c = prec;
c--;) {
106 mgrs1[z +
c ] = digits_[ix % base_]; ix /= base_;
107 mgrs1[z +
c + prec] = digits_[iy % base_]; iy /= base_;
111 copy(mgrs1, mgrs1 + mlen, mgrs.begin());
115 int prec, std::string& mgrs) {
119 real ys = northp ? y : y - utmNshift_;
128 lat =
real(0.9) * ys;
133 latp =
real(0.901) * ys + (ys > 0 ? 1 : -1) *
real(0.135),
136 late =
real(0.902) * ys * (1 -
real(1.85
e-6) * ys * ys);
137 if (LatitudeBand(latp) == LatitudeBand(late))
146 Forward(zone, northp, x, y, lat, prec, mgrs);
151 int& prec,
bool centerp) {
156 toupper(mgrs[0]) ==
'I' &&
157 toupper(mgrs[1]) ==
'N' &&
158 toupper(mgrs[2]) ==
'V') {
170 zone1 = 10 * zone1 +
i;
177 + mgrs.substr(0, p));
181 int zonem1 = zone1 - 1;
182 const char* band = utmp ? latband_ : upsband_;
186 + (utmp ?
"UTM" :
"UPS") +
" set " + band);
187 bool northp1 = iband >= (utmp ? 10 : 2);
190 real deg =
real(utmNshift_) / (90 * tile_);
195 x = ((zone == 31 && iband == 17) ? 4 : 5) * tile_;
198 + (northp ? 0 : utmNshift_);
201 x = ((iband & 1 ? 1 : -1) *
floor(4 * deg +
real(0.5))
202 + upseasting_) * tile_;
204 y = upseasting_ * tile_;
208 }
else if (
len - p < 2)
210 const char*
col = utmp ? utmcols_[zonem1 % 3] : upscols_[iband];
211 const char*
row = utmp ? utmrow_ : upsrows_[northp1];
216 + (utmp ?
"zone " + mgrs.substr(0, p-2) :
227 irow = (irow + utmrowperiod_ - utmevenrowshift_) % utmrowperiod_;
229 irow = UTMRow(iband, icol, irow);
230 if (irow == maxutmSrow_)
232 +
" not in zone/band " + mgrs.substr(0, p-2));
234 irow = northp1 ? irow : irow + 100;
235 icol = icol + minutmcol_;
237 bool eastp = iband & 1;
238 icol += eastp ? upseasting_ : (northp1 ? minupsNind_ : minupsSind_);
239 irow += northp1 ? minupsNind_ : minupsSind_;
241 int prec1 = (
len -
p)/2;
246 for (
int i = 0;
i < prec1; ++
i) {
251 if (ix < 0 || iy < 0)
252 throw GeographicErr(
"Encountered a non-digit in " + mgrs.substr(p));
253 x1 = base_ * x1 + ix;
254 y1 = base_ * y1 + iy;
258 throw GeographicErr(
"Encountered a non-digit in " + mgrs.substr(p));
263 if (prec1 > maxprec_)
265 +
" digits in " + mgrs.substr(p));
267 unit *= 2;
x1 = 2 *
x1 + 1; y1 = 2 * y1 + 1;
271 x = (tile_ *
x1) / unit;
272 y = (tile_ * y1) / unit;
290 ind = (utmp ? 2 : 0) + (northp ? 1 : 0);
291 if (! (ix >= mineasting_[ind] && ix < maxeasting_[ind]) ) {
292 if (ix == maxeasting_[ind] && x == maxeasting_[ind] * tile_)
297 + (utmp ?
"UTM" :
"UPS") +
" range for " 298 + (northp ?
"N" :
"S" ) +
" hemisphere [" 304 if (! (iy >= minnorthing_[ind] && iy < maxnorthing_[ind]) ) {
305 if (iy == maxnorthing_[ind] && y == maxnorthing_[ind] * tile_)
310 + (utmp ?
"UTM" :
"UPS") +
" range for " 311 + (northp ?
"N" :
"S" ) +
" hemisphere [" 320 if (northp && iy < minutmNrow_) {
323 }
else if (!northp && iy >= maxutmSrow_) {
324 if (y == maxutmSrow_ * tile_)
345 bool northp = iband >= 0;
369 minrow = iband > -10 ?
373 baserow = (minrow + maxrow) / 2 - utmrowperiod_ / 2;
377 irow = (irow - baserow + maxutmSrow_) % utmrowperiod_ + baserow;
378 if (!( irow >= minrow && irow <= maxrow )) {
387 sband = iband >= 0 ? iband : -iband - 1,
389 srow = irow >= 0 ? irow : -irow - 1,
391 scol = icol < 4 ? icol : -icol + 7;
394 if ( ! ( (srow == 70 && sband == 8 && scol >= 2) ||
395 (srow == 71 && sband == 7 && scol <= 2) ||
396 (srow == 79 && sband == 9 && scol >= 1) ||
397 (srow == 80 && sband == 8 && scol <= 1) ) )
407 throw GeographicErr(
"MGRS::Check: equator coverage failure");
410 throw GeographicErr(
"MGRS::Check: UTM doesn't reach latitude = 84");
413 throw GeographicErr(
"MGRS::Check: UTM doesn't reach latitude = -80");
416 throw GeographicErr(
"MGRS::Check: Norway exception creates a gap");
419 throw GeographicErr(
"MGRS::Check: Svalbard exception creates a gap");
423 GeographicErr(
"MGRS::Check: North UPS doesn't reach latitude = 84");
427 GeographicErr(
"MGRS::Check: South UPS doesn't reach latitude = -80");
430 const short tab[] = {
446 7, 5, 70, 7, 7, 70, 7, 7, 71, 7, 9, 71,
447 8, 5, 71, 8, 6, 71, 8, 6, 72, 8, 9, 72,
448 8, 5, 79, 8, 8, 79, 8, 8, 80, 8, 9, 80,
449 9, 5, 80, 9, 7, 80, 9, 7, 81, 9, 9, 81,
452 const int bandchecks =
sizeof(tab) / (3 *
sizeof(
short));
453 for (
int i = 0;
i < bandchecks; ++
i) {
455 if (!( LatitudeBand(lat) == tab[3*
i+0] ))
static const int minnorthing_[4]
Header for GeographicLib::Utility class.
static const char *const upscols_[4]
const mpreal ldexp(const mpreal &v, mp_exp_t exp)
static const char *const digits_
static const int mineasting_[4]
static int UTMRow(int iband, int icol, int irow)
static const char *const upsband_
static const char *const hemispheres_
Header for GeographicLib::MGRS class.
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)
static const char *const upsrows_[2]
Namespace for GeographicLib.
Array< double, 1, 3 > e(1./3., 0.5, 2.)
static std::string str(T x, int p=-1)
static void CheckCoords(bool utmp, bool &northp, real &x, real &y)
static const char *const utmcols_[3]
static void Reverse(int zone, bool northp, real x, real y, real &lat, real &lon, real &gamma, real &k, bool mgrslimits=false)
static void Reverse(const std::string &mgrs, int &zone, bool &northp, real &x, real &y, int &prec, bool centerp=true)
static const int maxnorthing_[4]
EIGEN_DEVICE_FUNC const FloorReturnType floor() const
Exception handling for GeographicLib.
static const int maxeasting_[4]
static int lookup(const std::string &s, char c)
int EIGEN_BLAS_FUNC() copy(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
Jet< T, N > pow(const Jet< T, N > &f, double g)
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
static const char *const latband_
static void Forward(int zone, bool northp, real x, real y, int prec, std::string &mgrs)
static const char *const utmrow_