Install the Geo library
masterTo use Geo in your Elixir project, add it to your mix.exs dependencies list. Use the ~> 4.0 version constraint to ensure compatibility with the v4 series.
defp deps do
[
{:geo, "~> 4.0"}
]
endrepository·master·Indexed 20 days ago
https://github.com/felt/geoA collection of GIS functions for Elixir that handles conversions to and from WKT, WKB, and GeoJSON for various geometry types, including Point, LineString, Polygon, and their Multi/Z/M variants.
To use Geo in your Elixir project, add it to your mix.exs dependencies list. Use the ~> 4.0 version constraint to ensure compatibility with the v4 series.
defp deps do
[
{:geo, "~> 4.0"}
]
endThe Geo.WKT.Decoder supports WKT strings that include a Spatial Reference System Identifier (SRID). To include an SRID, format the string by prefixing the WKT with SRID= followed by the integer ID and a semicolon. The decoder will extract the integer and assign it to the srid field of the resulting Geo.geometry struct.
# Decoding a WKT string with an SRID
# Format: "SRID=ID;WKT"
{:ok, geometry} = Geo.WKT.Decoder.decode("SRID=4326;POINT(1 1)")
# The resulting struct will have the srid field set
# %Geo.Point{coordinates: {1.0, 1.0}, srid: 4326}The Geo library provides automatic JSON encoding for all geometry types. It detects and uses the available JSON library (JSON or Jason) to encode geometries via Geo.JSON.encode!/1.
# If Jason is loaded, Geo.Point implements Jason.Encoder
geo = %Geo.Point{x: 1.0, y: 2.0}
Jason.encode!(geo)When calling Geo.JSON.Encoder.encode!/2 with a %Geo.GeometryCollection{} and the option feature: true, the encoder translates the collection into a GeoJSON FeatureCollection.
In this mode, the properties defined on the GeometryCollection are merged into each individual Feature within the collection. Properties defined on the encapsulated Geo.geometry() structs will override the properties inherited from the collection.
# If geom is a %Geo.GeometryCollection{properties: %{a: 1}, geometries: [...]}
# and you call:
Geo.JSON.Encoder.encode!(geom, feature: true)
# The result is a %{"type" => "FeatureCollection", "features" => [...]}
# where each feature's properties include %{"a" => 1}When the :impl_to_string compilation environment variable is set to true, all Geo geometry types implement the String.Chars protocol. This allows you to convert any geometry to its Well-Known Text (WKT) representation using to_string/1 or string interpolation.
# Requires compilation with :impl_to_string set to true
geo = %Geo.Point{x: 1.0, y: 2.0}
"#{geo}" # Uses Geo.WKT.encode!/1 internallyUse Geo.WKB to handle Well-Known Binary (WKB) and Extended WKB (EWKB) formats. This is useful for low-level binary geospatial data exchange.
Geo.WKB.decode(binary): Returns {:ok, geometry} or {:error, reason}.Geo.WKB.decode!(binary): Returns the geometry struct or raises an error.Geo.WKB.encode!(geometry): Returns the WKB binary string.{:ok, point} = Geo.WKB.decode("0101000000000000000000F03F000000000000F03F")
%Geo.Point{ coordinates: {1.0, 1.0}, srid: nil }
Geo.WKB.encode!(point)
"00000000013FF00000000000003FF0000000000000"
point = Geo.WKB.decode!("0101000020E61000009EFB613A637B4240CF2C0950D3735EC0")
%Geo.Point{ coordinates: {36.9639657, -121.8097725}, srid: 4326 }
Geo.WKB.encode!(point)
"0020000001000010E640427B633A61FB9EC05E73D350092CCF"Geo.JSON handles the conversion between Geo structs and maps that follow the GeoJSON specification.
Important: Geo.JSON does not perform JSON parsing/stringification itself. You must use a JSON library (like Jason) to convert between JSON strings and maps before/after using Geo.JSON.
Geo.JSON.encode(geometry): Returns {:ok, map} where the map is shaped as GeoJSON.Geo.JSON.decode(map): Returns {:ok, geometry} from a GeoJSON-shaped map.Geo.JSON.encode!(geometry): Returns a GeoJSON-shaped map.# Convert struct to GeoJSON-shaped map
Geo.JSON.encode(point)
{:ok, %{ "type" => "Point", "coordinates" => [100.0, 0.0] }}
# Convert GeoJSON-shaped map to struct (requires external JSON parser)
point = JSON.decode!("{\"type\": \"Point\", \"coordinates\": [100.0, 0.0] }") |> Geo.JSON.decode
{:ok, %Geo.Point{coordinates: {100.0, 0.0}, srid: 4326, properties: %{}}
# Convert struct to JSON string (requires external JSON parser)
Geo.JSON.encode!(point) |> JSON.encode!
"{\"coordinates\":[100.0,0.0],\"type\":\"Point\"}"Use Geo.WKT to convert between Well-Known Text (WKT) strings and Geo structs. It supports both standard WKT and Extended WKT (EWKT) which includes Spatial Reference System Identifiers (SRID).
Geo.WKT.decode(wkt_string): Returns {:ok, geometry} or {:error, reason}.Geo.WKT.decode!(wkt_string): Returns the geometry struct or raises an error.Geo.WKT.encode!(geometry): Returns the WKT string representation.{:ok, point} = Geo.WKT.decode("POINT(30 -90)")
%Geo.Point{ coordinates: {30, -90}, srid: nil}
Geo.WKT.encode!(point)
"POINT(30 -90)"
point = Geo.WKT.decode!("SRID=4326;POINT(30 -90)")
%Geo.Point{coordinates: {30, -90}, srid: 4326}The following examples demonstrate common usage patterns for Geo.WKB:
# Decode a base-16 string to a Point
{:ok, point} = Geo.WKB.decode("0101000000000000000000F03F000000000000F03F")
# => Geo.Point[coordinates: {1, 1}, srid: nil]
# Decode a base-16 string with an SRID
point = Geo.WKB.decode!("01010002E61000009EFB613A637B4240CF2C0950D3735EC0")
# => Geo.Point[coordinates: {36.9639657, -121.8097725}, srid: 4326]{:ok, point} = Geo.WKB.decode("0101000000000000000000F03F000000000000F03F")
Geo.Point[coordinates: {1, 1}, srid: nil]
iex> Geo.WKT.encode!(point)
"POINT(1 1)"
iex> point = Geo.WKB.decode!("01010002E61000009EFB613A637B4240CF2C0950D3735EC0")
Geo.Point[coordinates: {36.9639657, -121.8097725}, srid: 4326]The Geo.JSON.Decoder module provides functions to convert GeoJSON maps (typically parsed from JSON) into Geo geometry structs.
It supports several GeoJSON object types:
Point, LineString, Polygon, etc.Key Behaviors:
4326 (WGS 84) per the GeoJSON spec.null geometries are stripped from a FeatureCollection. A standalone Feature with null geometry returns nil.{x, y}).# To decode safely with error handling:
case Geo.JSON.Decoder.decode(geo_json_map) do
{:ok, %Geo.Point{}} -> # handle success
{:error, %Geo.JSON.Decoder.DecodeError{}} -> # handle error
end
# To decode and raise on error:
geometry = Geo.JSON.Decoder.decode!(geo_json_map)Use Geo.JSON.Encoder.encode/2 to safely convert a Geo.geometry() struct into a map representing its GeoJSON equivalent. This function returns {:ok, map} on success or {:error, %Geo.JSON.Encoder.EncodeError{}} if encoding fails.
Note that the encoder disregards SRID information for the geometry itself (as GeoJSON is expected to be in WGS 84), but it will include a crs field in the resulting map if an SRID is present.
# Returns {:ok, map} or {:error, EncodeError}
Geo.JSON.Encoder.encode(geom)If you need the raw byte sequence instead of a base-16 string, use Geo.WKB.encode_to_iodata/2. This returns the WKB as iodata (a sequence of bytes).
Geo.WKB.encode_to_iodata(geom, :xdr)