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.