An Open Location Code library for Common Lisp.
Open Location Code is a location encoding system for addresses, independent of street names and building numbers. The encoded location identifier is called Plus Code since it always contains a plus sign character. For example, 8FX8QJ2G+QH is the Plus Code of the Roman bridge in Trier, Germany.
See https://plus.codes.
The methods requested by the Open Location Code specification are implemented as follows:
encode(latitude longitude) ⇒ full-code
Convert a latitude and longitude into a 10 digit Plus Code.encode(latitude longitude precision) ⇒ full-code
Convert a latitude and longitude into an arbitrary length Plus Code.decode(code) ⇒ code-area
Decode a Plus Code into, at a minimum, the latitude and longitude of the south-west corner and the area’s height and width.validp(code) ⇒ boolean
Determine if a string is a valid sequence of Plus Code characters.fullp(code) ⇒ boolean
Determine if a string is a valid full Plus Code.shortp(code) ⇒ boolean
Determine if a string is a valid short Plus Code.shorten(full-code latitude longitude) ⇒ short-code
Remove four or six digits from the front of a Plus Code given a reference location.recover(short-code latitude longitude) ⇒ full-code
Recover a full Plus Code from a short code and a reference location.
See https://github.com/google/open-location-code/ for more documentation and sample implementations.
The Open Location Code library is available in Quicklisp.
(ql:quickload "open-location-code")The test suite can be run by evaluating the following form.
(asdf:test-system "open-location-code")The Open Location Code library uses integer arithmetic for converting
locations to Plus Codes and vice versa. The Common Lisp rationalize
function is used to convert locations given in floating-point numbers
into rational numbers.
The Google developers finally realized that floating-point arithmetic is inaccurate by definition. They are now in the transition phase to integer arithmetic. However, there is IMHO still some inconsistency between the integer algorithms and the numbers in the test data. Due to that, one encoding test fails with an off-by-one error for the time being:
| Failed Form: (OPEN-LOCATION-CODE:ENCODE OPEN-LOCATION-CODE-TESTS::LAT
OPEN-LOCATION-CODE-TESTS::LON
OPEN-LOCATION-CODE-TESTS::PREC)
| Expected "CHGW2H5C+X2RRRRR" but saw "CHGW2H5C+X2RRRRJ"
| OPEN-LOCATION-CODE-TESTS::LAT => 80.00999996d0
| OPEN-LOCATION-CODE-TESTS::LON => 58.57d0
| OPEN-LOCATION-CODE-TESTS::PREC => 10
The test succeeds if you write 80.00999996 as 8000999996/100000000. Changing 80.00999996 to 80.009999960000009 fixes the floating-point inaccuracy issue since the rational number approximation for this number is always closer to the next larger floating-point number and thus greater than 80.00999996.