src/GARS.cpp
Go to the documentation of this file.
1 
10 #include <GeographicLib/GARS.hpp>
12 
13 namespace GeographicLib {
14 
15  using namespace std;
16 
17  const char* const GARS::digits_ = "0123456789";
18  const char* const GARS::letters_ = "ABCDEFGHJKLMNPQRSTUVWXYZ";
19 
20  void GARS::Forward(real lat, real lon, int prec, std::string& gars) {
21  if (abs(lat) > 90)
22  throw GeographicErr("Latitude " + Utility::str(lat)
23  + "d not in [-90d, 90d]");
24  if (Math::isnan(lat) || Math::isnan(lon)) {
25  gars = "INVALID";
26  return;
27  }
28  lon = Math::AngNormalize(lon); // lon in [-180,180)
29  if (lat == 90) lat *= (1 - numeric_limits<real>::epsilon() / 2);
30  prec = max(0, min(int(maxprec_), prec));
31  int
32  x = int(floor(lon * m_)) - lonorig_ * m_,
33  y = int(floor(lat * m_)) - latorig_ * m_,
34  ilon = x * mult1_ / m_,
35  ilat = y * mult1_ / m_;
36  x -= ilon * m_ / mult1_; y -= ilat * m_ / mult1_;
37  char gars1[maxlen_];
38  ++ilon;
39  for (int c = lonlen_; c--;) {
40  gars1[c] = digits_[ ilon % baselon_]; ilon /= baselon_;
41  }
42  for (int c = latlen_; c--;) {
43  gars1[lonlen_ + c] = letters_[ilat % baselat_]; ilat /= baselat_;
44  }
45  if (prec > 0) {
46  ilon = x / mult3_; ilat = y / mult3_;
47  gars1[baselen_] = digits_[mult2_ * (mult2_ - 1 - ilat) + ilon + 1];
48  if (prec > 1) {
49  ilon = x % mult3_; ilat = y % mult3_;
50  gars1[baselen_ + 1] = digits_[mult3_ * (mult3_ - 1 - ilat) + ilon + 1];
51  }
52  }
53  gars.resize(baselen_ + prec);
54  copy(gars1, gars1 + baselen_ + prec, gars.begin());
55  }
56 
57  void GARS::Reverse(const std::string& gars, real& lat, real& lon,
58  int& prec, bool centerp) {
59  int len = int(gars.length());
60  if (len >= 3 &&
61  toupper(gars[0]) == 'I' &&
62  toupper(gars[1]) == 'N' &&
63  toupper(gars[2]) == 'V') {
64  lat = lon = Math::NaN();
65  return;
66  }
67  if (len < baselen_)
68  throw GeographicErr("GARS must have at least 5 characters " + gars);
69  if (len > maxlen_)
70  throw GeographicErr("GARS can have at most 7 characters " + gars);
71  int prec1 = len - baselen_;
72  int ilon = 0;
73  for (int c = 0; c < lonlen_; ++c) {
74  int k = Utility::lookup(digits_, gars[c]);
75  if (k < 0)
76  throw GeographicErr("GARS must start with 3 digits " + gars);
77  ilon = ilon * baselon_ + k;
78  }
79  if (!(ilon >= 1 && ilon <= 720))
80  throw GeographicErr("Initial digits in GARS must lie in [1, 720] " +
81  gars);
82  --ilon;
83  int ilat = 0;
84  for (int c = 0; c < latlen_; ++c) {
85  int k = Utility::lookup(letters_, gars[lonlen_ + c]);
86  if (k < 0)
87  throw GeographicErr("Illegal letters in GARS " + gars.substr(3,2));
88  ilat = ilat * baselat_ + k;
89  }
90  if (!(ilat < 360))
91  throw GeographicErr("GARS letters must lie in [AA, QZ] " + gars);
92  real
93  unit = mult1_,
94  lat1 = ilat + latorig_ * unit,
95  lon1 = ilon + lonorig_ * unit;
96  if (prec1 > 0) {
97  int k = Utility::lookup(digits_, gars[baselen_]);
98  if (!(k >= 1 && k <= mult2_ * mult2_))
99  throw GeographicErr("6th character in GARS must [1, 4] " + gars);
100  --k;
101  unit *= mult2_;
102  lat1 = mult2_ * lat1 + (mult2_ - 1 - k / mult2_);
103  lon1 = mult2_ * lon1 + (k % mult2_);
104  if (prec1 > 1) {
105  k = Utility::lookup(digits_, gars[baselen_ + 1]);
106  if (!(k >= 1 /* && k <= mult3_ * mult3_ */))
107  throw GeographicErr("7th character in GARS must [1, 9] " + gars);
108  --k;
109  unit *= mult3_;
110  lat1 = mult3_ * lat1 + (mult3_ - 1 - k / mult3_);
111  lon1 = mult3_ * lon1 + (k % mult3_);
112  }
113  }
114  if (centerp) {
115  unit *= 2; lat1 = 2 * lat1 + 1; lon1 = 2 * lon1 + 1;
116  }
117  lat = lat1 / unit;
118  lon = lon1 / unit;
119  prec = prec1;
120  }
121 
122 } // namespace GeographicLib
static T AngNormalize(T x)
Definition: Math.hpp:440
static T NaN()
Definition: Math.hpp:830
#define max(a, b)
Definition: datatypes.h:20
Scalar * y
static const double lat
Header for GeographicLib::Utility class.
#define min(a, b)
Definition: datatypes.h:19
static bool isnan(T x)
Definition: Math.hpp:853
Scalar Scalar * c
Definition: benchVecAdd.cpp:17
Definition: BFloat16.h:88
static void Forward(real lat, real lon, int prec, std::string &gars)
Definition: src/GARS.cpp:20
static double epsilon
Definition: testRot3.cpp:37
EIGEN_DEVICE_FUNC const FloorReturnType floor() const
static void Reverse(const std::string &gars, real &lat, real &lon, int &prec, bool centerp=true)
Definition: src/GARS.cpp:57
Definition: main.h:100
Namespace for GeographicLib.
static const char *const letters_
Definition: GARS.hpp:42
static std::string str(T x, int p=-1)
Definition: Utility.hpp:276
static const char *const digits_
Definition: GARS.hpp:41
Exception handling for GeographicLib.
Definition: Constants.hpp:389
static int lookup(const std::string &s, char c)
Definition: Utility.hpp:459
static const double lon
int EIGEN_BLAS_FUNC() copy(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
Definition: level1_impl.h:29
Header for GeographicLib::GARS class.
size_t len(handle h)
Get the length of a Python object.
Definition: pytypes.h:2244
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
#define abs(x)
Definition: datatypes.h:17


gtsam
Author(s):
autogenerated on Tue Jul 4 2023 02:34:15