MCPcopy Create free account
hub / github.com/comaps/comaps / Decode

Function Decode

3party/open-location-code/openlocationcode.cc:193–254  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

191}
192
193CodeArea Decode(const std::string &code) {
194 std::string clean_code = clean_code_chars(code);
195 // Constrain to the maximum length.
196 if (clean_code.size() > internal::kMaximumDigitCount) {
197 clean_code = clean_code.substr(0, internal::kMaximumDigitCount);
198 }
199 // Initialise the values for each section. We work them out as integers and
200 // convert them to floats at the end.
201 int normal_lat =
202 -internal::kLatitudeMaxDegrees * internal::kPairPrecisionInverse;
203 int normal_lng =
204 -internal::kLongitudeMaxDegrees * internal::kPairPrecisionInverse;
205 int extra_lat = 0;
206 int extra_lng = 0;
207 // How many digits do we have to process?
208 size_t digits = std::min(internal::kPairCodeLength, clean_code.size());
209 // Define the place value for the most significant pair.
210 int pv = pow(internal::kEncodingBase, internal::kPairCodeLength / 2 - 1);
211 for (size_t i = 0; i < digits - 1; i += 2) {
212 normal_lat += get_alphabet_position(clean_code[i]) * pv;
213 normal_lng += get_alphabet_position(clean_code[i + 1]) * pv;
214 if (i < digits - 2) {
215 pv /= internal::kEncodingBase;
216 }
217 }
218 // Convert the place value to a float in degrees.
219 double lat_precision = (double)pv / internal::kPairPrecisionInverse;
220 double lng_precision = (double)pv / internal::kPairPrecisionInverse;
221 // Process any extra precision digits.
222 if (clean_code.size() > internal::kPairCodeLength) {
223 // Initialise the place values for the grid.
224 int row_pv = pow(internal::kGridRows, internal::kGridCodeLength - 1);
225 int col_pv = pow(internal::kGridColumns, internal::kGridCodeLength - 1);
226 // How many digits do we have to process?
227 digits = std::min(internal::kMaximumDigitCount, clean_code.size());
228 for (size_t i = internal::kPairCodeLength; i < digits; i++) {
229 int dval = get_alphabet_position(clean_code[i]);
230 int row = dval / internal::kGridColumns;
231 int col = dval % internal::kGridColumns;
232 extra_lat += row * row_pv;
233 extra_lng += col * col_pv;
234 if (i < digits - 1) {
235 row_pv /= internal::kGridRows;
236 col_pv /= internal::kGridColumns;
237 }
238 }
239 // Adjust the precisions from the integer values to degrees.
240 lat_precision = (double)row_pv / internal::kGridLatPrecisionInverse;
241 lng_precision = (double)col_pv / internal::kGridLngPrecisionInverse;
242 }
243 // Merge the values from the normal and extra precision parts of the code.
244 // Everything is ints so they all need to be cast to floats.
245 double lat = (double)normal_lat / internal::kPairPrecisionInverse +
246 (double)extra_lat / internal::kGridLatPrecisionInverse;
247 double lng = (double)normal_lng / internal::kPairPrecisionInverse +
248 (double)extra_lng / internal::kGridLngPrecisionInverse;
249 // Round everything off to 14 places.
250 return CodeArea(round(lat * 1e14) / 1e14, round(lng * 1e14) / 1e14,

Callers 2

ShortenFunction · 0.70
RecoverNearestFunction · 0.70

Calls 4

clean_code_charsFunction · 0.85
get_alphabet_positionFunction · 0.85
CodeAreaClass · 0.85
sizeMethod · 0.45

Tested by

no test coverage detected