Skip to content

Commit

Permalink
Merge pull request #32 from caspervdw/measurements
Browse files Browse the repository at this point in the history
Document and test measurement funcs
  • Loading branch information
caspervdw committed Aug 27, 2019
2 parents be52092 + 4a4e40b commit 6a7336b
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 18 deletions.
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ API Reference

constructive
geometry
measurement
predicates
set_operations

Expand Down
9 changes: 9 additions & 0 deletions docs/measurement.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
:mod:`pygeos.measurement`
=========================

.. automodule:: pygeos.measurement
:members:
:exclude-members:
:special-members:
:inherited-members:
:show-inheritance:
84 changes: 80 additions & 4 deletions pygeos/measurements.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,97 @@
from . import ufuncs
from . import Geometry, Empty # NOQA

__all__ = ["area", "distance", "length", "hausdorff_distance"]


def area(geometries):
return ufuncs.area(geometries)
def area(geometry):
"""Computes the area of a (multi)polygon.
Parameters
----------
geometry : Geometry or array_like
Examples
--------
>>> area(Geometry("POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))"))
100.0
>>> area(Geometry("MULTIPOLYGON (((0 0, 0 10, 10 10, 0 0)), ((0 0, 0 10, 10 10, 0 0)))"))
100.0
>>> area(Empty)
nan
"""
return ufuncs.area(geometry)


def distance(a, b):
"""Computes the Cartesian distance between two geometries.
Parameters
----------
a, b : Geometry or array_like
Examples
--------
>>> point = Geometry("POINT (0 0)")
>>> distance(Geometry("POINT (10 0)"), point)
10.0
>>> distance(Geometry("LINESTRING (1 1, 1 -1)"), point)
1.0
>>> distance(Geometry("POLYGON ((3 0, 5 0, 5 5, 3 5, 3 0))"), point)
3.0
>>> distance(Empty, point)
nan
"""
return ufuncs.distance(a, b)


def length(geometries):
return ufuncs.length(geometries)
def length(geometry):
"""Computes the length of a (multi)linestring or polygon perimeter.
Parameters
----------
geometry : Geometry or array_like
Examples
--------
>>> length(Geometry("LINESTRING (0 0, 0 2, 3 2)"))
5.0
>>> length(Geometry("MULTILINESTRING ((0 0, 1 0), (0 0, 1 0))"))
2.0
>>> length(Geometry("POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))"))
40.0
>>> length(Empty)
nan
"""
return ufuncs.length(geometry)


def hausdorff_distance(a, b, densify=None):
"""Compute the discrete Haussdorf distance between two geometries.
The Haussdorf distance is a measure of similarity: it is the greatest
distance between any point in A and the closest point in B. The discrete
distance is an approximation of this metric: only vertices are considered.
The parameter 'densify' makes this approximation less coarse by splitting
the line segments between vertices before computing the distance.
Parameters
----------
a, b : Geometry or array_like
densify : float, array_like or None
The value of densify is required to be between 0 and 1.
Examples
--------
>>> line_1 = Geometry("LINESTRING (130 0, 0 0, 0 150)")
>>> line_2 = Geometry("LINESTRING (10 10, 10 150, 130 10)")
>>> hausdorff_distance(line_1, line_2) # doctest: +ELLIPSIS
14.14...
>>> hausdorff_distance(line_1, line_2, densify=0.5)
70.0
>>> hausdorff_distance(line_1, Empty)
nan
"""
if densify is None:
return ufuncs.hausdorff_distance(a, b)
else:
Expand Down
73 changes: 59 additions & 14 deletions pygeos/test/test_measurement.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,38 @@
import pytest
import numpy as np

from pygeos import Empty

from .common import point_polygon_testdata
from .common import point, polygon
from .common import point
from .common import line_string
from .common import linear_ring
from .common import polygon
from .common import polygon_with_hole
from .common import multi_point
from .common import multi_line_string
from .common import multi_polygon
from .common import geometry_collection


def test_area():
assert pygeos.area(polygon) == 4.0
@pytest.mark.parametrize(
"geom",
[
point,
line_string,
linear_ring,
multi_point,
multi_line_string,
geometry_collection,
],
)
def test_area_non_polygon(geom):
assert pygeos.area(geom) == 0.0


def test_area_nan():
actual = pygeos.area(np.array([polygon, np.nan, None]))
assert actual[0] == pygeos.area(polygon)
assert np.isnan(actual[1])
assert np.isnan(actual[2])
def test_area():
actual = pygeos.area([polygon, polygon_with_hole, multi_polygon])
assert actual.tolist() == [4.0, 96.0, 1.01]


def test_distance():
Expand All @@ -23,13 +42,29 @@ def test_distance():
np.testing.assert_allclose(actual, expected)


def test_distance_nan():
actual = pygeos.distance(
np.array([point, np.nan, np.nan, point, None, None, point]),
np.array([np.nan, point, np.nan, None, point, None, point]),
def test_distance_empty():
actual = pygeos.distance(point, Empty)
assert np.isnan(actual)


def test_length():
actual = pygeos.length(
[
point,
line_string,
linear_ring,
polygon,
polygon_with_hole,
multi_point,
multi_polygon,
]
)
assert actual[-1] == 0.0
assert np.isnan(actual[:-1].astype(np.float)).all()
assert actual.tolist() == [0.0, 2.0, 4.0, 8.0, 48.0, 0.0, 4.4]


def test_length_empty():
actual = pygeos.length(Empty)
assert np.isnan(actual)


def test_haussdorf_distance():
Expand All @@ -46,3 +81,13 @@ def test_haussdorf_distance_densify():
b = pygeos.linestrings([[0, 100], [0, 10], [80, 10]])
actual = pygeos.hausdorff_distance(a, b, densify=0.001)
assert actual == pytest.approx(47.8, abs=0.1)


def test_haussdorf_distance_empty():
actual = pygeos.hausdorff_distance(point, Empty)
assert np.isnan(actual)


def test_haussdorf_densify_nan():
actual = pygeos.hausdorff_distance(point, point, densify=np.nan)
assert np.isnan(actual)

0 comments on commit 6a7336b

Please sign in to comment.