@@ -16,7 +16,6 @@ package olc
1616
1717import (
1818 "errors"
19- "strings"
2019)
2120
2221var (
@@ -43,17 +42,25 @@ func Encode(lat, lng float64, codeLen int) string {
4342 // This allows us to use only integer operations, so avoiding any accumulation of floating point representation errors.
4443 latVal := latitudeAsInteger (lat )
4544 lngVal := longitudeAsInteger (lng )
46-
4745 // Clip the code length to legal values.
4846 codeLen = clipCodeLen (codeLen )
49- // Use a char array so we can build it up from the end digits, without having
50- // to keep reallocating strings.
51- var code [maxCodeLen + 1 ]byte
47+ // Call the integer based encoding method.
48+ return integerEncode (latVal , lngVal , codeLen )
49+ }
50+
51+ func integerEncode (latVal , lngVal int64 , codeLen int ) string {
52+ // Use a char array so we can build it up from the end digits, without having to keep reallocating strings.
53+ // Prime it with padding and separator.
54+ var code []byte = []byte ("00000000+0012345" )
5255
5356 // Compute the grid part of the code if necessary.
5457 if codeLen > pairCodeLen {
5558 for i := maxCodeLen - pairCodeLen ; i >= 1 ; i -- {
56- code [sepPos + 2 + i ], latVal , lngVal = latLngGridStep (latVal , lngVal )
59+ latDigit := latVal % int64 (gridRows )
60+ lngDigit := lngVal % int64 (gridCols )
61+ code [sepPos + 2 + i ] = Alphabet [latDigit * gridCols + lngDigit ]
62+ latVal /= int64 (gridRows )
63+ lngVal /= int64 (gridCols )
5764 }
5865 } else {
5966 latVal /= gridLatFullValue
@@ -64,9 +71,6 @@ func Encode(lat, lng float64, codeLen int) string {
6471 code [sepPos + 2 ], lngVal = pairIndexStep (lngVal )
6572 code [sepPos + 1 ], latVal = pairIndexStep (latVal )
6673
67- // Avoid the need for string concatenation by filling in the Separator manually.
68- code [sepPos ] = Separator
69-
7074 // Compute the pair section of the code.
7175 // Even indices contain latitude and odd contain longitude.
7276 for pairStart := (pairCodeLen / 2 + 1 ); pairStart >= 0 ; pairStart = pairStart - 2 {
@@ -77,8 +81,11 @@ func Encode(lat, lng float64, codeLen int) string {
7781 if codeLen >= sepPos {
7882 return string (code [:codeLen + 1 ])
7983 }
80- // Pad and return the code.
81- return string (code [:codeLen ]) + strings .Repeat (string (Padding ), sepPos - codeLen ) + string (Separator )
84+ // If the code needs padding, add it and return to the separator.
85+ for i := codeLen ; i < sepPos ; i ++ {
86+ code [i ] = Padding
87+ }
88+ return string (code [:sepPos + 1 ])
8289}
8390
8491// clipCodeLen returns the smallest valid code length greater than or equal to
@@ -97,16 +104,6 @@ func clipCodeLen(codeLen int) int {
97104 return codeLen
98105}
99106
100- // latLngGridStep computes the next smallest grid code in sequence,
101- // followed by the remaining latitude and longitude values not yet converted
102- // to a grid code.
103- func latLngGridStep (latVal , lngVal int64 ) (byte , int64 , int64 ) {
104- latDigit := latVal % int64 (gridRows )
105- lngDigit := lngVal % int64 (gridCols )
106- ndx := latDigit * gridCols + lngDigit
107- return Alphabet [ndx ], latVal / int64 (gridRows ), lngVal / int64 (gridCols )
108- }
109-
110107// pairIndexStep computes the next smallest pair code in sequence,
111108// followed by the remaining integer not yet converted to a pair code.
112109func pairIndexStep (coordinate int64 ) (byte , int64 ) {
0 commit comments