src/Georef.cpp
Go to the documentation of this file.
1 
10 #include <GeographicLib/Georef.hpp>
12 
13 namespace GeographicLib {
14 
15  using namespace std;
16 
17  const char* const Georef::digits_ = "0123456789";
18  const char* const Georef::lontile_ = "ABCDEFGHJKLMNPQRSTUVWXYZ";
19  const char* const Georef::lattile_ = "ABCDEFGHJKLM";
20  const char* const Georef::degrees_ = "ABCDEFGHJKLMNPQ";
21 
22  void Georef::Forward(real lat, real lon, int prec, std::string& georef) {
23  if (abs(lat) > 90)
24  throw GeographicErr("Latitude " + Utility::str(lat)
25  + "d not in [-90d, 90d]");
26  if (Math::isnan(lat) || Math::isnan(lon)) {
27  georef = "INVALID";
28  return;
29  }
30  lon = Math::AngNormalize(lon); // lon in [-180,180)
31  if (lat == 90) lat *= (1 - numeric_limits<real>::epsilon() / 2);
32  prec = max(-1, min(int(maxprec_), prec));
33  if (prec == 1) ++prec; // Disallow prec = 1
34  // The C++ standard mandates 64 bits for long long. But
35  // check, to make sure.
36  GEOGRAPHICLIB_STATIC_ASSERT(numeric_limits<long long>::digits >= 45,
37  "long long not wide enough to store 21600e9");
38  const long long m = 60000000000LL;
39  long long
40  x = (long long)(floor(lon * real(m))) - lonorig_ * m,
41  y = (long long)(floor(lat * real(m))) - latorig_ * m;
42  int ilon = int(x / m); int ilat = int(y / m);
43  char georef1[maxlen_];
44  georef1[0] = lontile_[ilon / tile_];
45  georef1[1] = lattile_[ilat / tile_];
46  if (prec >= 0) {
47  georef1[2] = degrees_[ilon % tile_];
48  georef1[3] = degrees_[ilat % tile_];
49  if (prec > 0) {
50  x -= m * ilon; y -= m * ilat;
51  long long d = (long long)pow(real(base_), maxprec_ - prec);
52  x /= d; y /= d;
53  for (int c = prec; c--;) {
54  georef1[baselen_ + c ] = digits_[x % base_]; x /= base_;
55  georef1[baselen_ + c + prec] = digits_[y % base_]; y /= base_;
56  }
57  }
58  }
59  georef.resize(baselen_ + 2 * prec);
60  copy(georef1, georef1 + baselen_ + 2 * prec, georef.begin());
61  }
62 
63  void Georef::Reverse(const std::string& georef, real& lat, real& lon,
64  int& prec, bool centerp) {
65  int len = int(georef.length());
66  if (len >= 3 &&
67  toupper(georef[0]) == 'I' &&
68  toupper(georef[1]) == 'N' &&
69  toupper(georef[2]) == 'V') {
70  lat = lon = Math::NaN();
71  return;
72  }
73  if (len < baselen_ - 2)
74  throw GeographicErr("Georef must start with at least 2 letters "
75  + georef);
76  int prec1 = (2 + len - baselen_) / 2 - 1;
77  int k;
78  k = Utility::lookup(lontile_, georef[0]);
79  if (k < 0)
80  throw GeographicErr("Bad longitude tile letter in georef " + georef);
81  real lon1 = k + lonorig_ / tile_;
82  k = Utility::lookup(lattile_, georef[1]);
83  if (k < 0)
84  throw GeographicErr("Bad latitude tile letter in georef " + georef);
85  real lat1 = k + latorig_ / tile_;
86  real unit = 1;
87  if (len > 2) {
88  unit *= tile_;
89  k = Utility::lookup(degrees_, georef[2]);
90  if (k < 0)
91  throw GeographicErr("Bad longitude degree letter in georef " + georef);
92  lon1 = lon1 * tile_ + k;
93  if (len < 4)
94  throw GeographicErr("Missing latitude degree letter in georef "
95  + georef);
96  k = Utility::lookup(degrees_, georef[3]);
97  if (k < 0)
98  throw GeographicErr("Bad latitude degree letter in georef " + georef);
99  lat1 = lat1 * tile_ + k;
100  if (prec1 > 0) {
101  if (georef.find_first_not_of(digits_, baselen_) != string::npos)
102  throw GeographicErr("Non digits in trailing portion of georef "
103  + georef.substr(baselen_));
104  if (len % 2)
105  throw GeographicErr("Georef must end with an even number of digits "
106  + georef.substr(baselen_));
107  if (prec1 == 1)
108  throw GeographicErr("Georef needs at least 4 digits for minutes "
109  + georef.substr(baselen_));
110  if (prec1 > maxprec_)
111  throw GeographicErr("More than " + Utility::str(2*maxprec_)
112  + " digits in georef "
113  + georef.substr(baselen_));
114  for (int i = 0; i < prec1; ++i) {
115  int m = i ? base_ : 6;
116  unit *= m;
117  int
118  x = Utility::lookup(digits_, georef[baselen_ + i]),
119  y = Utility::lookup(digits_, georef[baselen_ + i + prec1]);
120  if (!(i || (x < m && y < m)))
121  throw GeographicErr("Minutes terms in georef must be less than 60 "
122  + georef.substr(baselen_));
123  lon1 = m * lon1 + x;
124  lat1 = m * lat1 + y;
125  }
126  }
127  }
128  if (centerp) {
129  unit *= 2; lat1 = 2 * lat1 + 1; lon1 = 2 * lon1 + 1;
130  }
131  lat = (tile_ * lat1) / unit;
132  lon = (tile_ * lon1) / unit;
133  prec = prec1;
134  }
135 
136 } // namespace GeographicLib
static T AngNormalize(T x)
Definition: Math.hpp:440
static const char *const lattile_
Definition: Georef.hpp:43
Matrix3f m
static T NaN()
Definition: Math.hpp:830
#define max(a, b)
Definition: datatypes.h:20
Header for GeographicLib::Georef class.
float real
Definition: datatypes.h:10
Scalar * y
return int(ret)+1
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
static const char *const lontile_
Definition: Georef.hpp:42
Scalar Scalar * c
Definition: benchVecAdd.cpp:17
static const char *const degrees_
Definition: Georef.hpp:44
Definition: Half.h:150
static double epsilon
Definition: testRot3.cpp:39
static void Forward(real lat, real lon, int prec, std::string &georef)
Definition: src/Georef.cpp:22
Namespace for GeographicLib.
static const char *const digits_
Definition: Georef.hpp:41
static std::string str(T x, int p=-1)
Definition: Utility.hpp:276
static void Reverse(const std::string &georef, real &lat, real &lon, int &prec, bool centerp=true)
Definition: src/Georef.cpp:63
Math::real real
Definition: Georef.hpp:40
EIGEN_DEVICE_FUNC const FloorReturnType floor() const
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
Jet< T, N > pow(const Jet< T, N > &f, double g)
Definition: jet.h:570
size_t len(handle h)
Definition: pytypes.h:1514
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 Sat May 8 2021 02:42:08