GeographicLib 2.7

Loading...
Searching...
No Matches
Geohash.hpp
Go to the documentation of this file.
1/**
2 * \file Geohash.hpp
3 * \brief Header for GeographicLib::Geohash class
4 *
5 * Copyright (c) Charles Karney (2012-2022) <karney@alum.mit.edu> and licensed
6 * under the MIT/X11 License. For more information, see
7 * https://geographiclib.sourceforge.io/
8 **********************************************************************/
9
10#if !defined(GEOGRAPHICLIB_GEOHASH_HPP)
11#define GEOGRAPHICLIB_GEOHASH_HPP 1
12
13#include <GeographicLib/Constants.hpp>
14
15 namespace GeographicLib {
16
17 /**
18 * \brief Conversions for geohashes
19 *
20 * Geohashes are described in
21 * - https://en.wikipedia.org/wiki/Geohash
22 * - http://geohash.org/
23 * .
24 * They provide a compact string representation of a particular geographic
25 * location (expressed as latitude and longitude), with the property that if
26 * trailing characters are dropped from the string the geographic location
27 * remains nearby. The classes Georef and GARS implement similar compact
28 * representations.
29 *
30 * Example of use:
31 * \include example-Geohash.cpp
32 **********************************************************************/
33
34 class GEOGRAPHICLIB_EXPORT Geohash {
35 private:
36 typedef Math::real real;
37 static const int maxlen_ = 18;
38 static const unsigned long long mask_ = 1ULL << 45;
39 static const char* const lcdigits_;
40 static const char* const ucdigits_;
41 Geohash() = delete; // Disable constructor
42
43 public:
44
45 /**
46 * Convert from geographic coordinates to a geohash.
47 *
48 * @param[in] lat latitude of point (degrees).
49 * @param[in] lon longitude of point (degrees).
50 * @param[in] len the length of the resulting geohash.
51 * @param[out] geohash the geohash.
52 * @exception GeographicErr if \e lat is not in [&minus;90&deg;,
53 * 90&deg;].
54 * @exception std::bad_alloc if memory for \e geohash can't be allocated.
55 *
56 * Internally, \e len is first put in the range [0, 18]. (\e len = 18
57 * provides approximately 1&mu;m precision.)
58 *
59 * If \e lat or \e lon is NaN, the returned geohash is "invalid".
60 **********************************************************************/
61 static void Forward(real lat, real lon, int len, std::string& geohash);
62
63 /**
64 * Convert from a geohash to geographic coordinates.
65 *
66 * @param[in] geohash the geohash.
67 * @param[out] lat latitude of point (degrees).
68 * @param[out] lon longitude of point (degrees).
69 * @param[out] len the length of the geohash.
70 * @param[in] centerp if true (the default) return the center of the
71 * geohash location, otherwise return the south-west corner.
72 * @exception GeographicErr if \e geohash contains illegal characters.
73 *
74 * Only the first 18 characters for \e geohash are considered. (18
75 * characters provides approximately 1&mu;m precision.) The case of the
76 * letters in \e geohash is ignored.
77 *
78 * If the first 3 characters of \e geohash are "inv", then \e lat and \e
79 * lon are set to NaN and \e len is unchanged. ("nan" is treated
80 * similarly.)
81 **********************************************************************/
82 static void Reverse(const std::string& geohash, real& lat, real& lon,
83 int& len, bool centerp = true);
84
85 /**
86 * The latitude resolution of a geohash.
87 *
88 * @param[in] len the length of the geohash.
89 * @return the latitude resolution (degrees).
90 *
91 * Internally, \e len is first put in the range [0, 18].
92 **********************************************************************/
93 static Math::real LatitudeResolution(int len) {
94 using std::ldexp;
95 len = (std::max)(0, (std::min)(int(maxlen_), len));
96 return ldexp(real(Math::hd), -(5 * len / 2));
97 }
98
99 /**
100 * The longitude resolution of a geohash.
101 *
102 * @param[in] len the length of the geohash.
103 * @return the longitude resolution (degrees).
104 *
105 * Internally, \e len is first put in the range [0, 18].
106 **********************************************************************/
107 static Math::real LongitudeResolution(int len) {
108 using std::ldexp;
109 len = (std::max)(0, (std::min)(int(maxlen_), len));
110 return ldexp(real(Math::td), -(5 * len - 5 * len / 2));
111 }
112
113 /**
114 * The geohash length required to meet a given geographic resolution.
115 *
116 * @param[in] res the minimum of resolution in latitude and longitude
117 * (degrees).
118 * @return geohash length.
119 *
120 * The returned length is in the range [0, 18].
121 **********************************************************************/
122 static int GeohashLength(real res) {
123 using std::fabs; res = fabs(res);
124 for (int len = 0; len < maxlen_; ++len)
125 if (LongitudeResolution(len) <= res)
126 return len;
127 return maxlen_;
128 }
129
130 /**
131 * The geohash length required to meet a given geographic resolution.
132 *
133 * @param[in] latres the resolution in latitude (degrees).
134 * @param[in] lonres the resolution in longitude (degrees).
135 * @return geohash length.
136 *
137 * The returned length is in the range [0, 18].
138 **********************************************************************/
139 static int GeohashLength(real latres, real lonres) {
140 using std::fabs;
141 latres = fabs(latres);
142 lonres = fabs(lonres);
143 for (int len = 0; len < maxlen_; ++len)
144 if (LatitudeResolution(len) <= latres &&
145 LongitudeResolution(len) <= lonres)
146 return len;
147 return maxlen_;
148 }
149
150 /**
151 * The decimal geographic precision required to match a given geohash
152 * length. This is the number of digits needed after decimal point in a
153 * decimal degrees representation.
154 *
155 * @param[in] len the length of the geohash.
156 * @return the decimal precision (may be negative).
157 *
158 * Internally, \e len is first put in the range [0, 18]. The returned
159 * decimal precision is in the range [&minus;2, 12].
160 **********************************************************************/
161 static int DecimalPrecision(int len) {
162 using std::floor, std::log;
163 return -int(floor(log(LatitudeResolution(len))/log(Math::real(10))));
164 }
165
166 };
167
168} // namespace GeographicLib
169
170#endif // GEOGRAPHICLIB_GEOHASH_HPP
Constants.hpp
Header for GeographicLib::Constants class.
GEOGRAPHICLIB_EXPORT
#define GEOGRAPHICLIB_EXPORT
Definition Constants.hpp:59
real
GeographicLib::Math::real real
Definition Geod3Solve.cpp:25
GeographicLib::Geohash::LatitudeResolution
static Math::real LatitudeResolution(int len)
Definition Geohash.hpp:93
GeographicLib::Geohash::DecimalPrecision
static int DecimalPrecision(int len)
Definition Geohash.hpp:161
GeographicLib::Geohash::LongitudeResolution
static Math::real LongitudeResolution(int len)
Definition Geohash.hpp:107
GeographicLib::Geohash::GeohashLength
static int GeohashLength(real latres, real lonres)
Definition Geohash.hpp:139
GeographicLib::Geohash::Forward
static void Forward(real lat, real lon, int len, std::string &geohash)
Definition Geohash.cpp:20
GeographicLib::Geohash::Reverse
static void Reverse(const std::string &geohash, real &lat, real &lon, int &len, bool centerp=true)
Definition Geohash.cpp:61
GeographicLib::Geohash::GeohashLength
static int GeohashLength(real res)
Definition Geohash.hpp:122
GeographicLib::Math::td
static constexpr int td
degrees per turn
Definition Math.hpp:146
GeographicLib::Math::hd
static constexpr int hd
degrees per half turn
Definition Math.hpp:145
GeographicLib::Math::real
double real
Definition Math.hpp:115
GeographicLib
Namespace for GeographicLib.
Definition Accumulator.cpp:12