envelope v0.2.0 Envelope

A library for calculating envelopes of geometries and tools to compare them. This is most useful as an approximation of spacial relationships between more complicated geometries.

iex> Envelope.from_geo( %Geo.Polygon{coordinates: [[{2, -2}, {20, -2}, {11, 11}, {2, -2}]]} )
%Envelope{ min_x: 2, min_y: -2, max_x: 20, max_y: 11 }

iex> Envelope.from_geo( %Geo.LineString{coordinates: [{1, 3}, {2, -1}, {0, -1}, {1, 3}]} )
%Envelope{ min_x: 0, min_y: -1, max_x: 2, max_y: 3 }

You can also expand an existing Envelope with a geometry or another Envelope

iex> a = Envelope.from_geo( %Geo.Polygon{coordinates: [[{2, -2}, {20, -2}, {11, 11}, {2, -2}]]} )
...> b = %Geo.LineString{coordinates: [{1, 3}, {2, -1}, {0, -1}, {1, 3}]}
...> Envelope.expand(a, b)
%Envelope{ min_x: 0, min_y: -2, max_x: 20, max_y: 11 }

Summary

Functions

Returns an Envelope that represents no extent at all. This is primarily a convenience function for starting an expanding Envelope. Internally, “empty” Envelopes are represented with nil values for all extents

Returns true if the given envelope is empty (has non-existent extent), otherwise false

Returns a new Envelope that is expanded to include an additional geometry

Returns a new Envelope that is expanded in positive and negative directions in each axis by radius

Returns an Envelope that represents the extent of the geometry or coordinates

Returns whether two envelopes touch or intersect

Types

points ::
  {number, number} |
  list |
  %{coordinates: list} |
  %Geo.Point{coordinates: term, srid: term} |
  %Geo.MultiPoint{coordinates: term, srid: term} |
  %Geo.LineString{coordinates: term, srid: term} |
  %Geo.MultiLineString{coordinates: term, srid: term} |
  %Geo.Polygon{coordinates: term, srid: term} |
  %Geo.MultiPolygon{coordinates: term, srid: term}

Functions

empty()

Specs

empty :: %Envelope{max_x: term, max_y: term, min_x: term, min_y: term}

Returns an Envelope that represents no extent at all. This is primarily a convenience function for starting an expanding Envelope. Internally, “empty” Envelopes are represented with nil values for all extents.

Note that there is a important distinction between an empty Envelope and an Envelope around a single Point (where the min and max for each axis are real numbers but may represent zero area).

Examples

iex> Envelope.empty
%Envelope{max_x: nil, max_y: nil, min_x: nil, min_y: nil}

iex> Envelope.empty |> Envelope.empty?
true
empty?(envelope)

Specs

empty?(%Envelope{max_x: term, max_y: term, min_x: term, min_y: term}) :: boolean

Returns true if the given envelope is empty (has non-existent extent), otherwise false

Examples

iex> Envelope.empty |> Envelope.empty?
true

iex> %Envelope{ min_x: 0, min_y: -1, max_x: 2, max_y: 3 } |> Envelope.empty?
false
expand(env1, env2)

Specs

expand(%Envelope{max_x: term, max_y: term, min_x: term, min_y: term}, {number, number} | %Envelope{max_x: term, max_y: term, min_x: term, min_y: term} | points) :: %Envelope{max_x: term, max_y: term, min_x: term, min_y: term}

Returns a new Envelope that is expanded to include an additional geometry.

Examples

iex> a = Envelope.from_geo(%Geo.Polygon{coordinates: [[{2, -2}, {20, -2}, {11, 11}, {2, -2}]]})
...> b = %Geo.LineString{coordinates: [{1, 3}, {2, -1}, {0, -1}, {1, 3}]}
...> Envelope.expand(a, b)
%Envelope{ min_x: 0, min_y: -2, max_x: 20, max_y: 11 }

iex> a = %Envelope{ min_x: 0, min_y: -2, max_x: 20, max_y: 11 }
...> b = %Envelope{ min_x: 2, min_y: -3, max_x: 12, max_y: -2 }
...> Envelope.expand(a, b)
%Envelope{ min_x: 0, min_y: -3, max_x: 20, max_y: 11 }

iex> Envelope.expand(Envelope.empty, %Envelope{ min_x: 0, min_y: -2, max_x: 20, max_y: 11 })
%Envelope{ min_x: 0, min_y: -2, max_x: 20, max_y: 11 }

iex> Envelope.expand(Envelope.empty, Envelope.empty) |> Envelope.empty?
true
expand_by(env, radius)

Specs

expand_by(%Envelope{max_x: term, max_y: term, min_x: term, min_y: term}, number) :: %Envelope{max_x: term, max_y: term, min_x: term, min_y: term}

Returns a new Envelope that is expanded in positive and negative directions in each axis by radius.

Examples

iex> Envelope.expand_by(Envelope.from_geo(%Geo.Polygon{coordinates: [[{2, -2}, {20, -2}, {11, 11}, {2, -2}]]}), 3)
%Envelope{ min_x: -1, min_y: -5, max_x: 23, max_y: 14 }

iex> Envelope.expand_by(Envelope.empty, 4) |> Envelope.empty?
true
from_geo(coordinates)

Specs

from_geo(points) :: %Envelope{max_x: term, max_y: term, min_x: term, min_y: term}

Returns an Envelope that represents the extent of the geometry or coordinates.

Examples

iex> Envelope.from_geo %{coordinates: [{11, 10}, {4, 2.5}, {16, 2.5}, {11, 10}]}
%Envelope{ max_x: 16, max_y: 10, min_x: 4, min_y: 2.5 }

iex> Envelope.from_geo [{11, 10}, {4, 2.5}, {16, 2.5}, {11, 10}]
%Envelope{ max_x: 16, max_y: 10, min_x: 4, min_y: 2.5 }

iex> Envelope.from_geo %Geo.Polygon{coordinates: [[{1, 3}, {2, -1}, {0, -1}, {1, 3}]]}
%Envelope{ min_x: 0, min_y: -1, max_x: 2, max_y: 3 }

iex> Envelope.from_geo {1, 3}
%Envelope{ min_x: 1, min_y: 3, max_x: 1, max_y: 3 }
intersect?(env1, env2)

Specs

intersect?(%Envelope{max_x: term, max_y: term, min_x: term, min_y: term}, %Envelope{max_x: term, max_y: term, min_x: term, min_y: term}) :: boolean

Returns whether two envelopes touch or intersect.

Examples

iex> Envelope.intersect?(
...> %Envelope{ min_x: -1, min_y: -5, max_x: 23, max_y: 14 },
...> %Envelope{ min_x: 0, min_y: 3, max_x: 7, max_y: 4 })
true

iex> Envelope.intersect?(
...> %Envelope{ min_x: -1, min_y: 5, max_x: 23, max_y: 14 },
...> %Envelope{ min_x: 0, min_y: -3, max_x: 7, max_y: 4 })
false