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