Geo.Turf

CIhex.pm

Spatial analysis for Elixir, ported from TurfJS. Operates on Geo structs using WGS84 coordinates.

Usage

All functions accept and return standard Geo structs.

Geo.Turf.Measure

Measurements and geometry queries.

point = %Geo.Point{coordinates: {-75.343, 39.984}}
other = %Geo.Point{coordinates: {-75.534, 39.123}}

Geo.Turf.Measure.distance(point, other, :kilometers)       # => 97.13
Geo.Turf.Measure.bearing(point, other)                     # => -170.23
Geo.Turf.Measure.close_to(point, other, 100, :kilometers)  # => true
Geo.Turf.Measure.destination(point, 50, 90, units: :kilometers)  # => %Geo.Point{...}

route = %Geo.LineString{coordinates: [{-23.621, 64.769}, {-23.629, 64.766}, {-23.638, 64.766}]}
Geo.Turf.Measure.length_of(route, :kilometers)   # => 0.93
Geo.Turf.Measure.along(route, 0.5, :kilometers)  # => %Geo.Point{...}

polygon = %Geo.Polygon{coordinates: [[{125, -15}, {113, -22}, {154, -27}, {144, -15}, {125, -15}]]}
Geo.Turf.Measure.area(polygon)      # => 3332484969239.27 (m²)
Geo.Turf.Measure.center(polygon)    # => %Geo.Point{...}  (bbox centre)
Geo.Turf.Measure.centroid(polygon)  # => %Geo.Point{...}  (mean of vertices)

Geo.Turf.Classification

Spatial predicates and search.

poly = %Geo.Polygon{coordinates: [[{0, 0}, {0, 10}, {10, 10}, {10, 0}, {0, 0}]]}

Geo.Turf.Classification.point_in_polygon?(%Geo.Point{coordinates: {5, 5}}, poly)   # => true
Geo.Turf.Classification.point_in_polygon?(%Geo.Point{coordinates: {15, 5}}, poly)  # => false

points = [%Geo.Point{coordinates: {5, 5}}, %Geo.Point{coordinates: {15, 5}}]
Geo.Turf.Classification.points_within_polygon(points, poly)  # => [%Geo.Point{coordinates: {5, 5}}]

target = %Geo.Point{coordinates: {0, 0}}
Geo.Turf.Classification.nearest_point(target, points)  # => %Geo.Point{coordinates: {5, 5}}

Geo.Turf.Transformation

Geometry construction and transformation.

point = %Geo.Point{coordinates: {-75.343, 39.984}}

Geo.Turf.Transformation.circle(point, 10, units: :kilometers)  # => %Geo.Polygon{...}

Geo.Turf.Helpers

Bounding box utilities.

polygon = %Geo.Polygon{coordinates: [[{0, 0}, {0, 10}, {10, 10}, {10, 0}, {0, 0}]]}

Geo.Turf.Helpers.bbox(polygon)             # => {0, 0, 10, 10}
Geo.Turf.Helpers.bbox_polygon({0, 0, 10, 10})  # => %Geo.Polygon{...}

# Compose them:
polygon |> Geo.Turf.Helpers.bbox() |> Geo.Turf.Helpers.bbox_polygon()  # => %Geo.Polygon{...}

See the full API docs for all available functions.

Works with geo_postgis

If you query a PostGIS database via geo_postgis, the structs it returns work directly with GeoTurf — no conversion needed:

# Ecto query returns %Geo.Point{} and %Geo.Polygon{} fields automatically.
# Pass them straight into GeoTurf:
locations
|> Enum.filter(&Geo.Turf.Measure.close_to(&1.geom, origin, 50, :kilometers))
|> Enum.sort_by(&Geo.Turf.Measure.distance(&1.geom, origin))

Suggestions

Missing a function from TurfJS? Open an issue — a test case alongside it is always welcome.