SpatialMap (spatial_map v0.1.0)

A SpatialMap is meant to hold static features in a spatial plane and allow for searching for features by geospatial lookup.

Link to this section Summary

Functions

Returns the number of features in the SpacialMap

Deltes a feature from the SpatialMap.

Returns the feature from the SpatialMap for the given refence or nil if one is not found.

Returns all features in the SpatialMap

Moves a feature from one geometry to another.

Creates a new SpatialMap with the given options.

Adds a new feature, which consists of a geometry and a set of metadata, and returns a reference for the feature the updated map.

Adds a feature to a map and only returns the SpatialMap. This is useful for chaining mulitple features

Queries the SpatialMap for all featurs that intersect the given geometry.

Same as query/2, but returns the properties from the resulting features.

Same as query_properties/2, but returns the value of the given key for the resulting features.

Returns the type of storage for the given SpatialMap.

Link to this section Types

Specs

geometry() ::
  {number(), number()}
  | %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()}

Specs

t() :: %SpatialMap{
  feature_table: reference() | nil,
  features: map() | nil,
  grid: [{number(), number(), number()}],
  local: map() | nil,
  storage_type: :local | :ets,
  table: reference() | nil
}

Link to this section Functions

Link to this function

count_features(map)

Specs

count_features(t()) :: non_neg_integer()

Returns the number of features in the SpacialMap

Examples

iex> SpatialMap.new()
...> |> SpatialMap.count_features()
0

iex> SpatialMap.new()
...> |> SpatialMap.put_feature!(%Geo.Point{coordinates: {1, 3}}, %{name: :a})
...> |> SpatialMap.put_feature!(%Geo.Point{coordinates: {2, 1}}, %{name: :b})
...> |> SpatialMap.put_feature!(%Geo.Point{coordinates: {4, 3}}, %{name: :c})
...> |> SpatialMap.count_features()
3

iex> SpatialMap.new(storage_type: :ets)
...> |> SpatialMap.count_features()
0

iex> SpatialMap.new(storage_type: :ets)
...> |> SpatialMap.put_feature!(%Geo.Point{coordinates: {1, 3}}, %{name: :a})
...> |> SpatialMap.put_feature!(%Geo.Point{coordinates: {2, 1}}, %{name: :b})
...> |> SpatialMap.put_feature!(%Geo.Point{coordinates: {4, 3}}, %{name: :c})
...> |> SpatialMap.count_features()
3
Link to this function

delete_feature(map, ref)

Specs

delete_feature(t(), reference()) :: t()

Deltes a feature from the SpatialMap.

Imprtant Note: this function also operates on all the cells occupied by the features, so it is as expensive as adding a new feature.

Example

iex> {map, ref} = 
...>   SpatialMap.new()
...>   |> SpatialMap.put_feature(%Geo.Point{coordinates: {-90, 30}}, %{foo: :bar})
...> map
...> |> SpatialMap.delete_feature(ref)
...> |> SpatialMap.query({-90, 30})
[]
Link to this function

get_feature(map, ref)

Specs

get_feature(t(), reference()) :: SpatialMap.Feature.t() | nil

Returns the feature from the SpatialMap for the given refence or nil if one is not found.

Example

iex> {map, ref} = 
...>   SpatialMap.new()
...>   |> SpatialMap.put_feature(%Geo.Point{coordinates: {-90, 30}}, %{foo: :bar})
...> SpatialMap.get_feature(map, ref) |> Map.get(:properties)
%{foo: :bar}

iex> SpatialMap.new()
...> |> SpatialMap.get_feature(make_ref())
nil

iex> {map, ref} = 
...>   SpatialMap.new(storage_type: :ets)
...>   |> SpatialMap.put_feature(%Geo.Point{coordinates: {-90, 30}}, %{foo: :bar})
...> SpatialMap.get_feature(map, ref) |> Map.get(:properties)
%{foo: :bar}

iex> SpatialMap.new(storage_type: :ets)
...> |> SpatialMap.get_feature(make_ref())
nil
Link to this function

list_features(map)

Specs

list_features(t()) :: [SpatialMap.Feature.t()]

Returns all features in the SpatialMap

Link to this function

move_feature(map, ref, geometry)

Specs

move_feature(t(), reference(), geometry()) :: t()

Moves a feature from one geometry to another.

Important Note: This is an even more expensive operation than put_feature in that it has to iterate over the geometry of the orignal position and the new geometry.

Example

iex> {map, ref} = 
...>   SpatialMap.new()
...>   |> SpatialMap.put_feature(%Geo.Point{coordinates: {-90, 30}}, %{foo: :bar})
...> map
...> |> SpatialMap.move_feature(ref, %Geo.Point{coordinates: {-110, 40}})
...> |> SpatialMap.query({-90, 30})
[]

iex> {map, ref} = 
...>   SpatialMap.new(storaget_type: :ets)
...>   |> SpatialMap.put_feature(%Geo.Point{coordinates: {-90, 30}}, %{foo: :bar})
...> map
...> |> SpatialMap.move_feature(ref, %Geo.Point{coordinates: {-110, 40}})
...> |> SpatialMap.query({-90, 30})
[]
Link to this function

new(opts \\ [])

Specs

new(keyword()) :: t()

Creates a new SpatialMap with the given options.

  • storage_type - can be either :local (default) or :ets. A :local storage type stores the features in a local map inside the SpatialHash struct. An :ets storage type creates wan ETS table for feature storage. Default: :local

  • table_name - an atom specifying the name of the underlying ETS table. This is only used when storage_type is set to :ets and is required if more than one SpatialMap of type :ets is created on the current node.

  • access - when creating a SpatialMap of type :ets, this specifies the access protection for the underlying table. Default: :public

  • grid - specifies the grid to be used with the underlying SpatialHash of the map. Please see SpacialHash documentation for more information. Default: SpatialHash.world_grid()

Examples

iex> SpatialMap.new()
...> |> SpatialMap.storage_type()
:local
Link to this function

put_feature(map, geometry, metadata \\ %{})

Specs

put_feature(t(), geometry(), map()) :: {t(), reference()}

Adds a new feature, which consists of a geometry and a set of metadata, and returns a reference for the feature the updated map.

Important Note: For larger features and small grid cell sizes, this function can take an extremely long time. See README.md for more information about this tradoff.

Example

iex> {map, ref} = 
...>   SpatialMap.new()
...>   |> SpatialMap.put_feature(%Geo.Point{coordinates: {-90, 30}}, %{foo: :bar})
...> SpatialMap.get_feature(map, ref) |> Map.get(:properties)
%{foo: :bar}
Link to this function

put_feature!(map, geometry, metadata \\ %{})

Specs

put_feature!(t(), geometry(), map()) :: t()

Adds a feature to a map and only returns the SpatialMap. This is useful for chaining mulitple features

Example

iex> SpatialMap.new()
...> |> SpatialMap.put_feature!(%Geo.Point{coordinates: {-90, 30}}, %{foo: :bar})
...> |> SpatialMap.query({-90, 30}) 
...> |> List.first()
...> |> Map.get(:properties)
%{foo: :bar}
Link to this function

query(map, geometry)

Specs

query(t(), geometry()) :: [SpatialMap.Feature.t()]

Queries the SpatialMap for all featurs that intersect the given geometry.

Link to this function

query_properties(map, geometry)

Specs

query_properties(t(), geometry()) :: [map()]

Same as query/2, but returns the properties from the resulting features.

Examples

iex> SpatialMap.new()
...> |> SpatialMap.put_feature!(%Geo.Point{coordinates: {1, 3}}, %{name: :a})
...> |> SpatialMap.put_feature!(%Geo.Point{coordinates: {2, 1}}, %{name: :b})
...> |> SpatialMap.put_feature!(%Geo.Point{coordinates: {4, 3}}, %{name: :c})
...> |> SpatialMap.query_properties(%Geo.Polygon{coordinates: [[{0, 0}, {0, 5}, {5, 0}, {0, 0}]]})
[%{name: :a}, %{name: :b}]
Link to this function

query_properties(map, geometry, key)

Specs

query_properties(t(), geometry(), any()) :: [any()]

Same as query_properties/2, but returns the value of the given key for the resulting features.

Examplesref

iex> SpatialMap.new()
...> |> SpatialMap.put_feature!(%Geo.Point{coordinates: {1, 3}}, %{name: :a})
...> |> SpatialMap.put_feature!(%Geo.Point{coordinates: {2, 1}}, %{name: :b})
...> |> SpatialMap.put_feature!(%Geo.Point{coordinates: {4, 3}}, %{name: :c})
...> |> SpatialMap.query_properties(%Geo.Polygon{coordinates: [[{0, 0}, {0, 5}, {5, 0}, {0, 0}]]}, :name)
[:a, :b]
Link to this function

storage_type(spatial_map)

Specs

storage_type(t()) :: :local | :ets

Returns the type of storage for the given SpatialMap.

Exmaples

iex> SpatialMap.new(storage_type: :ets)
...> |> SpatialMap.storage_type()
:ets