OpenLocationCode (olc v0.1.0)
View SourceConvert locations to and from Open Location Code (Plus Code).
Plus Codes are short, 10-11 character codes that can be used instead of street addresses. The codes can be generated and decoded offline, and use a reduced character set that minimises the chance of codes including words.
Codes are able to be shortened relative to a nearby location. This means that in many cases, only four to seven characters of the code are needed. To recover the original code, the same location is not required, as long as a nearby location is provided.
Codes represent rectangular areas rather than points, and the longer the code, the smaller the area. A 10 character code represents a 13.5x13.5 meter area (at the equator). An 11 character code represents approximately a 2.8x3.5 meter area.
Examples
# Encode a location, default accuracy:
OpenLocationCode.encode(47.365590, 8.524997)
#=> {:ok, "8FVC9G8F+6X"}
# Encode a location using one stage of additional refinement:
OpenLocationCode.encode(47.365590, 8.524997, 11)
#=> {:ok, "8FVC9G8F+6XQ"}
# Decode a full code:
{:ok, code_area} = OpenLocationCode.decode("8FVC9G8F+6X")
# Attempt to trim the first characters from a code:
OpenLocationCode.shorten("8FVC9G8F+6X", 47.5, 8.5)
#=> {:ok, "9G8F+6X"}
# Recover the full code from a short code:
OpenLocationCode.recover_nearest("9G8F+6X", 47.4, 8.6)
#=> {:ok, "8FVC9G8F+6X"}
OpenLocationCode.recover_nearest("8F+6X", 47.4, 8.6)
#=> {:ok, "8FVC9G8F+6X"}
Summary
Functions
Clip a latitude into the range -90 to 90.
Decodes an Open Location Code into location coordinates.
Encode a location into an Open Location Code.
Encode a location using integer values into a code.
Determines if a code is a valid full Open Location Code.
Convert location in degrees into integer representations.
Normalize a longitude into the range -180 to 180, not including 180.
Recover the nearest matching full code to a specified location.
Determines if a code is a valid short code.
Remove characters from the start of an Open Location Code.
Determines if a code is valid.
Functions
Clip a latitude into the range -90 to 90.
Decodes an Open Location Code into location coordinates.
Returns a tuple with :ok
and a CodeArea
struct that includes the
coordinates of the bounding box - the lower left, center and upper right.
Returns an error tuple if the code is invalid or not a full code.
Examples
iex> OpenLocationCode.decode("8FVC9G8F+6X")
{:ok,
%OpenLocationCode.CodeArea{
latitude_lo: 47.3655,
longitude_lo: 8.524875,
latitude_hi: 47.36562499999999,
longitude_hi: 8.525,
latitude_center: 47.365562499999996,
longitude_center: 8.5249375,
code_length: 10
}}
iex> OpenLocationCode.decode("invalid")
{:error, :invalid_code}
iex> OpenLocationCode.decode("9G8F+6X") # short code
{:error, :full_code_expected}
Encode a location into an Open Location Code.
Produces a code of the specified length, or the default length if no length is provided. The length determines the accuracy of the code. The default length is 10 characters.
Parameters
latitude
- The latitude in degrees (must be between -90 and 90)longitude
- The longitude in degrees (must be between -180 and 180)code_length
- The desired length of the code (default: 10, max: 15)
Examples
iex> OpenLocationCode.encode(47.365590, 8.524997)
{:ok, "8FVC9G8F+6X"}
iex> OpenLocationCode.encode(47.365590, 8.524997, 11)
{:ok, "8FVC9G8F+6XQ"}
Encode a location using integer values into a code.
This function takes pre-computed integer representations of latitude and longitude coordinates and generates an Open Location Code.
Examples
iex> OpenLocationCode.encode_integers(4736559000, 852499700, 10)
{:ok, "F7F6F367+WX"}
Determines if a code is a valid full Open Location Code.
Not all possible combinations of Open Location Code characters decode to valid latitude and longitude values. This checks that a code is valid and also that the latitude and longitude values are legal.
Examples
iex> OpenLocationCode.full?("8FVC9G8F+6X")
true
iex> OpenLocationCode.full?("9G8F+6X") # short code
false
iex> OpenLocationCode.full?("invalid")
false
Convert location in degrees into integer representations.
This is an internal helper function that converts floating-point coordinates into integer values for processing.
Examples
iex> OpenLocationCode.location_to_integers(47.365590, 8.524997)
{:ok, {3434139750, 1544396775}}
Normalize a longitude into the range -180 to 180, not including 180.
Recover the nearest matching full code to a specified location.
Given a short code of between four and seven characters, this recovers the nearest matching full code to the specified location.
If a full code is provided, it returns the code in proper capitalization.
Parameters
code
- A short Open Location Code (or full code)reference_latitude
- Reference latitude in degreesreference_longitude
- Reference longitude in degrees
Examples
iex> OpenLocationCode.recover_nearest("9G8F+6X", 47.4, 8.6)
{:ok, "8FVC9G8F+6X"}
iex> OpenLocationCode.recover_nearest("8F+6X", 47.4, 8.6)
{:ok, "8FVCCJ8F+6X"}
# Full codes are returned as-is (but uppercased)
iex> OpenLocationCode.recover_nearest("8fvc9g8f+6x", 47.4, 8.6)
{:ok, "8FVC9G8F+6X"}
Determines if a code is a valid short code.
A short Open Location Code is a sequence created by removing four or more digits from an Open Location Code. It must include a separator character.
Examples
iex> OpenLocationCode.short?("9G8F+6X")
true
iex> OpenLocationCode.short?("8F+6X")
true
iex> OpenLocationCode.short?("8FVC9G8F+6X") # full code
false
iex> OpenLocationCode.short?("invalid")
false
Remove characters from the start of an Open Location Code.
This uses a reference location to determine how many initial characters can be removed from the OLC code. The closer the reference location is to the code's center, the more characters can be removed.
Returns an error if the code cannot be shortened (e.g., if it's not a full code, contains padding, or is too short).
Parameters
code
- A full Open Location Codelatitude
- Reference latitude in degreeslongitude
- Reference longitude in degrees
Examples
iex> OpenLocationCode.shorten("8FVC9G8F+6X", 47.5, 8.5)
{:ok, "9G8F+6X"}
# Error cases
iex> OpenLocationCode.shorten("9G8F+6X", 47.5, 8.5) # short code
{:error, :full_code_expected}
iex> OpenLocationCode.shorten("8FVC00+", 47.5, 8.5) # padded code
{:error, :cannot_shorten_padded_codes}
Determines if a code is valid.
To be valid, all characters must be from the Open Location Code character set with at most one separator. The separator can be in any even-numbered position up to the eighth digit.
Examples
iex> OpenLocationCode.valid?("8FVC9G8F+6X")
true
iex> OpenLocationCode.valid?("8FVC9G8F+6XQ")
true
iex> OpenLocationCode.valid?("invalid")
false
iex> OpenLocationCode.valid?("8FVC9G8F6X") # missing separator
false