@@ -47,6 +47,78 @@ const int64_t kLongitudeMaxDegrees = 180;
47
47
const int kPositionLUT [' X' - ' C' + 1 ] = {8 , -1 , -1 , 9 , 10 , 11 , -1 , 12 ,
48
48
-1 , -1 , 13 , -1 , -1 , 14 , 15 , 16 ,
49
49
-1 , -1 , -1 , 17 , 18 , 19 };
50
+
51
+ int64_t latitudeToInteger (double latitude) {
52
+ int64_t lat = round (latitude * kGridLatPrecisionInverse );
53
+ lat += kLatitudeMaxDegrees * kGridLatPrecisionInverse ;
54
+ if (lat < 0 ) {
55
+ lat = 0 ;
56
+ } else if (lat >= 2 * kLatitudeMaxDegrees * kGridLatPrecisionInverse ) {
57
+ lat = 2 * kLatitudeMaxDegrees * kGridLatPrecisionInverse - 1 ;
58
+ }
59
+ return lat;
60
+ }
61
+
62
+ int64_t longitudeToInteger (double longitude) {
63
+ int64_t lng = round (longitude * kGridLngPrecisionInverse );
64
+ lng += kLongitudeMaxDegrees * kGridLngPrecisionInverse ;
65
+ if (lng <= 0 ) {
66
+ lng = lng % (2 * kLongitudeMaxDegrees * kGridLngPrecisionInverse ) +
67
+ 2 * kLongitudeMaxDegrees * kGridLngPrecisionInverse ;
68
+ } else if (lng >= 2 * kLongitudeMaxDegrees * kGridLngPrecisionInverse ) {
69
+ lng = lng % (2 * kLongitudeMaxDegrees * kGridLngPrecisionInverse );
70
+ }
71
+ return lng;
72
+ }
73
+
74
+ std::string encodeIntegers (int64_t lat_val, int64_t lng_val,
75
+ size_t code_length) {
76
+ // Reserve characters for the code digits and the separator.
77
+ std::string code = " 1234567890abcdef" ;
78
+ // Add the separator character.
79
+ code[internal::kSeparatorPosition ] = internal::kSeparator ;
80
+
81
+ // Compute the grid part of the code if necessary.
82
+ if (code_length > internal::kPairCodeLength ) {
83
+ for (size_t i = internal::kGridCodeLength ; i >= 1 ; i--) {
84
+ int lat_digit = lat_val % internal::kGridRows ;
85
+ int lng_digit = lng_val % internal::kGridColumns ;
86
+ code[internal::kSeparatorPosition + 2 + i] =
87
+ internal::kAlphabet [lat_digit * internal::kGridColumns + lng_digit];
88
+ lat_val /= internal::kGridRows ;
89
+ lng_val /= internal::kGridColumns ;
90
+ }
91
+ } else {
92
+ lat_val /= pow (internal::kGridRows , internal::kGridCodeLength );
93
+ lng_val /= pow (internal::kGridColumns , internal::kGridCodeLength );
94
+ }
95
+
96
+ // Add the pair after the separator.
97
+ code[internal::kSeparatorPosition + 1 ] =
98
+ internal::kAlphabet [lat_val % internal::kEncodingBase ];
99
+ code[internal::kSeparatorPosition + 2 ] =
100
+ internal::kAlphabet [lng_val % internal::kEncodingBase ];
101
+ lat_val /= internal::kEncodingBase ;
102
+ lng_val /= internal::kEncodingBase ;
103
+
104
+ // Compute the pair section before the separator in reverse order.
105
+ // Even indices contain latitude and odd contain longitude.
106
+ for (int i = (internal::kPairCodeLength / 2 + 1 ); i >= 0 ; i -= 2 ) {
107
+ code[i] = internal::kAlphabet [lat_val % internal::kEncodingBase ];
108
+ code[i + 1 ] = internal::kAlphabet [lng_val % internal::kEncodingBase ];
109
+ lat_val /= internal::kEncodingBase ;
110
+ lng_val /= internal::kEncodingBase ;
111
+ }
112
+ // Replace digits with padding if necessary.
113
+ if (code_length < internal::kSeparatorPosition ) {
114
+ for (size_t i = code_length; i < internal::kSeparatorPosition ; i++) {
115
+ code[i] = internal::kPaddingCharacter ;
116
+ }
117
+ code_length = internal::kSeparatorPosition ;
118
+ }
119
+ // Return the code up to and including the separator.
120
+ return code.substr (0 , code_length + 1 );
121
+ }
50
122
} // namespace internal
51
123
52
124
namespace {
@@ -129,78 +201,9 @@ std::string Encode(const LatLng &location, size_t code_length) {
129
201
code_length = code_length + 1 ;
130
202
}
131
203
// Convert latitude and longitude into integer values.
132
- int64_t lat_val =
133
- round (location.latitude * internal::kGridLatPrecisionInverse );
134
- int64_t lng_val =
135
- round (location.longitude * internal::kGridLngPrecisionInverse );
136
-
137
- // Adjust latitude and longitude so that they are normalized/clipped.
138
- lat_val += internal::kLatitudeMaxDegrees * internal::kGridLatPrecisionInverse ;
139
- if (lat_val < 0 ) {
140
- lat_val = 0 ;
141
- } else if (lat_val >= 2 * internal::kLatitudeMaxDegrees *
142
- internal::kGridLatPrecisionInverse ) {
143
- lat_val =
144
- 2 * internal::kLatitudeMaxDegrees * internal::kGridLatPrecisionInverse -
145
- 1 ;
146
- }
147
- lng_val +=
148
- internal::kLongitudeMaxDegrees * internal::kGridLngPrecisionInverse ;
149
- if (lng_val <= 0 ) {
150
- lng_val =
151
- lng_val % (2 * internal::kLongitudeMaxDegrees *
152
- internal::kGridLngPrecisionInverse ) +
153
- 2 * internal::kLongitudeMaxDegrees * internal::kGridLngPrecisionInverse ;
154
- } else if (lng_val >= 2 * internal::kLongitudeMaxDegrees *
155
- internal::kGridLngPrecisionInverse ) {
156
- lng_val = lng_val % (2 * internal::kLongitudeMaxDegrees *
157
- internal::kGridLngPrecisionInverse );
158
- }
159
- // Reserve characters for the code digits and the separator.
160
- std::string code = " 1234567890abcdef" ;
161
- // Add the separator character.
162
- code[internal::kSeparatorPosition ] = internal::kSeparator ;
163
-
164
- // Compute the grid part of the code if necessary.
165
- if (code_length > internal::kPairCodeLength ) {
166
- for (size_t i = internal::kGridCodeLength ; i >= 1 ; i--) {
167
- int lat_digit = lat_val % internal::kGridRows ;
168
- int lng_digit = lng_val % internal::kGridColumns ;
169
- code[internal::kSeparatorPosition + 2 + i] =
170
- internal::kAlphabet [lat_digit * internal::kGridColumns + lng_digit];
171
- lat_val /= internal::kGridRows ;
172
- lng_val /= internal::kGridColumns ;
173
- }
174
- } else {
175
- lat_val /= pow (internal::kGridRows , internal::kGridCodeLength );
176
- lng_val /= pow (internal::kGridColumns , internal::kGridCodeLength );
177
- }
178
-
179
- // Add the pair after the separator.
180
- code[internal::kSeparatorPosition + 1 ] =
181
- internal::kAlphabet [lat_val % internal::kEncodingBase ];
182
- code[internal::kSeparatorPosition + 2 ] =
183
- internal::kAlphabet [lng_val % internal::kEncodingBase ];
184
- lat_val /= internal::kEncodingBase ;
185
- lng_val /= internal::kEncodingBase ;
186
-
187
- // Compute the pair section before the separator in reverse order.
188
- // Even indices contain latitude and odd contain longitude.
189
- for (int i = (internal::kPairCodeLength / 2 + 1 ); i >= 0 ; i -= 2 ) {
190
- code[i] = internal::kAlphabet [lat_val % internal::kEncodingBase ];
191
- code[i + 1 ] = internal::kAlphabet [lng_val % internal::kEncodingBase ];
192
- lat_val /= internal::kEncodingBase ;
193
- lng_val /= internal::kEncodingBase ;
194
- }
195
- // Replace digits with padding if necessary.
196
- if (code_length < internal::kSeparatorPosition ) {
197
- for (size_t i = code_length; i < internal::kSeparatorPosition ; i++) {
198
- code[i] = internal::kPaddingCharacter ;
199
- }
200
- code_length = internal::kSeparatorPosition ;
201
- }
202
- // Return the code up to and including the separator.
203
- return code.substr (0 , code_length + 1 );
204
+ int64_t lat_val = internal::latitudeToInteger (location.latitude );
205
+ int64_t lng_val = internal::longitudeToInteger (location.longitude );
206
+ return internal::encodeIntegers (lat_val, lng_val, code_length);
204
207
}
205
208
206
209
std::string Encode (const LatLng &location) {
0 commit comments