GeographicLib: Geohash.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
12
14
15 using namespace std;
16
17 const char* const Geohash::lcdigits_ = "0123456789bcdefghjkmnpqrstuvwxyz";
18 const char* const Geohash::ucdigits_ = "0123456789BCDEFGHJKMNPQRSTUVWXYZ";
19
21 using std::isnan;
22 static const real shift = ldexp(real(1), 45);
23 static const real loneps = Math::hd / shift;
24 static const real lateps = Math::qd / shift;
27 + "d not in [-" + to_string(Math::qd)
28 + "d, " + to_string(Math::qd) + "d]");
29 if (isnan(lat) || isnan(lon)) {
30 geohash = "invalid";
31 return;
32 }
33 if (lat == Math::qd) lat -= lateps / 2;
35 if (lon == Math::hd) lon = -Math::hd;
36
37
38 len = max(0, min(int(maxlen_), len));
39 unsigned long long
40 ulon = (unsigned long long)(floor(lon/loneps) + shift),
41 ulat = (unsigned long long)(floor(lat/lateps) + shift);
42 char geohash1[maxlen_];
43 unsigned byte = 0;
44 for (unsigned i = 0; i < 5 * unsigned(len);) {
45 if ((i & 1) == 0) {
46 byte = (byte << 1) + unsigned((ulon & mask_) != 0);
47 ulon <<= 1;
48 } else {
49 byte = (byte << 1) + unsigned((ulat & mask_) != 0);
50 ulat <<= 1;
51 }
52 ++i;
53 if (i % 5 == 0) {
54 geohash1[(i/5)-1] = lcdigits_[byte];
55 byte = 0;
56 }
57 }
58 geohash.resize(len);
59 copy(geohash1, geohash1 + len, geohash.begin());
60 }
61
63 int& len, bool centerp) {
64 static const real shift = ldexp(real(1), 45);
65 static const real loneps = Math::hd / shift;
66 static const real lateps = Math::qd / shift;
67 int len1 = min(int(maxlen_), int(geohash.length()));
68 if (len1 >= 3 &&
69 ((toupper(geohash[0]) == 'I' &&
70 toupper(geohash[1]) == 'N' &&
71 toupper(geohash[2]) == 'V') ||
72
73 (toupper(geohash[1]) == 'A' &&
74 toupper(geohash[0]) == 'N' &&
75 toupper(geohash[2]) == 'N'))) {
77 return;
78 }
79 unsigned long long ulon = 0, ulat = 0;
80 for (unsigned k = 0, j = 0; k < unsigned(len1); ++k) {
82 if (byte < 0)
83 throw GeographicErr("Illegal character in geohash " + geohash);
84 for (unsigned m = 16; m; m >>= 1) {
85 if (j == 0)
86 ulon = (ulon << 1) + unsigned((byte & m) != 0);
87 else
88 ulat = (ulat << 1) + unsigned((byte & m) != 0);
89 j ^= 1;
90 }
91 }
92 ulon <<= 1; ulat <<= 1;
93 if (centerp) {
94 ulon += 1;
95 ulat += 1;
96 }
97 int s = 5 * (maxlen_ - len1);
98 ulon <<= (s / 2);
99 ulat <<= s - (s / 2);
100 lon = ulon * loneps - Math::hd;
101 lat = ulat * lateps - Math::qd;
102 len = len1;
103 }
104
105}
Header for GeographicLib::Geohash class.
Header for GeographicLib::Utility class.
Exception handling for GeographicLib.
static void Forward(real lat, real lon, int len, std::string &geohash)
Definition Geohash.cpp:20
static void Reverse(const std::string &geohash, real &lat, real &lon, int &len, bool centerp=true)
Definition Geohash.cpp:62
static constexpr int qd
degrees per quarter turn
static T AngNormalize(T x)
static constexpr int hd
degrees per half turn
static int lookup(const std::string &s, char c)
static std::string str(T x, int p=-1)
Namespace for GeographicLib.