Envelope (envelope v1.4.1)

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 }

Link to this section Summary

Functions

Calculates the simple area of an Envelope.

Estimates the area of an Envelope in square meters when the Envelope's coordinates are in degress of longitude and latitude.

Returns the center point of an envelope.

Returns whether one envelope fully contains another envelope or point.

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.

Simple distance from the bottom bounadary to the top boundary of the Envelope.

When an Envelope's coordinates are in degress of longitude and latitude, calculates the great circle distance between the center of the north and south extent in meters.

Returns whether two envelopes touch or intersect.

Returns a Geo.Polygon, Geo.LineString, or Geo.Point that is equal to the area covered by the given Envelope.

Simple distance from the left bounadary to the right boundary of the Envelope.

When an Envelope's coordinates are in degress of longitude and latitude, calculates the great circle distance between the center of the east and west extent in meters.

The inverse of the relationship tested by Envelope#contains?

Link to this section Types

@type point() :: {number(), number()}
@type points() ::
  point()
  | list()
  | %{coordinates: list()}
  | %Geo.Point{coordinates: term(), properties: term(), srid: term()}
  | %Geo.MultiPoint{coordinates: term(), properties: term(), srid: term()}
  | %Geo.LineString{coordinates: term(), properties: term(), srid: term()}
  | %Geo.MultiLineString{coordinates: term(), properties: term(), srid: term()}
  | %Geo.Polygon{coordinates: term(), properties: term(), srid: term()}
  | %Geo.MultiPolygon{coordinates: term(), properties: term(), srid: term()}
@type t() :: %Envelope{
  max_x: number() | nil,
  max_y: number() | nil,
  min_x: number() | nil,
  min_y: number() | nil
}

Link to this section Functions

@spec area(t()) :: number()

Calculates the simple area of an Envelope.

examples

Examples

iex> Envelope.area(Envelope.from_geo(%Geo.Polygon{coordinates: [[{2, -2}, {20, -2}, {11, 11}, {2, -2}]]}))
234
@spec area_gc(t()) :: number()

Estimates the area of an Envelope in square meters when the Envelope's coordinates are in degress of longitude and latitude.

examples

Examples

iex> Envelope.area_gc(Envelope.from_geo(%Geo.Polygon{coordinates: [[{2, -2}, {20, -2}, {11, 11}, {2, -2}]]})) |> round
2865575088701
@spec center(t()) :: {number(), number()}

Returns the center point of an envelope.

examples

Examples

iex> %Envelope{ min_x: 0, min_y: -1, max_x: 2, max_y: 5 } |> Envelope.center() {1.0, 2.0}

iex> Envelope.empty() |> Envelope.center() nil

Link to this function

contains?(env, env2)

@spec contains?(t() | points(), t() | points()) :: boolean()

Returns whether one envelope fully contains another envelope or point.

examples

Examples

iex> Envelope.contains?(
...> %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.contains?(
...> %Envelope{ min_x: -1, min_y: 5, max_x: 23, max_y: 14 },
...> %Envelope{ min_x: -2, min_y: 5, max_x: 7, max_y: 4 })
false

iex> Envelope.contains?(
...> %Geo.Polygon{ coordinates: [{-1, 3}, {-3, -1}, { 5, -3}, {4, 12}, {-2, 11}, {-1, 3}] },
...> {0, 11})
true
@spec empty() :: t()

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

Examples

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

iex> Envelope.empty |> Envelope.empty?
true
Link to this function

empty?(envelope)

@spec empty?(t()) :: boolean()

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

examples

Examples

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

iex> %Envelope{ min_x: 0, min_y: -1, max_x: 2, max_y: 3 } |> Envelope.empty?
false
Link to this function

expand(env1, env2)

@spec expand(t(), point() | t() | points()) :: t()

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

examples

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.empty
...> |> Envelope.expand(%Envelope{ min_x: 0, min_y: -2, max_x: 12, max_y: 11 })
...> |> Envelope.expand(%Geo.Polygon{coordinates: [[{2, -2}, {20, -2}, {11, 11}, {2, -2}]]})
...> |> Envelope.expand(%{type: "Point", coordinates: {-1, 3}})
%Envelope{ min_x: -1, min_y: -2, max_x: 20, max_y: 11 }

iex> Envelope.expand(Envelope.empty, Envelope.empty) |> Envelope.empty?
true
Link to this function

expand_by(env, radius)

@spec expand_by(t(), number()) :: t()

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

examples

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
Link to this function

from_geo(coordinates)

@spec from_geo(points()) :: t()

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

examples

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 }
@spec height(t()) :: number()

Simple distance from the bottom bounadary to the top boundary of the Envelope.

examples

Examples

iex> Envelope.height(Envelope.from_geo(%Geo.Polygon{coordinates: [[{2, -2}, {20, -2}, {11, 11}, {2, -2}]]}))
13
@spec height_gc(t()) :: number()

When an Envelope's coordinates are in degress of longitude and latitude, calculates the great circle distance between the center of the north and south extent in meters.

examples

Examples

iex> Envelope.height_gc(Envelope.from_geo(%Geo.Polygon{coordinates: [[{2, -2}, {20, -2}, {11, 11}, {2, -2}]]})) |> round
1445536
Link to this function

intersects?(env1, env2)

@spec intersects?(t() | points(), t() | points()) :: boolean()

Returns whether two envelopes touch or intersect.

examples

Examples

iex> Envelope.intersects?(
...> %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.intersects?(
...> %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
@spec to_geo(t()) :: Geo.Polygon.t() | Geo.Point.t() | Geo.LineString.t()

Returns a Geo.Polygon, Geo.LineString, or Geo.Point that is equal to the area covered by the given Envelope.

Note that they exact type of the Geometry returned will depend on the nature of the Envelope:

  • Geo.Point will be returned when an envelope has zero area and all extents are equal.
  • Geo.LineString will be returned when an envelope has zero area and it extends along only one axes.
  • Geo.Polygon will be returned when an envelope has non-zeron area

examples

Examples

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

iex> Envelope.to_geo %Envelope{ min_x: 1, min_y: 3, max_x: 1, max_y: 5 }
%Geo.LineString{coordinates: [{1, 3}, {1, 5}]}

iex> Envelope.to_geo %Envelope{ min_x: 1, min_y: 3, max_x: 4, max_y: 3 }
%Geo.LineString{coordinates: [{1, 3}, {4, 3}]}

iex> Envelope.to_geo %Envelope{ min_x: 1, min_y: 3, max_x: 1, max_y: 3 }
%Geo.Point{coordinates: {1, 3}}
@spec width(t()) :: number()

Simple distance from the left bounadary to the right boundary of the Envelope.

examples

Examples

iex> Envelope.width(Envelope.from_geo(%Geo.Polygon{coordinates: [[{2, -2}, {20, -2}, {11, 11}, {2, -2}]]}))
18
@spec width_gc(t()) :: number()

When an Envelope's coordinates are in degress of longitude and latitude, calculates the great circle distance between the center of the east and west extent in meters.

examples

Examples

iex> Envelope.width_gc(Envelope.from_geo(%Geo.Polygon{coordinates: [[{2, -2}, {20, -2}, {11, 11}, {2, -2}]]})) |> round
1982362
@spec within?(t() | points(), t() | points()) :: boolean()

The inverse of the relationship tested by Envelope#contains?

examples

Examples

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

iex> Envelope.within?(
...> %Geo.Polygon{ coordinates: [{-1, 3}, {-3, -1}, { 5, -3}, {4, 12}, {-2, 11}, {-1, 3}] },
...> {0, 11})
false