geo_partition v0.1.1 GeoPartition.Geometry View Source
Extensions of Topo and Geo to perform calculations on map geometries
Link to this section Summary
Functions
Find the area of a polygon. To find geographic area based on lat/long coords, use geo: :globe,
default is geo: :flat
Removes occluding holes from a given polygon, preserving properly contained holes
Check if three points are collinear
Converts a cycle (graph) into a polygon
Converts a graph into a polygon
Find the intersection point of two LineStrings. Returns a tuple indicating the type of intersection:
:disjoint, the LineStrings have no points in common:degen, the LineStrings share points but are collinear, the endpoint of one incident with non-endpoint of other, or they share an endpoint:intersects, the LineStrings have a non-trivial point of intersection
Converts a polygon (Geo.Polygon) to a graph. If the polygon has holes that overlap the
outer ring, they will be circumvented
Link to this section Types
Link to this section Functions
Find the area of a polygon. To find geographic area based on lat/long coords, use geo: :globe,
default is geo: :flat
Examples
iex> shape = %Geo.Polygon{
...> coordinates: [
...> [
...> {0.0, 0.0},
...> {4.0, 0.0},
...> {4.0, 3.0},
...> {0.0, 3.0},
...> {0.0, 0.0},
...> ],
...> [
...> {1.0, 1.0},
...> {3.0, 1.0},
...> {3.0, 4.0},
...> {1.0, 4.0},
...> {1.0, 1.0},
...> ]
...> ]
...> }
iex> GeoPartition.Geometry.area(shape, [geo: :flat])
8.0
Removes occluding holes from a given polygon, preserving properly contained holes
Examples
iex> shape = %Geo.Polygon{
...> coordinates: [
...> [
...> {0.0, 0.0},
...> {4.0, 0.0},
...> {4.0, 3.0},
...> {0.0, 3.0},
...> {0.0, 0.0},
...> ],
...> [
...> {1.0, 1.0},
...> {3.0, 1.0},
...> {3.0, 4.0},
...> {1.0, 4.0},
...> {1.0, 1.0},
...> ],
...> [
...> {1.0, 0.3},
...> {3.0, 0.3},
...> {3.0, 0.7},
...> {1.0, 0.3}
...> ]
...> ]
...> }
iex> GeoPartition.Geometry.clean_holes(shape)
%Geo.Polygon{
coordinates: [
[
{0.0, 0.0},
{4.0, 0.0},
{4.0, 3.0},
{3.0, 3.0},
{3.0, 1.0},
{1.0, 1.0},
{1.0, 3.0},
{0.0, 3.0},
{0.0, 0.0},
],
[
{1.0, 0.3},
{3.0, 0.3},
{3.0, 0.7},
{1.0, 0.3}
]
],
properties: %{},
srid: nil
}
Check if three points are collinear
Examples
iex> GeoPartition.Geometry.collinear?({1, 1}, {2, 2}, {3, 3})
true
iex> GeoPartition.Geometry.collinear?({1, 1}, {2, 2}, {3, 4})
false
Converts a cycle (graph) into a polygon.
Examples
iex> cycle = {
...> [
...> %Geo.Point{ coordinates: {1.0, 1.0}, properties: %{covered: false, ring: :outer}, srid: nil },
...> %Geo.Point{ coordinates: {3.0, 2.0}, properties: %{covered: false, ring: :outer}, srid: nil },
...> %Geo.Point{ coordinates: {1.0, 3.0}, properties: %{covered: false, ring: :outer}, srid: nil }
...> ], [
...> MapSet.new([
...> %Geo.Point{coordinates: {1.0, 1.0}, properties: %{covered: false, ring: :outer}, srid: nil},
...> %Geo.Point{coordinates: {3.0, 2.0}, properties: %{covered: false, ring: :outer}, srid: nil}
...> ]),
...> MapSet.new([
...> %Geo.Point{coordinates: {1.0, 3.0}, properties: %{covered: false, ring: :outer}, srid: nil},
...> %Geo.Point{coordinates: {3.0, 2.0}, properties: %{covered: false, ring: :outer}, srid: nil}
...> ]),
...> MapSet.new([
...> %Geo.Point{coordinates: {1.0, 3.0}, properties: %{covered: false, ring: :outer}, srid: nil},
...> %Geo.Point{coordinates: {1.0, 1.0}, properties: %{covered: false, ring: :outer}, srid: nil}
...> ])
...> ]}
iex> GeoPartition.Geometry.cycle_to_ring(cycle)
[
{1.0, 3.0},
{3.0, 2.0},
{1.0, 1.0},
{1.0, 3.0}
]
Converts a graph into a polygon
Examples
iex> graph = {[
...> %Geo.Point{ coordinates: {1.0, 1.0}, properties: %{covered: false, ring: :outer}, srid: nil },
...> %Geo.Point{ coordinates: {1.0, 3.0}, properties: %{covered: false, ring: :outer}, srid: nil },
...> %Geo.Point{ coordinates: {2.0, 2.0}, properties: %{covered: true, ring: :inner}, srid: nil },
...> %Geo.Point{ coordinates: {2.5, 1.75}, srid: nil, properties: %{covered: false, ring: :intersection} },
...> %Geo.Point{ coordinates: {2.5, 2.25}, srid: nil, properties: %{covered: false, ring: :intersection} }
...> ], [
...> MapSet.new([
...> %Geo.Point{coordinates: {1.0, 3.0}, properties: %{covered: false, ring: :outer}, srid: nil},
...> %Geo.Point{coordinates: {2.5, 2.25}, properties: %{covered: false, ring: :intersection}, srid: nil}
...> ]),
...> MapSet.new([
...> %Geo.Point{coordinates: {2.0, 2.0}, properties: %{covered: true, ring: :inner}, srid: nil},
...> %Geo.Point{coordinates: {2.5, 2.25}, properties: %{covered: false, ring: :intersection}, srid: nil}
...> ]),
...> MapSet.new([
...> %Geo.Point{coordinates: {1.0, 1.0}, properties: %{covered: false, ring: :outer}, srid: nil},
...> %Geo.Point{coordinates: {2.5, 1.75}, properties: %{covered: false, ring: :intersection}, srid: nil}
...> ]),
...> MapSet.new([
...> %Geo.Point{coordinates: {2.0, 2.0}, properties: %{covered: true, ring: :inner}, srid: nil},
...> %Geo.Point{coordinates: {2.5, 1.75}, properties: %{covered: false, ring: :intersection}, srid: nil}
...> ]),
...> MapSet.new([
...> %Geo.Point{coordinates: {1.0, 1.0}, properties: %{covered: false, ring: :outer}, srid: nil},
...> %Geo.Point{coordinates: {1.0, 3.0}, properties: %{covered: false, ring: :outer}, srid: nil}
...> ])
...>]}
iex> GeoPartition.Geometry.graph_to_polygon(graph)
%Geo.Polygon{
coordinates: [
[
{1.0, 1.0},
{2.5, 1.75},
{2.0, 2.0},
{2.5, 2.25},
{1.0, 3.0},
{1.0, 1.0}
]
]
}
Find the intersection point of two LineStrings. Returns a tuple indicating the type of intersection:
:disjoint, the LineStrings have no points in common:degen, the LineStrings share points but are collinear, the endpoint of one incident with non-endpoint of other, or they share an endpoint:intersects, the LineStrings have a non-trivial point of intersection
Examples
iex> reference = %Geo.LineString{coordinates: [{1.0, 1.0}, {2.0, 2.0}]}
iex> disjoint = %Geo.LineString{coordinates: [{2.0, 1.0}, {2.0, 2.0}]}
iex> GeoPartition.Geometry.intersection(reference, disjoint)
{:endpoint, "endpoint"}
iex> reference = %Geo.LineString{coordinates: [{1.0, 1.0}, {2.0, 2.0}]}
iex> disjoint = %Geo.LineString{coordinates: [{2.0, 1.0}, {3.0, 2.0}]}
iex> GeoPartition.Geometry.intersection(reference, disjoint)
{:disjoint, "disjoint"}
iex> reference = %Geo.LineString{coordinates: [{1.0, 1.0}, {2.0, 2.0}]}
iex> overlap = %Geo.LineString{coordinates: [{1.5, 1.5}, {3.0, 3.0}]}
iex> GeoPartition.Geometry.intersection(reference, overlap)
{:degen, "degen"}
iex> reference = %Geo.LineString{coordinates: [{1.0, 1.0}, {2.0, 2.0}]}
iex> intersect = %Geo.LineString{coordinates: [{2.0, 1.0}, {1.0, 2.0}]}
iex> GeoPartition.Geometry.intersection(reference, intersect)
{:intersects, %Geo.Point{coordinates: {1.5, 1.5}, properties: %{}, srid: nil}}
Converts a polygon (Geo.Polygon) to a graph. If the polygon has holes that overlap the
outer ring, they will be circumvented
Examples
iex> shape = %Geo.Polygon{
...> coordinates: [
...> [
...> {1.0, 1.0},
...> {3.0, 2.0},
...> {1.0, 3.0},
...> {1.0, 1.0}
...> ],
...> [
...> {2.0, 2.0},
...> {4.0, 1.0},
...> {4.0, 3.0},
...> {2.0, 2.0}
...> ],
...> [
...> {1.4, 2.4},
...> {1.4, 1.6},
...> {1.8, 1.6},
...> {1.8, 2.4},
...> {1.4, 2.4}
...> ]
...> ]
...> }
iex> GeoPartition.Geometry.polygon_to_graph(shape)
{[
%Geo.Point{ coordinates: {1.0, 1.0}, properties: %{covered: false, ring: :outer}, srid: nil },
%Geo.Point{ coordinates: {1.0, 3.0}, properties: %{covered: false, ring: :outer}, srid: nil },
%Geo.Point{ coordinates: {2.0, 2.0}, properties: %{covered: true, ring: :inner}, srid: nil },
%Geo.Point{ coordinates: {1.4, 2.4}, properties: %{covered: true, ring: :inner}, srid: nil },
%Geo.Point{ coordinates: {1.4, 1.6}, properties: %{covered: true, ring: :inner}, srid: nil },
%Geo.Point{ coordinates: {1.8, 1.6}, properties: %{covered: true, ring: :inner}, srid: nil },
%Geo.Point{ coordinates: {1.8, 2.4}, properties: %{covered: true, ring: :inner}, srid: nil },
%Geo.Point{ coordinates: {2.5, 1.75}, srid: nil, properties: %{covered: false, ring: :intersection} },
%Geo.Point{ coordinates: {2.5, 2.25}, srid: nil, properties: %{covered: false, ring: :intersection} }
], [
MapSet.new([
%Geo.Point{coordinates: {1.0, 3.0}, properties: %{covered: false, ring: :outer}, srid: nil},
%Geo.Point{coordinates: {2.5, 2.25}, properties: %{covered: false, ring: :intersection}, srid: nil}
]),
MapSet.new([
%Geo.Point{coordinates: {2.0, 2.0}, properties: %{covered: true, ring: :inner}, srid: nil},
%Geo.Point{coordinates: {2.5, 2.25}, properties: %{covered: false, ring: :intersection}, srid: nil}
]),
MapSet.new([
%Geo.Point{coordinates: {1.0, 1.0}, properties: %{covered: false, ring: :outer}, srid: nil},
%Geo.Point{coordinates: {2.5, 1.75}, properties: %{covered: false, ring: :intersection}, srid: nil}
]),
MapSet.new([
%Geo.Point{coordinates: {2.0, 2.0}, properties: %{covered: true, ring: :inner}, srid: nil},
%Geo.Point{coordinates: {2.5, 1.75}, properties: %{covered: false, ring: :intersection}, srid: nil}
]),
MapSet.new([
%Geo.Point{coordinates: {1.0, 1.0}, properties: %{covered: false, ring: :outer}, srid: nil},
%Geo.Point{coordinates: {1.0, 3.0}, properties: %{covered: false, ring: :outer}, srid: nil}
]),
MapSet.new([
%Geo.Point{coordinates: {1.4, 1.6}, properties: %{covered: true, ring: :inner}, srid: nil},
%Geo.Point{coordinates: {1.4, 2.4}, properties: %{covered: true, ring: :inner}, srid: nil}
]),
MapSet.new([
%Geo.Point{coordinates: {1.8, 1.6}, properties: %{covered: true, ring: :inner}, srid: nil},
%Geo.Point{coordinates: {1.4, 1.6}, properties: %{covered: true, ring: :inner}, srid: nil}
]),
MapSet.new([
%Geo.Point{coordinates: {1.8, 2.4}, properties: %{covered: true, ring: :inner}, srid: nil},
%Geo.Point{coordinates: {1.8, 1.6}, properties: %{covered: true, ring: :inner}, srid: nil}
]),
MapSet.new([
%Geo.Point{coordinates: {1.8, 2.4}, properties: %{covered: true, ring: :inner}, srid: nil},
%Geo.Point{coordinates: {1.4, 2.4}, properties: %{covered: true, ring: :inner}, srid: nil}
])
]}