Coordinate handling for Rover.
Rover speaks {latitude, longitude} everywhere — the order humans use when
they read a coordinate out loud, and the order Leaflet uses. OpenLayers works
internally in [x, y] (i.e. [longitude, latitude]) projected to Web
Mercator; that flip happens once, in the JavaScript runtime, and never leaks
into your application code.
Mixing the two up is the single most common OpenLayers bug, so this module is
deliberately strict: latitudes outside -90..90 and longitudes outside
-180..180 raise instead of silently placing your marker in the ocean.
iex> Rover.Geo.coord!({45.75, 4.85})
{45.75, 4.85}
iex> Rover.Geo.coord!(%{lat: 45.75, lng: 4.85})
{45.75, 4.85}
Summary
Types
A bounding box, as {south, west, north, east}.
A latitude/longitude pair, in that order.
Anything Rover accepts as a coordinate: a {lat, lon} tuple, or a map with
:lat/:latitude and :lon/:lng/:longitude keys (atom or string).
Functions
Returns the bounding box {south, west, north, east} enclosing coords.
Same as coord!/1 but returns {:ok, coord} or :error.
Normalises value into a {lat, lon} tuple of floats.
Great-circle distance between two coordinates, in metres (haversine).
Renders a coordinate as the [lon, lat] pair OpenLayers expects.
Types
Functions
Returns the bounding box {south, west, north, east} enclosing coords.
Returns nil for an empty list. Note that this is a plain min/max box: it does
not handle geometries straddling the antimeridian.
Examples
iex> Rover.Geo.bbox([{45.0, 4.0}, {46.0, 5.0}])
{45.0, 4.0, 46.0, 5.0}
iex> Rover.Geo.bbox([])
nil
Same as coord!/1 but returns {:ok, coord} or :error.
Normalises value into a {lat, lon} tuple of floats.
Raises ArgumentError when the shape is unrecognised or the values are out of
range.
Examples
iex> Rover.Geo.coord!({45.75, 4.85})
{45.75, 4.85}
iex> Rover.Geo.coord!(%{"latitude" => 48, "longitude" => 2})
{48.0, 2.0}A latitude of 145.75 is not a latitude, so Rover rejects it rather than
quietly drawing your marker somewhere impossible:
iex> Rover.Geo.coord(%{lat: 145.75, lon: 4.85})
:error
Great-circle distance between two coordinates, in metres (haversine).
Examples
iex> Rover.Geo.distance({45.75, 4.85}, {48.85, 2.35}) |> round()
392834
Renders a coordinate as the [lon, lat] pair OpenLayers expects.
You should not need this — the JavaScript runtime handles the flip — but it is
public so that Rover.Geo stays useful when you drop down to raw GeoJSON.
iex> Rover.Geo.to_lon_lat({45.75, 4.85})
[4.85, 45.75]