src/Geohash.cpp
Go to the documentation of this file.
1 
12 
13 namespace GeographicLib {
14 
15  using namespace std;
16 
17  const char* const Geohash::lcdigits_ = "0123456789bcdefghjkmnpqrstuvwxyz";
18  const char* const Geohash::ucdigits_ = "0123456789BCDEFGHJKMNPQRSTUVWXYZ";
19 
20  void Geohash::Forward(real lat, real lon, int len, std::string& geohash) {
21  static const real shift = ldexp(real(1), 45);
22  static const real loneps = 180 / shift;
23  static const real lateps = 90 / shift;
24  if (abs(lat) > 90)
25  throw GeographicErr("Latitude " + Utility::str(lat)
26  + "d not in [-90d, 90d]");
27  if (Math::isnan(lat) || Math::isnan(lon)) {
28  geohash = "invalid";
29  return;
30  }
31  if (lat == 90) lat -= lateps / 2;
32  lon = Math::AngNormalize(lon); // lon in [-180,180)
33  // lon/loneps in [-2^45,2^45); lon/loneps + shift in [0,2^46)
34  // similarly for lat
35  len = max(0, min(int(maxlen_), len));
36  unsigned long long
37  ulon = (unsigned long long)(floor(lon/loneps) + shift),
38  ulat = (unsigned long long)(floor(lat/lateps) + shift);
39  char geohash1[maxlen_];
40  unsigned byte = 0;
41  for (unsigned i = 0; i < 5 * unsigned(len);) {
42  if ((i & 1) == 0) {
43  byte = (byte << 1) + unsigned((ulon & mask_) != 0);
44  ulon <<= 1;
45  } else {
46  byte = (byte << 1) + unsigned((ulat & mask_) != 0);
47  ulat <<= 1;
48  }
49  ++i;
50  if (i % 5 == 0) {
51  geohash1[(i/5)-1] = lcdigits_[byte];
52  byte = 0;
53  }
54  }
55  geohash.resize(len);
56  copy(geohash1, geohash1 + len, geohash.begin());
57  }
58 
59  void Geohash::Reverse(const std::string& geohash, real& lat, real& lon,
60  int& len, bool centerp) {
61  static const real shift = ldexp(real(1), 45);
62  static const real loneps = 180 / shift;
63  static const real lateps = 90 / shift;
64  int len1 = min(int(maxlen_), int(geohash.length()));
65  if (len1 >= 3 &&
66  ((toupper(geohash[0]) == 'I' &&
67  toupper(geohash[1]) == 'N' &&
68  toupper(geohash[2]) == 'V') ||
69  // Check A first because it is not in a standard geohash
70  (toupper(geohash[1]) == 'A' &&
71  toupper(geohash[0]) == 'N' &&
72  toupper(geohash[2]) == 'N'))) {
73  lat = lon = Math::NaN();
74  return;
75  }
76  unsigned long long ulon = 0, ulat = 0;
77  for (unsigned k = 0, j = 0; k < unsigned(len1); ++k) {
78  int byte = Utility::lookup(ucdigits_, geohash[k]);
79  if (byte < 0)
80  throw GeographicErr("Illegal character in geohash " + geohash);
81  for (unsigned m = 16; m; m >>= 1) {
82  if (j == 0)
83  ulon = (ulon << 1) + unsigned((byte & m) != 0);
84  else
85  ulat = (ulat << 1) + unsigned((byte & m) != 0);
86  j ^= 1;
87  }
88  }
89  ulon <<= 1; ulat <<= 1;
90  if (centerp) {
91  ulon += 1;
92  ulat += 1;
93  }
94  int s = 5 * (maxlen_ - len1);
95  ulon <<= (s / 2);
96  ulat <<= s - (s / 2);
97  lon = ulon * loneps - 180;
98  lat = ulat * lateps - 90;
99  len = len1;
100  }
101 
102 } // namespace GeographicLib
GeographicLib::Geohash::Forward
static void Forward(real lat, real lon, int len, std::string &geohash)
Definition: src/Geohash.cpp:20
GeographicLib::Math::AngNormalize
static T AngNormalize(T x)
Definition: Math.hpp:440
GeographicLib::Math::NaN
static T NaN()
Definition: Math.hpp:830
s
RealScalar s
Definition: level1_cplx_impl.h:126
GeographicLib::Utility::str
static std::string str(T x, int p=-1)
Definition: Utility.hpp:276
GeographicLib
Namespace for GeographicLib.
Definition: JacobiConformal.hpp:15
real
float real
Definition: datatypes.h:10
GeographicLib::Geohash::lcdigits_
static const char *const lcdigits_
Definition: Geohash.hpp:45
copy
int EIGEN_BLAS_FUNC() copy(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
Definition: level1_impl.h:29
GeographicLib::GeographicErr
Exception handling for GeographicLib.
Definition: Constants.hpp:389
GeographicLib::Utility::lookup
static int lookup(const std::string &s, char c)
Definition: Utility.hpp:459
GeographicLib::Geohash::ucdigits_
static const char *const ucdigits_
Definition: Geohash.hpp:46
j
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2
Geohash.hpp
Header for GeographicLib::Geohash class.
Utility.hpp
Header for GeographicLib::Utility class.
GeographicLib::Geohash::Reverse
static void Reverse(const std::string &geohash, real &lat, real &lon, int &len, bool centerp=true)
Definition: src/Geohash.cpp:59
m
Matrix3f m
Definition: AngleAxis_mimic_euler.cpp:1
GeographicLib::Math::isnan
static bool isnan(T x)
Definition: Math.hpp:853
std
Definition: BFloat16.h:88
min
#define min(a, b)
Definition: datatypes.h:19
abs
#define abs(x)
Definition: datatypes.h:17
len
size_t len(handle h)
Get the length of a Python object.
Definition: pytypes.h:2446
lon
static const double lon
Definition: testGeographicLib.cpp:34
max
#define max(a, b)
Definition: datatypes.h:20
real
Definition: main.h:100
i
int i
Definition: BiCGSTAB_step_by_step.cpp:9
floor
const EIGEN_DEVICE_FUNC FloorReturnType floor() const
Definition: ArrayCwiseUnaryOps.h:481
lat
static const double lat
Definition: testGeographicLib.cpp:34


gtsam
Author(s):
autogenerated on Sun Dec 22 2024 04:11:37