@@ -82,23 +82,13 @@ int OLC_IsFull(const char* code, size_t size) {
8282 return is_full (& info );
8383}
8484
85- int OLC_Encode (const OLC_LatLon * location , size_t length , char * code ,
86- int maxlen ) {
85+ void OLC_LocationToIntegers (const OLC_LatLon * degrees ,
86+ OLC_LatLonIntegers * integers ) {
8787 // Multiply degrees by precision. Use lround to explicitly round rather than
8888 // truncate, which causes issues when using values like 0.1 that do not have
8989 // precise floating point representations.
90- long long int lat = lround (location -> lat * kGridLatPrecisionInverse );
91- long long int lng = lround (location -> lon * kGridLonPrecisionInverse );
92- // Limit the maximum number of digits in the code.
93- if (length > kMaximumDigitCount ) {
94- length = kMaximumDigitCount ;
95- }
96- if (length < kMinimumDigitCount ) {
97- length = kMinimumDigitCount ;
98- }
99- if (length < kPairCodeLength && length % 2 == 1 ) {
100- length = length + 1 ;
101- }
90+ long long int lat = lround (degrees -> lat * kGridLatPrecisionInverse );
91+ long long int lon = lround (degrees -> lon * kGridLonPrecisionInverse );
10292 // Convert latitude to positive range (0..2*degrees*precision) and clip.
10393 lat += OLC_kLatMaxDegrees * kGridLatPrecisionInverse ;
10494 if (lat < 0 ) {
@@ -108,16 +98,35 @@ int OLC_Encode(const OLC_LatLon* location, size_t length, char* code,
10898 lat = 2 * OLC_kLatMaxDegrees * kGridLatPrecisionInverse - 1 ;
10999 }
110100 // Convert longitude to the positive range and normalise.
111- lng += OLC_kLonMaxDegrees * kGridLonPrecisionInverse ;
112- if (lng < 0 ) {
101+ lon += OLC_kLonMaxDegrees * kGridLonPrecisionInverse ;
102+ if (lon < 0 ) {
113103 // If after adding 180 it is still less than zero, do integer division
114104 // on a full longitude (360) and add the remainder.
115- lng = lng % (2 * OLC_kLonMaxDegrees * kGridLonPrecisionInverse ) +
105+ lon = lon % (2 * OLC_kLonMaxDegrees * kGridLonPrecisionInverse ) +
116106 (2 * OLC_kLonMaxDegrees * kGridLonPrecisionInverse );
117- } else if (lng >= 2 * OLC_kLonMaxDegrees * kGridLonPrecisionInverse ) {
107+ } else if (lon >= 2 * OLC_kLonMaxDegrees * kGridLonPrecisionInverse ) {
118108 // If it's greater than 360, just get the integer division remainder.
119- lng = lng % (2 * OLC_kLonMaxDegrees * kGridLonPrecisionInverse );
109+ lon = lon % (2 * OLC_kLonMaxDegrees * kGridLonPrecisionInverse );
120110 }
111+ integers -> lat = lat ;
112+ integers -> lon = lon ;
113+ }
114+
115+ int OLC_EncodeIntegers (const OLC_LatLonIntegers * location , size_t length ,
116+ char * code , int maxlen ) {
117+ // Limit the maximum number of digits in the code.
118+ if (length > kMaximumDigitCount ) {
119+ length = kMaximumDigitCount ;
120+ }
121+ if (length < kMinimumDigitCount ) {
122+ length = kMinimumDigitCount ;
123+ }
124+ if (length < kPairCodeLength && length % 2 == 1 ) {
125+ length = length + 1 ;
126+ }
127+
128+ long long int lat = location -> lat ;
129+ long long int lon = location -> lon ;
121130
122131 // Reserve characters for the code digits, the separator and the null
123132 // terminator.
@@ -129,30 +138,30 @@ int OLC_Encode(const OLC_LatLon* location, size_t length, char* code,
129138 if (length > kPairCodeLength ) {
130139 for (size_t i = kMaximumDigitCount - kPairCodeLength ; i >= 1 ; i -- ) {
131140 int lat_digit = lat % kGridRows ;
132- int lng_digit = lng % kGridCols ;
141+ int lng_digit = lon % kGridCols ;
133142 fullcode [kSeparatorPosition + 2 + i ] =
134143 kAlphabet [lat_digit * kGridCols + lng_digit ];
135144 lat /= kGridRows ;
136- lng /= kGridCols ;
145+ lon /= kGridCols ;
137146 }
138147 } else {
139148 lat /= pow (kGridRows , kGridCodeLength );
140- lng /= pow (kGridCols , kGridCodeLength );
149+ lon /= pow (kGridCols , kGridCodeLength );
141150 }
142151
143152 // Add the pair after the separator.
144153 fullcode [kSeparatorPosition + 1 ] = kAlphabet [lat % kEncodingBase ];
145- fullcode [kSeparatorPosition + 2 ] = kAlphabet [lng % kEncodingBase ];
154+ fullcode [kSeparatorPosition + 2 ] = kAlphabet [lon % kEncodingBase ];
146155 lat /= kEncodingBase ;
147- lng /= kEncodingBase ;
156+ lon /= kEncodingBase ;
148157
149158 // Compute the pair section before the separator in reverse order.
150159 // Even indices contain latitude and odd contain longitude.
151160 for (int i = (kPairCodeLength / 2 + 1 ); i >= 0 ; i -= 2 ) {
152161 fullcode [i ] = kAlphabet [lat % kEncodingBase ];
153- fullcode [i + 1 ] = kAlphabet [lng % kEncodingBase ];
162+ fullcode [i + 1 ] = kAlphabet [lon % kEncodingBase ];
154163 lat /= kEncodingBase ;
155- lng /= kEncodingBase ;
164+ lon /= kEncodingBase ;
156165 }
157166 // Replace digits with padding if necessary.
158167 if (length < kSeparatorPosition ) {
@@ -170,6 +179,13 @@ int OLC_Encode(const OLC_LatLon* location, size_t length, char* code,
170179 return length ;
171180}
172181
182+ int OLC_Encode (const OLC_LatLon * location , size_t length , char * code ,
183+ int maxlen ) {
184+ OLC_LatLonIntegers integers ;
185+ OLC_LocationToIntegers (location , & integers );
186+ return OLC_EncodeIntegers (& integers , length , code , maxlen );
187+ }
188+
173189int OLC_EncodeDefault (const OLC_LatLon * location , char * code , int maxlen ) {
174190 return OLC_Encode (location , kPairCodeLength , code , maxlen );
175191}
0 commit comments