GeographicLib: Georef.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 Georef::digits_ = "0123456789";

18 const char* const Georef::lontile_ = "ABCDEFGHJKLMNPQRSTUVWXYZ";

19 const char* const Georef::lattile_ = "ABCDEFGHJKLM";

20 const char* const Georef::degrees_ = "ABCDEFGHJKLMNPQ";

21

22 void Georef::Forward(real lat, real lon, int prec, string& georef) {

23 using std::isnan;

26 + "d not in [-" + to_string(Math::qd)

27 + "d, " + to_string(Math::qd) + "d]");

28 if (isnan(lat) || isnan(lon)) {

29 georef = "INVALID";

30 return;

31 }

33 if (lat == Math::qd) lat *= (1 - numeric_limits::epsilon() / 2);

34 prec = max(-1, min(int(maxprec_), prec));

35 if (prec == 1) ++prec;

36

37

38 static_assert(numeric_limits::digits >= 45,

39 "long long not wide enough to store 21600e9");

40 const long long m = 60000000000LL;

41 long long

42 x = (long long)(floor(lon * real(m))) - lonorig_ * m,

43 y = (long long)(floor(lat * real(m))) - latorig_ * m;

44 int ilon = int(x / m); int ilat = int(y / m);

45 char georef1[maxlen_];

46 georef1[0] = lontile_[ilon / tile_];

47 georef1[1] = lattile_[ilat / tile_];

48 if (prec >= 0) {

49 georef1[2] = degrees_[ilon % tile_];

50 georef1[3] = degrees_[ilat % tile_];

51 if (prec > 0) {

52 x -= m * ilon; y -= m * ilat;

53 long long d = (long long)pow(real(base_), maxprec_ - prec);

54 x /= d; y /= d;

55 for (int c = prec; c--;) {

56 georef1[baselen_ + c ] = digits_[x % base_]; x /= base_;

57 georef1[baselen_ + c + prec] = digits_[y % base_]; y /= base_;

58 }

59 }

60 }

61 georef.resize(baselen_ + 2 * prec);

62 copy(georef1, georef1 + baselen_ + 2 * prec, georef.begin());

63 }

64

66 int& prec, bool centerp) {

67 int len = int(georef.length());

68 if (len >= 3 &&

69 toupper(georef[0]) == 'I' &&

70 toupper(georef[1]) == 'N' &&

71 toupper(georef[2]) == 'V') {

73 return;

74 }

75 if (len < baselen_ - 2)

76 throw GeographicErr("Georef must start with at least 2 letters "

77 + georef);

78 int prec1 = (2 + len - baselen_) / 2 - 1;

79 int k;

81 if (k < 0)

82 throw GeographicErr("Bad longitude tile letter in georef " + georef);

83 real lon1 = k + lonorig_ / tile_;

85 if (k < 0)

86 throw GeographicErr("Bad latitude tile letter in georef " + georef);

87 real lat1 = k + latorig_ / tile_;

88 real unit = 1;

89 if (len > 2) {

90 unit *= tile_;

92 if (k < 0)

93 throw GeographicErr("Bad longitude degree letter in georef " + georef);

94 lon1 = lon1 * tile_ + k;

95 if (len < 4)

96 throw GeographicErr("Missing latitude degree letter in georef "

97 + georef);

99 if (k < 0)

100 throw GeographicErr("Bad latitude degree letter in georef " + georef);

101 lat1 = lat1 * tile_ + k;

102 if (prec1 > 0) {

103 if (georef.find_first_not_of(digits_, baselen_) != string::npos)

104 throw GeographicErr("Non digits in trailing portion of georef "

105 + georef.substr(baselen_));

106 if (len % 2)

107 throw GeographicErr("Georef must end with an even number of digits "

108 + georef.substr(baselen_));

109 if (prec1 == 1)

110 throw GeographicErr("Georef needs at least 4 digits for minutes "

111 + georef.substr(baselen_));

112 if (prec1 > maxprec_)

114 + " digits in georef "

115 + georef.substr(baselen_));

116 for (int i = 0; i < prec1; ++i) {

117 int m = i ? base_ : 6;

118 unit *= m;

119 int

121 y = Utility::lookup(digits_, georef[baselen_ + i + prec1]);

122 if (!(i || (x < m && y < m)))

123 throw GeographicErr("Minutes terms in georef must be less than 60 "

124 + georef.substr(baselen_));

125 lon1 = m * lon1 + x;

126 lat1 = m * lat1 + y;

127 }

128 }

129 }

130 if (centerp) {

131 unit *= 2; lat1 = 2 * lat1 + 1; lon1 = 2 * lon1 + 1;

132 }

133 lat = (tile_ * lat1) / unit;

134 lon = (tile_ * lon1) / unit;

135 prec = prec1;

136 }

137

138}

Header for GeographicLib::Georef class.

Header for GeographicLib::Utility class.

Exception handling for GeographicLib.

static void Forward(real lat, real lon, int prec, std::string &georef)

Definition Georef.cpp:22

static void Reverse(const std::string &georef, real &lat, real &lon, int &prec, bool centerp=true)

Definition Georef.cpp:65

static constexpr int qd

degrees per quarter turn

static T AngNormalize(T x)

static int lookup(const std::string &s, char c)

static std::string str(T x, int p=-1)

Namespace for GeographicLib.