GeographicLib  1.35
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) <charles@karney.com> and licensed under
6  * the MIT/X11 License. For more information, see
7  * http://geographiclib.sourceforge.net/
8  **********************************************************************/
9 
10 #if !defined(GEOGRAPHICLIB_GEOHASH_HPP)
11 #define GEOGRAPHICLIB_GEOHASH_HPP 1
12 
14 
15 #if defined(_MSC_VER)
16 // Squelch warnings about dll vs string
17 # pragma warning (push)
18 # pragma warning (disable: 4251)
19 #endif
20 
21 namespace GeographicLib {
22 
23  /**
24  * \brief Conversions for geohashes
25  *
26  * Geohashes are described in
27  * - http://en.wikipedia.org/wiki/Geohash
28  * - http://geohash.org/
29  * .
30  * They provide a compact string representation of a particular geographic
31  * location (expressed as latitude and longitude), with the property that if
32  * trailing characters are dropped from the string the geographic location
33  * remains nearby.
34  *
35  * Example of use:
36  * \include example-Geohash.cpp
37  **********************************************************************/
38 
40  private:
41  typedef Math::real real;
42  static const int maxlen_ = 18;
43  static const unsigned long long mask_ = 1ULL << 45;
44  static const int decprec_[];
45  static const real loneps_;
46  static const real lateps_;
47  static const real shift_;
48  static const std::string lcdigits_;
49  static const std::string ucdigits_;
50  Geohash(); // Disable constructor
51 
52  public:
53 
54  /**
55  * Convert from geographic coordinates to a geohash.
56  *
57  * @param[in] lat latitude of point (degrees).
58  * @param[in] lon longitude of point (degrees).
59  * @param[in] len the length of the resulting geohash.
60  * @param[out] geohash the geohash.
61  * @exception GeographicErr if \e la is not in [&minus;90&deg;,
62  * 90&deg;].
63  * @exception GeographicErr if \e lon is not in [&minus;540&deg;,
64  * 540&deg;).
65  * @exception std::bad_alloc if memory for \e geohash can't be allocated.
66  *
67  * Internally, \e len is first put in the range [0, 18].
68  *
69  * If \e lat or \e lon is NaN, the returned geohash is "nan".
70  **********************************************************************/
71  static void Forward(real lat, real lon, int len, std::string& geohash);
72 
73  /**
74  * Convert from a geohash to geographic coordinates.
75  *
76  * @param[in] geohash the geohash.
77  * @param[out] lat latitude of point (degrees).
78  * @param[out] lon longitude of point (degrees).
79  * @param[out] len the length of the geohash.
80  * @param[in] centerp if true (the default) return the center of the
81  * geohash location, otherwise return the south-west corner.
82  * @exception GeographicErr if \e geohash contains illegal characters.
83  *
84  * Only the first 18 characters for \e geohash are considered. The case of
85  * the letters in \e geohash is ignored.
86  *
87  * If the first three characters in \e geohash are "nan", then \e lat and
88  * \e lon are set to NaN.
89  **********************************************************************/
90  static void Reverse(const std::string& geohash, real& lat, real& lon,
91  int& len, bool centerp = true);
92 
93  /**
94  * The latitude resolution of a geohash.
95  *
96  * @param[in] len the length of the geohash.
97  * @return the latitude resolution (degrees).
98  *
99  * Internally, \e len is first put in the range [0, 18].
100  **********************************************************************/
101  static Math::real LatitudeResolution(int len) throw() {
102  len = (std::max)(0, (std::min)(int(maxlen_), len));
103  return 180 * std::pow(0.5, 5 * len / 2);
104  }
105 
106  /**
107  * The longitude resolution of a geohash.
108  *
109  * @param[in] len the length of the geohash.
110  * @return the longitude resolution (degrees).
111  *
112  * Internally, \e len is first put in the range [0, 18].
113  **********************************************************************/
114  static Math::real LongitudeResolution(int len) throw() {
115  len = (std::max)(0, (std::min)(int(maxlen_), len));
116  return 360 * std::pow(0.5, 5 * len - 5 * len / 2);
117  }
118 
119  /**
120  * The geohash length required to meet a given geographic resolution.
121  *
122  * @param[in] res the minimum of resolution in latitude and longitude
123  * (degrees).
124  * @return geohash length.
125  *
126  * The returned length is in the range [0, 18].
127  **********************************************************************/
128  static int GeohashLength(real res) throw() {
129  res = std::abs(res);
130  for (int len = 0; len < maxlen_; ++len)
131  if (LongitudeResolution(len) <= res)
132  return len;
133  return maxlen_;
134  }
135 
136  /**
137  * The geohash length required to meet a given geographic resolution.
138  *
139  * @param[in] latres the resolution in latitude (degrees).
140  * @param[in] lonres the resolution in longitude (degrees).
141  * @return geohash length.
142  *
143  * The returned length is in the range [0, 18].
144  **********************************************************************/
145  static int GeohashLength(real latres, real lonres) throw() {
146  latres = std::abs(latres);
147  lonres = std::abs(lonres);
148  for (int len = 0; len < maxlen_; ++len)
149  if (LatitudeResolution(len) <= latres &&
150  LongitudeResolution(len) <= lonres)
151  return len;
152  return maxlen_;
153  }
154 
155  /**
156  * The decimal geographic precision required to match a given geohash
157  * length. This is the number of digits needed after decimal point in a
158  * decimal degrees representation.
159  *
160  * @param[in] len the length of the geohash.
161  * @return the decimal precision (may be negative).
162  *
163  * Internally, \e len is first put in the range [0, 18]. The returned
164  * decimal precision is in the range [&minus;2, 12].
165  **********************************************************************/
166  static int DecimalPrecision(int len) throw() {
167  return -int(std::floor(std::log(LatitudeResolution(len))/
168  std::log(Math::real(10))));
169  }
170 
171  };
172 
173 } // namespace GeographicLib
174 
175 #if defined(_MSC_VER)
176 # pragma warning (pop)
177 #endif
178 
179 #endif // GEOGRAPHICLIB_GEOHASH_HPP
static Math::real LongitudeResolution(int len)
Definition: Geohash.hpp:114
#define GEOGRAPHICLIB_EXPORT
Definition: Constants.hpp:52
GeographicLib::Math::real real
Definition: GeodSolve.cpp:40
static int GeohashLength(real res)
Definition: Geohash.hpp:128
Conversions for geohashes.
Definition: Geohash.hpp:39
static int GeohashLength(real latres, real lonres)
Definition: Geohash.hpp:145
static int DecimalPrecision(int len)
Definition: Geohash.hpp:166
Header for GeographicLib::Constants class.
static Math::real LatitudeResolution(int len)
Definition: Geohash.hpp:101