Description
The encoding and decoding implementations use integers rather than floats to avoid the build up of precision losses through repeated division or multiplication, and to improve the computation speed.
The initial conversion of degrees to integer for latitude is:
latVal := int64(math.Round(latDegrees * finalLatPrecision))
latVal += latMax * finalLatPrecision
(finalLatPrecision
is 2.5e7, and is the number of divisions in one degree of latitude that a maximum length OLC code can represent.)
The conversion results in an integer value that will be used to compute the code. Conversion from the integer to the code and back is stable (I mean there are no issues with precision loss).
Ideally we would have an integer that when converted back to a range contains the original latitude value. By range, I mean using the conversion value and adding 1/finalLatPrecision
.
Unfortunately using math.Round()
means that the resulting integer can be 1 higher than it should be, and after converting back to a range it does not contain the original latitude.
(Everything also applies to longitude.)
The impact is small because we are talking about being out by 1/2.5e7 or 1/8.192e6 degrees, or about half a centimetre, but this won't be helping the test cases.