Geometry Library for Elixir

Build StatusHex.pm

A Geometry library for Elixir that calculates spatial relationships between two geometries. Geometries can be of any of the following types:

Installation

defp deps do
  [{:topo, "~> 0.1.0"}]
end

Usage

Full Documentation

The Topo module provides functions for determining the relationship between two geometries. Each function returns a boolean and accepts any combination of Point, LineString, Polygon, MultiPoint, MultiLineString, or MultiPolygon.

Each of these functions can be passed any two Geometries in either a Map with a :type and :coordinates keys or as a struct generated via the Geo library (https://github.com/bryanjos/geo). Coordinates are represented as atoms {x, y} and multiple coordinates as Lists.

a = %{type: "Polygon", coordinates: [[{2, 2}, {20, 2}, {11, 11}, {2, 2}]]}
b = %Geo.Polygon{coordinates: [[{2, 2}, {20, 2}, {11, 11}, {2, 2}]]}

Topo.equals? a, b # => true

Instead of a Point geometry, just a single coordinate can be used.

a = %{type: "Polygon", coordinates: [[{2, 2}, {20, 2}, {11, 11}, {2, 2}]]}

Topo.intersects? a, {4, 6} # => true

The Topo library's functions will automatically attempt to "clean" geometries passed to them:

A note on contains?

There are a few non-obvious special cases that are worth mentioning:

  a = %Geo.Polygon{coordinates: [[{2, 2}, {20, 2}, {11, 11}, {2, 2}]]}
  b = %Geo.LineString{coordinates: [{2, 2}, {20, 2}, {11, 11}, {2, 2}]}

  Topo.contains? a, b # => false
  Topo.intersects? a, b  # => true
  a = %Geo.LineString{coordinates: [{1, 3}, {2, -1}, {0, -1}]}
  b = %Geo.LineString{coordinates: [{1, 3}, {2, -1}, {0, -1}, {1, 3}]}

  Topo.contains? a, {1, 3} # => false
  Topo.intersects? a, {1, 3} # => true
  Topo.contains? b, {1, 3} # => true

Tests

> mix test