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

18 const char* const GARS::letters_ = "ABCDEFGHJKLMNPQRSTUVWXYZ";

19

20 void GARS::Forward(real lat, real lon, int prec, string& gars) {

21 using std::isnan;

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

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

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

27 gars = "INVALID";

28 return;

29 }

31 if (lon == Math::hd) lon = -Math::hd;

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

33 prec = max(0, min(int(maxprec_), prec));

34 int

35 x = int(floor(lon * m_)) - lonorig_ * m_,

36 y = int(floor(lat * m_)) - latorig_ * m_,

37 ilon = x * mult1_ / m_,

38 ilat = y * mult1_ / m_;

39 x -= ilon * m_ / mult1_; y -= ilat * m_ / mult1_;

40 char gars1[maxlen_];

41 ++ilon;

42 for (int c = lonlen_; c--;) {

43 gars1[c] = digits_[ ilon % baselon_]; ilon /= baselon_;

44 }

45 for (int c = latlen_; c--;) {

46 gars1[lonlen_ + c] = letters_[ilat % baselat_]; ilat /= baselat_;

47 }

48 if (prec > 0) {

49 ilon = x / mult3_; ilat = y / mult3_;

50 gars1[baselen_] = digits_[mult2_ * (mult2_ - 1 - ilat) + ilon + 1];

51 if (prec > 1) {

52 ilon = x % mult3_; ilat = y % mult3_;

53 gars1[baselen_ + 1] = digits_[mult3_ * (mult3_ - 1 - ilat) + ilon + 1];

54 }

55 }

56 gars.resize(baselen_ + prec);

57 copy(gars1, gars1 + baselen_ + prec, gars.begin());

58 }

59

60 void GARS::Reverse(const string& gars, real& lat, real& lon,

61 int& prec, bool centerp) {

62 int len = int(gars.length());

63 if (len >= 3 &&

64 toupper(gars[0]) == 'I' &&

65 toupper(gars[1]) == 'N' &&

66 toupper(gars[2]) == 'V') {

68 return;

69 }

70 if (len < baselen_)

71 throw GeographicErr("GARS must have at least 5 characters " + gars);

72 if (len > maxlen_)

73 throw GeographicErr("GARS can have at most 7 characters " + gars);

74 int prec1 = len - baselen_;

75 int ilon = 0;

76 for (int c = 0; c < lonlen_; ++c) {

78 if (k < 0)

79 throw GeographicErr("GARS must start with 3 digits " + gars);

80 ilon = ilon * baselon_ + k;

81 }

82 if (!(ilon >= 1 && ilon <= 2 * Math::td))

83 throw GeographicErr("Initial digits in GARS must lie in [1, 720] " +

84 gars);

85 --ilon;

86 int ilat = 0;

87 for (int c = 0; c < latlen_; ++c) {

89 if (k < 0)

90 throw GeographicErr("Illegal letters in GARS " + gars.substr(3,2));

91 ilat = ilat * baselat_ + k;

92 }

94 throw GeographicErr("GARS letters must lie in [AA, QZ] " + gars);

95 real

96 unit = mult1_,

97 lat1 = ilat + latorig_ * unit,

98 lon1 = ilon + lonorig_ * unit;

99 if (prec1 > 0) {

101 if (!(k >= 1 && k <= mult2_ * mult2_))

102 throw GeographicErr("6th character in GARS must [1, 4] " + gars);

103 --k;

104 unit *= mult2_;

105 lat1 = mult2_ * lat1 + (mult2_ - 1 - k / mult2_);

106 lon1 = mult2_ * lon1 + (k % mult2_);

107 if (prec1 > 1) {

109 if (!(k >= 1 ))

110 throw GeographicErr("7th character in GARS must [1, 9] " + gars);

111 --k;

112 unit *= mult3_;

113 lat1 = mult3_ * lat1 + (mult3_ - 1 - k / mult3_);

114 lon1 = mult3_ * lon1 + (k % mult3_);

115 }

116 }

117 if (centerp) {

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

119 }

120 lat = lat1 / unit;

121 lon = lon1 / unit;

122 prec = prec1;

123 }

124

125}

Header for GeographicLib::GARS class.

Header for GeographicLib::Utility class.

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

Definition GARS.cpp:60

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

Definition GARS.cpp:20

Exception handling for GeographicLib.

static constexpr int qd

degrees per quarter turn

static T AngNormalize(T x)

static constexpr int td

degrees per turn

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.