@@ -44,23 +44,35 @@ const (
4444// codes represent smaller areas, but lengths > 14 are sub-centimetre and so
4545// 11 or 12 are probably the limit of useful codes.
4646func Encode (lat , lng float64 , codeLen int ) string {
47- codeLen = clipCodeLen (codeLen )
48- // Clip the latitude. Normalise the longitude.
49- lat , lng = clipLatitude (lat ), normalizeLng (lng )
50- // Latitude 90 needs to be adjusted to be just less, so the returned code
51- // can also be decoded.
52- if lat == latMax {
53- lat = normalizeLat (lat - computeLatPrec (codeLen ))
47+ // This approach converts each value to an integer after multiplying it by the final precision.
48+ // This allows us to use only integer operations, so avoiding any accumulation of floating point representation errors.
49+
50+ // Convert latitude into a positive integer clipped into the range 0-(just under 180*2.5e7).
51+ // Latitude 90 needs to be adjusted to be just less, so the returned code can also be decoded.
52+ latVal := int64 (math .Round (lat * finalLatPrecision ))
53+ latVal += latMax * finalLatPrecision
54+ if latVal < 0 {
55+ latVal = 0
56+ } else if latVal >= 2 * latMax * finalLatPrecision {
57+ latVal = 2 * latMax * finalLatPrecision - 1
58+ }
59+ // Convert longitude into a positive integer and normalise it into the range 0-360*8.192e6.
60+ lngVal := int64 (math .Round (lng * finalLngPrecision ))
61+ lngVal += lngMax * finalLngPrecision
62+ if lngVal <= 0 {
63+ lngVal = lngVal % (2 * lngMax * finalLngPrecision ) + 2 * lngMax * finalLngPrecision
64+ } else if lngVal >= 2 * lngMax * finalLngPrecision {
65+ lngVal = lngVal % (2 * lngMax * finalLngPrecision )
5466 }
67+
68+ // Clip the code length to legal values.
69+ codeLen = clipCodeLen (codeLen )
5570 // Use a char array so we can build it up from the end digits, without having
5671 // to keep reallocating strings.
5772 var code [maxCodeLen + 1 ]byte
5873
59- // Compute the code.
60- // This approach converts each value to an integer after multiplying it by
61- // the final precision. This allows us to use only integer operations, so
62- // avoiding any accumulation of floating point representation errors.
63- latVal , lngVal := roundLatLngToInts (lat , lng )
74+ // // Compute the code.
75+ // latVal, lngVal := roundLatLngToInts(lat, lng)
6476
6577 // Compute the grid part of the code if necessary.
6678 if codeLen > pairCodeLen {
0 commit comments