356 lines
10 KiB
Python
356 lines
10 KiB
Python
"""Methods for measuring (between) geometries."""
|
|
|
|
import warnings
|
|
|
|
import numpy as np
|
|
|
|
from shapely import lib
|
|
from shapely.decorators import multithreading_enabled
|
|
|
|
__all__ = [
|
|
"area",
|
|
"bounds",
|
|
"distance",
|
|
"frechet_distance",
|
|
"hausdorff_distance",
|
|
"length",
|
|
"minimum_bounding_radius",
|
|
"minimum_clearance",
|
|
"total_bounds",
|
|
]
|
|
|
|
|
|
@multithreading_enabled
|
|
def area(geometry, **kwargs):
|
|
"""Compute the area of a (multi)polygon.
|
|
|
|
Parameters
|
|
----------
|
|
geometry : Geometry or array_like
|
|
Geometry or geometries for which to compute the area.
|
|
**kwargs
|
|
See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
|
|
|
|
Examples
|
|
--------
|
|
>>> import shapely
|
|
>>> from shapely import MultiPolygon, Polygon
|
|
>>> polygon = Polygon([(0, 0), (0, 10), (10, 10), (10, 0), (0, 0)])
|
|
>>> shapely.area(polygon)
|
|
100.0
|
|
>>> polygon2 = Polygon([(10, 10), (10, 20), (20, 20), (20, 10), (10, 10)])
|
|
>>> shapely.area(MultiPolygon([polygon, polygon2]))
|
|
200.0
|
|
>>> shapely.area(Polygon())
|
|
0.0
|
|
>>> shapely.area(None)
|
|
nan
|
|
|
|
"""
|
|
return lib.area(geometry, **kwargs)
|
|
|
|
|
|
@multithreading_enabled
|
|
def distance(a, b, **kwargs):
|
|
"""Compute the Cartesian distance between two geometries.
|
|
|
|
Parameters
|
|
----------
|
|
a, b : Geometry or array_like
|
|
Geometry or geometries to compute the distance between.
|
|
**kwargs
|
|
See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
|
|
|
|
Examples
|
|
--------
|
|
>>> import shapely
|
|
>>> from shapely import LineString, Point, Polygon
|
|
>>> point = Point(0, 0)
|
|
>>> shapely.distance(Point(10, 0), point)
|
|
10.0
|
|
>>> shapely.distance(LineString([(1, 1), (1, -1)]), point)
|
|
1.0
|
|
>>> shapely.distance(Polygon([(3, 0), (5, 0), (5, 5), (3, 5), (3, 0)]), point)
|
|
3.0
|
|
>>> shapely.distance(Point(), point)
|
|
nan
|
|
>>> shapely.distance(None, point)
|
|
nan
|
|
|
|
"""
|
|
return lib.distance(a, b, **kwargs)
|
|
|
|
|
|
@multithreading_enabled
|
|
def bounds(geometry, **kwargs):
|
|
"""Compute the bounds (extent) of a geometry.
|
|
|
|
For each geometry these 4 numbers are returned: min x, min y, max x, max y.
|
|
|
|
Parameters
|
|
----------
|
|
geometry : Geometry or array_like
|
|
Geometry or geometries for which to compute the bounds.
|
|
**kwargs
|
|
See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
|
|
|
|
Examples
|
|
--------
|
|
>>> import shapely
|
|
>>> from shapely import LineString, Point, Polygon
|
|
>>> shapely.bounds(Point(2, 3)).tolist()
|
|
[2.0, 3.0, 2.0, 3.0]
|
|
>>> shapely.bounds(LineString([(0, 0), (0, 2), (3, 2)])).tolist()
|
|
[0.0, 0.0, 3.0, 2.0]
|
|
>>> shapely.bounds(Polygon()).tolist()
|
|
[nan, nan, nan, nan]
|
|
>>> shapely.bounds(None).tolist()
|
|
[nan, nan, nan, nan]
|
|
|
|
"""
|
|
return lib.bounds(geometry, **kwargs)
|
|
|
|
|
|
def total_bounds(geometry, **kwargs):
|
|
"""Compute the total bounds (extent) of the geometry.
|
|
|
|
Parameters
|
|
----------
|
|
geometry : Geometry or array_like
|
|
Geometry or geometries for which to compute the total bounds.
|
|
**kwargs
|
|
See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
|
|
|
|
Returns
|
|
-------
|
|
numpy ndarray of [xmin, ymin, xmax, ymax]
|
|
|
|
Examples
|
|
--------
|
|
>>> import shapely
|
|
>>> from shapely import LineString, Point, Polygon
|
|
>>> shapely.total_bounds(Point(2, 3)).tolist()
|
|
[2.0, 3.0, 2.0, 3.0]
|
|
>>> shapely.total_bounds([Point(2, 3), Point(4, 5)]).tolist()
|
|
[2.0, 3.0, 4.0, 5.0]
|
|
>>> shapely.total_bounds([
|
|
... LineString([(0, 1), (0, 2), (3, 2)]),
|
|
... LineString([(4, 4), (4, 6), (6, 7)])
|
|
... ]).tolist()
|
|
[0.0, 1.0, 6.0, 7.0]
|
|
>>> shapely.total_bounds(Polygon()).tolist()
|
|
[nan, nan, nan, nan]
|
|
>>> shapely.total_bounds([Polygon(), Point(2, 3)]).tolist()
|
|
[2.0, 3.0, 2.0, 3.0]
|
|
>>> shapely.total_bounds(None).tolist()
|
|
[nan, nan, nan, nan]
|
|
|
|
"""
|
|
b = bounds(geometry, **kwargs)
|
|
if b.ndim == 1:
|
|
return b
|
|
|
|
with warnings.catch_warnings():
|
|
# ignore 'All-NaN slice encountered' warnings
|
|
warnings.simplefilter("ignore", RuntimeWarning)
|
|
return np.array(
|
|
[
|
|
np.nanmin(b[..., 0]),
|
|
np.nanmin(b[..., 1]),
|
|
np.nanmax(b[..., 2]),
|
|
np.nanmax(b[..., 3]),
|
|
]
|
|
)
|
|
|
|
|
|
@multithreading_enabled
|
|
def length(geometry, **kwargs):
|
|
"""Compute the length of a (multi)linestring or polygon perimeter.
|
|
|
|
Parameters
|
|
----------
|
|
geometry : Geometry or array_like
|
|
Geometry or geometries for which to compute the length.
|
|
**kwargs
|
|
See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
|
|
|
|
Examples
|
|
--------
|
|
>>> import shapely
|
|
>>> from shapely import LineString, MultiLineString, Polygon
|
|
>>> shapely.length(LineString([(0, 0), (0, 2), (3, 2)]))
|
|
5.0
|
|
>>> shapely.length(MultiLineString([
|
|
... LineString([(0, 0), (1, 0)]),
|
|
... LineString([(1, 0), (2, 0)])
|
|
... ]))
|
|
2.0
|
|
>>> shapely.length(Polygon([(0, 0), (0, 10), (10, 10), (10, 0), (0, 0)]))
|
|
40.0
|
|
>>> shapely.length(LineString())
|
|
0.0
|
|
>>> shapely.length(None)
|
|
nan
|
|
|
|
"""
|
|
return lib.length(geometry, **kwargs)
|
|
|
|
|
|
@multithreading_enabled
|
|
def hausdorff_distance(a, b, densify=None, **kwargs):
|
|
"""Compute the discrete Hausdorff distance between two geometries.
|
|
|
|
The Hausdorff 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
|
|
Geometry or geometries to compute the distance between.
|
|
densify : float or array_like, optional
|
|
The value of densify is required to be between 0 and 1.
|
|
**kwargs
|
|
See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
|
|
|
|
Examples
|
|
--------
|
|
>>> import shapely
|
|
>>> from shapely import LineString
|
|
>>> line1 = LineString([(130, 0), (0, 0), (0, 150)])
|
|
>>> line2 = LineString([(10, 10), (10, 150), (130, 10)])
|
|
>>> shapely.hausdorff_distance(line1, line2)
|
|
14.142135623730951
|
|
>>> shapely.hausdorff_distance(line1, line2, densify=0.5)
|
|
70.0
|
|
>>> shapely.hausdorff_distance(line1, LineString())
|
|
nan
|
|
>>> shapely.hausdorff_distance(line1, None)
|
|
nan
|
|
|
|
"""
|
|
if densify is None:
|
|
return lib.hausdorff_distance(a, b, **kwargs)
|
|
else:
|
|
return lib.hausdorff_distance_densify(a, b, densify, **kwargs)
|
|
|
|
|
|
@multithreading_enabled
|
|
def frechet_distance(a, b, densify=None, **kwargs):
|
|
"""Compute the discrete Fréchet distance between two geometries.
|
|
|
|
The Fréchet 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.
|
|
|
|
Fréchet distance sweep continuously along their respective curves
|
|
and the direction of curves is significant. This makes it a better measure
|
|
of similarity than Hausdorff distance for curve or surface matching.
|
|
|
|
Parameters
|
|
----------
|
|
a, b : Geometry or array_like
|
|
Geometry or geometries to compute the distance between.
|
|
densify : float or array_like, optional
|
|
The value of densify is required to be between 0 and 1.
|
|
**kwargs
|
|
See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
|
|
|
|
Examples
|
|
--------
|
|
>>> import shapely
|
|
>>> from shapely import LineString
|
|
>>> line1 = LineString([(0, 0), (100, 0)])
|
|
>>> line2 = LineString([(0, 0), (50, 50), (100, 0)])
|
|
>>> shapely.frechet_distance(line1, line2)
|
|
70.71067811865476
|
|
>>> shapely.frechet_distance(line1, line2, densify=0.5)
|
|
50.0
|
|
>>> shapely.frechet_distance(line1, LineString())
|
|
nan
|
|
>>> shapely.frechet_distance(line1, None)
|
|
nan
|
|
|
|
"""
|
|
if densify is None:
|
|
return lib.frechet_distance(a, b, **kwargs)
|
|
return lib.frechet_distance_densify(a, b, densify, **kwargs)
|
|
|
|
|
|
@multithreading_enabled
|
|
def minimum_clearance(geometry, **kwargs):
|
|
"""Compute the Minimum Clearance distance.
|
|
|
|
A geometry's "minimum clearance" is the smallest distance by which
|
|
a vertex of the geometry could be moved to produce an invalid geometry.
|
|
|
|
If no minimum clearance exists for a geometry (for example, a single
|
|
point, or an empty geometry), infinity is returned.
|
|
|
|
Parameters
|
|
----------
|
|
geometry : Geometry or array_like
|
|
Geometry or geometries for which to compute the minimum clearance.
|
|
**kwargs
|
|
See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
|
|
|
|
Examples
|
|
--------
|
|
>>> import shapely
|
|
>>> from shapely import Polygon
|
|
>>> polygon = Polygon([(0, 0), (0, 10), (5, 6), (10, 10), (10, 0), (5, 4), (0, 0)])
|
|
>>> shapely.minimum_clearance(polygon)
|
|
2.0
|
|
>>> shapely.minimum_clearance(Polygon())
|
|
inf
|
|
>>> shapely.minimum_clearance(None)
|
|
nan
|
|
|
|
See Also
|
|
--------
|
|
minimum_clearance_line
|
|
|
|
"""
|
|
return lib.minimum_clearance(geometry, **kwargs)
|
|
|
|
|
|
@multithreading_enabled
|
|
def minimum_bounding_radius(geometry, **kwargs):
|
|
"""Compute the radius of the minimum bounding circle of an input geometry.
|
|
|
|
Parameters
|
|
----------
|
|
geometry : Geometry or array_like
|
|
Geometry or geometries for which to compute the minimum bounding radius.
|
|
**kwargs
|
|
See :ref:`NumPy ufunc docs <ufuncs.kwargs>` for other keyword arguments.
|
|
|
|
|
|
Examples
|
|
--------
|
|
>>> import shapely
|
|
>>> from shapely import GeometryCollection, LineString, MultiPoint, Point, Polygon
|
|
>>> shapely.minimum_bounding_radius(
|
|
... Polygon([(0, 5), (5, 10), (10, 5), (5, 0), (0, 5)])
|
|
... )
|
|
5.0
|
|
>>> shapely.minimum_bounding_radius(LineString([(1, 1), (1, 10)]))
|
|
4.5
|
|
>>> shapely.minimum_bounding_radius(MultiPoint([(2, 2), (4, 2)]))
|
|
1.0
|
|
>>> shapely.minimum_bounding_radius(Point(0, 1))
|
|
0.0
|
|
>>> shapely.minimum_bounding_radius(GeometryCollection())
|
|
0.0
|
|
|
|
See Also
|
|
--------
|
|
minimum_bounding_circle
|
|
|
|
"""
|
|
return lib.minimum_bounding_radius(geometry, **kwargs)
|