99
1010namespace openlocationcode {
1111namespace internal {
12- const char kSeparator = ' +' ;
13- const char kPaddingCharacter = ' 0' ;
14- const char kAlphabet [] = " 23456789CFGHJMPQRVWX" ;
12+ constexpr char kSeparator = ' +' ;
13+ constexpr char kPaddingCharacter = ' 0' ;
14+ constexpr char kAlphabet [] = " 23456789CFGHJMPQRVWX" ;
1515// Number of digits in the alphabet.
16- const size_t kEncodingBase = 20 ;
16+ constexpr size_t kEncodingBase = 20 ;
1717// The max number of digits returned in a Plus Code. Roughly 1 x 0.5 cm.
18- const size_t kMaximumDigitCount = 15 ;
19- const size_t kMinimumDigitCount = 2 ;
20- const size_t kPairCodeLength = 10 ;
21- const size_t kGridCodeLength = kMaximumDigitCount - kPairCodeLength ;
22- const size_t kGridColumns = 4 ;
23- const size_t kGridRows = kEncodingBase / kGridColumns ;
24- const size_t kSeparatorPosition = 8 ;
18+ constexpr size_t kMaximumDigitCount = 15 ;
19+ constexpr size_t kMinimumDigitCount = 2 ;
20+ constexpr size_t kPairCodeLength = 10 ;
21+ constexpr size_t kGridCodeLength = kMaximumDigitCount - kPairCodeLength ;
22+ constexpr size_t kGridColumns = 4 ;
23+ constexpr size_t kGridRows = kEncodingBase / kGridColumns ;
24+ constexpr size_t kSeparatorPosition = 8 ;
2525// Work out the encoding base exponent necessary to represent 360 degrees.
2626const size_t kInitialExponent = floor(log(360 ) / log(kEncodingBase ));
2727// Work out the enclosing resolution (in degrees) for the grid algorithm.
2828const double kGridSizeDegrees =
29- 1 / pow(kEncodingBase , kPairCodeLength / 2 - (kInitialExponent + 1 ));
29+ 1 / pow(kEncodingBase , static_cast < double >( static_cast < size_t >( kPairCodeLength / 2 ) - (kInitialExponent + 1 ) ));
3030// Inverse (1/) of the precision of the final pair digits in degrees. (20^3)
31- const int64_t kPairPrecisionInverse = 8000 ;
31+ constexpr int64_t kPairPrecisionInverse = 8000 ;
3232// Inverse (1/) of the precision of the final grid digits in degrees.
3333// (Latitude and longitude are different.)
3434const int64_t kGridLatPrecisionInverse =
35- kPairPrecisionInverse * pow (kGridRows , kGridCodeLength );
35+ kPairPrecisionInverse * static_cast < int64_t >( pow(kGridRows , kGridCodeLength ) );
3636const int64_t kGridLngPrecisionInverse =
37- kPairPrecisionInverse * pow (kGridColumns , kGridCodeLength );
37+ static_cast < int64_t >( kPairPrecisionInverse * pow (kGridColumns , kGridCodeLength ) );
3838// Latitude bounds are -kLatitudeMaxDegrees degrees and +kLatitudeMaxDegrees
3939// degrees which we transpose to 0 and 180 degrees.
40- const int64_t kLatitudeMaxDegrees = 90 ;
40+ constexpr int64_t kLatitudeMaxDegrees = 90 ;
4141// Longitude bounds are -kLongitudeMaxDegrees degrees and +kLongitudeMaxDegrees
4242// degrees which we transpose to 0 and 360.
43- const int64_t kLongitudeMaxDegrees = 180 ;
43+ constexpr int64_t kLongitudeMaxDegrees = 180 ;
4444// Lookup table of the alphabet positions of characters 'C' through 'X',
4545// inclusive. A value of -1 means the character isn't part of the alphabet.
46- const int kPositionLUT [' X' - ' C' + 1 ] = {8 , -1 , -1 , 9 , 10 , 11 , -1 , 12 ,
46+ constexpr int kPositionLUT [' X' - ' C' + 1 ] = {8 , -1 , -1 , 9 , 10 , 11 , -1 , 12 ,
4747 -1 , -1 , 13 , -1 , -1 , 14 , 15 , 16 ,
4848 -1 , -1 , -1 , 17 , 18 , 19 };
4949
50- int64_t latitudeToInteger (double latitude) {
51- int64_t lat = floor (latitude * kGridLatPrecisionInverse );
50+ int64_t latitudeToInteger (const double latitude) {
51+ int64_t lat = floor (latitude * static_cast < double >( kGridLatPrecisionInverse ) );
5252 lat += kLatitudeMaxDegrees * kGridLatPrecisionInverse ;
5353 if (lat < 0 ) {
5454 lat = 0 ;
@@ -58,8 +58,8 @@ int64_t latitudeToInteger(double latitude) {
5858 return lat;
5959}
6060
61- int64_t longitudeToInteger (double longitude) {
62- int64_t lng = floor (longitude * kGridLngPrecisionInverse );
61+ int64_t longitudeToInteger (const double longitude) {
62+ int64_t lng = floor (longitude * static_cast < double >( kGridLngPrecisionInverse ) );
6363 lng += kLongitudeMaxDegrees * kGridLngPrecisionInverse ;
6464 if (lng <= 0 ) {
6565 lng = lng % (2 * kLongitudeMaxDegrees * kGridLngPrecisionInverse ) +
@@ -75,45 +75,45 @@ std::string encodeIntegers(int64_t lat_val, int64_t lng_val,
7575 // Reserve characters for the code digits and the separator.
7676 std::string code = " 1234567890abcdef" ;
7777 // Add the separator character.
78- code[internal:: kSeparatorPosition ] = internal:: kSeparator ;
78+ code[kSeparatorPosition ] = kSeparator ;
7979
8080 // Compute the grid part of the code if necessary.
81- if (code_length > internal:: kPairCodeLength ) {
82- for (size_t i = internal:: kGridCodeLength ; i >= 1 ; i--) {
83- int lat_digit = lat_val % internal:: kGridRows ;
84- int lng_digit = lng_val % internal:: kGridColumns ;
85- code[internal:: kSeparatorPosition + 2 + i] =
86- internal:: kAlphabet [lat_digit * internal:: kGridColumns + lng_digit];
87- lat_val /= internal:: kGridRows ;
88- lng_val /= internal:: kGridColumns ;
81+ if (code_length > kPairCodeLength ) {
82+ for (size_t i = kGridCodeLength ; i >= 1 ; i--) {
83+ int lat_digit = lat_val % kGridRows ;
84+ int lng_digit = lng_val % kGridColumns ;
85+ code[kSeparatorPosition + 2 + i] =
86+ kAlphabet [lat_digit * kGridColumns + lng_digit];
87+ lat_val /= kGridRows ;
88+ lng_val /= kGridColumns ;
8989 }
9090 } else {
91- lat_val /= pow (internal:: kGridRows , internal:: kGridCodeLength );
92- lng_val /= pow (internal:: kGridColumns , internal:: kGridCodeLength );
91+ lat_val /= pow (kGridRows , kGridCodeLength );
92+ lng_val /= pow (kGridColumns , kGridCodeLength );
9393 }
9494
9595 // Add the pair after the separator.
96- code[internal:: kSeparatorPosition + 1 ] =
97- internal:: kAlphabet [lat_val % internal:: kEncodingBase ];
98- code[internal:: kSeparatorPosition + 2 ] =
99- internal:: kAlphabet [lng_val % internal:: kEncodingBase ];
100- lat_val /= internal:: kEncodingBase ;
101- lng_val /= internal:: kEncodingBase ;
96+ code[kSeparatorPosition + 1 ] =
97+ kAlphabet [lat_val % kEncodingBase ];
98+ code[kSeparatorPosition + 2 ] =
99+ kAlphabet [lng_val % kEncodingBase ];
100+ lat_val /= kEncodingBase ;
101+ lng_val /= kEncodingBase ;
102102
103103 // Compute the pair section before the separator in reverse order.
104104 // Even indices contain latitude and odd contain longitude.
105- for (int i = (internal:: kPairCodeLength / 2 + 1 ); i >= 0 ; i -= 2 ) {
106- code[i] = internal:: kAlphabet [lat_val % internal:: kEncodingBase ];
107- code[i + 1 ] = internal:: kAlphabet [lng_val % internal:: kEncodingBase ];
108- lat_val /= internal:: kEncodingBase ;
109- lng_val /= internal:: kEncodingBase ;
105+ for (int i = (kPairCodeLength / 2 + 1 ); i >= 0 ; i -= 2 ) {
106+ code[i] = kAlphabet [lat_val % kEncodingBase ];
107+ code[i + 1 ] = kAlphabet [lng_val % kEncodingBase ];
108+ lat_val /= kEncodingBase ;
109+ lng_val /= kEncodingBase ;
110110 }
111111 // Replace digits with padding if necessary.
112- if (code_length < internal:: kSeparatorPosition ) {
113- for (size_t i = code_length; i < internal:: kSeparatorPosition ; i++) {
114- code[i] = internal:: kPaddingCharacter ;
112+ if (code_length < kSeparatorPosition ) {
113+ for (size_t i = code_length; i < kSeparatorPosition ; i++) {
114+ code[i] = kPaddingCharacter ;
115115 }
116- code_length = internal:: kSeparatorPosition ;
116+ code_length = kSeparatorPosition ;
117117 }
118118 // Return the code up to and including the separator.
119119 return code.substr (0 , code_length + 1 );
@@ -135,7 +135,7 @@ double pow_neg(double base, double exponent) {
135135// Compute the latitude precision value for a given code length. Lengths <= 10
136136// have the same precision for latitude and longitude, but lengths > 10 have
137137// different precisions due to the grid method having fewer columns than rows.
138- double compute_precision_for_length (int code_length) {
138+ double compute_precision_for_length (const int code_length) {
139139 if (code_length <= 10 ) {
140140 return pow_neg (internal::kEncodingBase , floor ((code_length / -2 ) + 2 ));
141141 }
@@ -235,8 +235,8 @@ CodeArea Decode(const std::string &code) {
235235 }
236236 }
237237 // Convert the place value to a float in degrees.
238- double lat_precision = ( double )pv / internal::kPairPrecisionInverse ;
239- double lng_precision = ( double )pv / internal::kPairPrecisionInverse ;
238+ double lat_precision = static_cast < double >(pv) / internal::kPairPrecisionInverse ;
239+ double lng_precision = static_cast < double >(pv) / internal::kPairPrecisionInverse ;
240240 // Process any extra precision digits.
241241 if (clean_code.size () > internal::kPairCodeLength ) {
242242 // Initialise the place values for the grid.
@@ -256,20 +256,20 @@ CodeArea Decode(const std::string &code) {
256256 }
257257 }
258258 // Adjust the precisions from the integer values to degrees.
259- lat_precision = ( double ) row_pv / internal::kGridLatPrecisionInverse ;
260- lng_precision = ( double ) col_pv / internal::kGridLngPrecisionInverse ;
259+ lat_precision = static_cast < double >( row_pv) / internal::kGridLatPrecisionInverse ;
260+ lng_precision = static_cast < double >( col_pv) / internal::kGridLngPrecisionInverse ;
261261 }
262262 // Merge the values from the normal and extra precision parts of the code.
263263 // Everything is ints so they all need to be cast to floats.
264- double lat = ( double ) normal_lat / internal::kPairPrecisionInverse +
265- ( double ) extra_lat / internal::kGridLatPrecisionInverse ;
266- double lng = ( double ) normal_lng / internal::kPairPrecisionInverse +
267- ( double ) extra_lng / internal::kGridLngPrecisionInverse ;
264+ double lat = static_cast < double >( normal_lat) / internal::kPairPrecisionInverse +
265+ static_cast < double >( extra_lat) / internal::kGridLatPrecisionInverse ;
266+ double lng = static_cast < double >( normal_lng) / internal::kPairPrecisionInverse +
267+ static_cast < double >( extra_lng) / internal::kGridLngPrecisionInverse ;
268268 // Round everything off to 14 places.
269- return CodeArea ( round (lat * 1e14 ) / 1e14 , round (lng * 1e14 ) / 1e14 ,
269+ return { round (lat * 1e14 ) / 1e14 , round (lng * 1e14 ) / 1e14 ,
270270 round ((lat + lat_precision) * 1e14 ) / 1e14 ,
271271 round ((lng + lng_precision) * 1e14 ) / 1e14 ,
272- clean_code.size ()) ;
272+ clean_code.size ()} ;
273273}
274274
275275std::string Shorten (const std::string &code, const LatLng &reference_location) {
@@ -279,23 +279,23 @@ std::string Shorten(const std::string &code, const LatLng &reference_location) {
279279 if (code.find (internal::kPaddingCharacter ) != std::string::npos) {
280280 return code;
281281 }
282- CodeArea code_area = Decode (code);
283- LatLng center = code_area.GetCenter ();
282+ const CodeArea code_area = Decode (code);
283+ const LatLng center = code_area.GetCenter ();
284284 // Ensure that latitude and longitude are valid.
285- double latitude =
285+ const double latitude =
286286 adjust_latitude (reference_location.latitude , CodeLength (code));
287- double longitude = normalize_longitude (reference_location.longitude );
287+ const double longitude = normalize_longitude (reference_location.longitude );
288288 // How close are the latitude and longitude to the code center.
289- double range = std::max (fabs (center.latitude - latitude),
289+ const double range = std::max (fabs (center.latitude - latitude),
290290 fabs (center.longitude - longitude));
291291 std::string code_copy (code);
292- const double safety_factor = 0.3 ;
293- const int removal_lengths[ 3 ] = { 8 , 6 , 4 };
294- for ( int removal_length : removal_lengths) {
292+ constexpr int removal_lengths[ 3 ] = { 8 , 6 , 4 } ;
293+ for ( const int removal_length : removal_lengths) {
294+ constexpr double safety_factor = 0.3 ;
295295 // Check if we're close enough to shorten. The range must be less than 1/2
296296 // the resolution to shorten at all, and we want to allow some safety, so
297297 // use 0.3 instead of 0.5 as a multiplier.
298- double area_edge =
298+ const double area_edge =
299299 compute_precision_for_length (removal_length) * safety_factor;
300300 if (range < area_edge) {
301301 code_copy = code_copy.substr (removal_length);
0 commit comments