Measurement¶
Area, length, distance, nearest points, and similarity measures.
Related: CRS, units & measurement
area
¶
Accepted call forms
area(geom: Geometry, *, unit: Literal['planar', 'meters'] | None = None) -> float
area(geom: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], *, unit: Literal['planar', 'meters'] | None = None) -> NDArray[float64]
area(geom: Iterable[Geometry | Buffer | Mapping[str, Any] | SupportsGeoInterface | None], *, unit: Literal['planar', 'meters'] | None = None) -> NDArray[float64]
area(geom: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None] | Iterable[Geometry | Buffer | Mapping[str, Any] | SupportsGeoInterface | None], *, unit: Literal['planar', 'meters'] | None = None) -> float | NDArray[float64]
Compute area in CRS-natural units or with a unit override.
For a GeometryCollection, overlapping members count once, as the area
of their union. Parts of a valid MultiPolygon cannot overlap.
For geographic geometries, area is the ellipsoidal area of the region whose edges are straight in longitude/latitude.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
geom
|
Geometry, GeometryArray, or iterable of geometry-like values or None
|
Input geometry, array, or iterable materialized as a row-preserving
array. Missing rows return |
required |
unit
|
('planar', 'meters')
|
|
'planar'
|
Returns:
| Type | Description |
|---|---|
float or ndarray
|
Scalar area or one value per row. |
Raises:
| Type | Description |
|---|---|
CRSError
|
If the CRS lacks linear axis units for a metric result. |
GeometryError
|
If |
Examples:
>>> import gometry as gm
>>> gm.area(gm.box(0, 0, 2, 2), unit='planar')
4.0
distance
¶
Accepted call forms
distance(left: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Point | None], right: Point | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Point | None], *, path: Literal['rhumb'], unit: None = None) -> NDArray[float64]
distance(left: Point, right: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Point | None], *, path: Literal['rhumb'], unit: None = None) -> NDArray[float64]
distance(left: Point | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Point | None], right: Point | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Point | None], *, path: Literal['rhumb'], unit: None = None) -> float | NDArray[float64]
distance(left: Geometry, right: Geometry, *, path: Literal['geodesic'] = 'geodesic', unit: Literal['planar', 'meters'] | None = None) -> float
distance(left: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], right: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], *, path: Literal['geodesic'] = 'geodesic', unit: Literal['planar', 'meters'] | None = None) -> NDArray[float64]
distance(left: Geometry, right: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], *, path: Literal['geodesic'] = 'geodesic', unit: Literal['planar', 'meters'] | None = None) -> NDArray[float64]
distance(left: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], right: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], *, path: Literal['geodesic'] = 'geodesic', unit: Literal['planar', 'meters'] | None = None) -> float | NDArray[float64]
Compute the minimum distance between left and right.
CRS-aware: geodesic meters on a geographic CRS, native linear units on a
projected CRS, raw coordinate units when CRS-free. On a geographic CRS,
point-to-point distances use ellipsoidal geodesics, and shape edges are
straight in the CRS's longitude/latitude chart with short-way longitude
across the antimeridian. Filled polygon interiors participate. For two
points, path='rhumb' measures the constant-bearing route in meters on a
geographic CRS.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
left
|
Geometry, GeometryArray, or iterable of Geometry or None
|
Scalar and sequence operands broadcast pairwise; sequences must have equal length and compatible CRS/epoch frames. |
required |
right
|
Geometry, GeometryArray, or iterable of Geometry or None
|
Scalar and sequence operands broadcast pairwise; sequences must have equal length and compatible CRS/epoch frames. |
required |
path
|
('geodesic', 'rhumb')
|
Route for point operands. Omit for geodesic distance; rhumb distance
requires |
'geodesic'
|
unit
|
('planar', 'meters')
|
|
'planar'
|
Returns:
| Type | Description |
|---|---|
float or ndarray
|
One result per input pair. |
Raises:
| Type | Description |
|---|---|
CRSError
|
If the CRS lacks linear axis units for a metric result. |
CRSMismatchError
|
If the operands' CRS or coordinate-epoch metadata differ. |
GeometryTypeError
|
If |
CRSError
|
If |
GeometryError
|
If |
See Also
dwithin : Within-distance test. nearest_points : Closest-pair witness points. shortest_line : Connecting line between closest points. hausdorff_distance : Hausdorff (set-to-set) similarity distance. frechet_distance : Curve-to-curve similarity (linestrings).
Examples:
>>> import gometry as gm
>>> gm.distance(gm.Point(0, 0), gm.Point(3, 4))
5.0
>>> a, b = gm.Point(13.0, 52.0, crs=4326), gm.Point(13.1, 52.0, crs=4326)
>>> round(gm.distance(a, b)) # meters
6868
distance_3d
¶
Accepted call forms
distance_3d(left: Geometry, right: Geometry, *, unit: Literal['planar', 'meters'] | None = None) -> float
distance_3d(left: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], right: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], *, unit: Literal['planar', 'meters'] | None = None) -> NDArray[float64]
distance_3d(left: Geometry, right: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], *, unit: Literal['planar', 'meters'] | None = None) -> NDArray[float64]
distance_3d(left: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], right: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], *, unit: Literal['planar', 'meters'] | None = None) -> float | NDArray[float64]
Compute the minimum 3D (Euclidean) distance between two geometries, measured for their CRS.
Distance is over linework: points/multipoints as degenerate segments,
polygons via their boundary rings. Part of the 3D Euclidean family with
length_3d only — area and perimeter are inherently 2D (XY footprint)
and have no 3D form; the 3D extent is bounds with min_z/max_z.
A projected CRS gives native linear units and a CRS-free geometry gives
raw coordinate units — the same defaults as the 2D distance. A geographic
CRS raises under every unit: a Euclidean norm cannot combine degrees
with meter heights. Every vertex on both operands must carry a Z ordinate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
left
|
Geometry, GeometryArray, or iterable of Geometry or None
|
Scalar and sequence operands broadcast pairwise; sequences must have equal length and compatible CRS/epoch frames. |
required |
right
|
Geometry, GeometryArray, or iterable of Geometry or None
|
Scalar and sequence operands broadcast pairwise; sequences must have equal length and compatible CRS/epoch frames. |
required |
unit
|
('planar', 'meters')
|
|
'planar'
|
Returns:
| Type | Description |
|---|---|
float or ndarray
|
One result per input pair. |
Raises:
| Type | Description |
|---|---|
CRSError
|
If the CRS lacks linear axis units for a metric result. |
CRSMismatchError
|
If the operands' CRS or coordinate-epoch metadata differ. |
GeometryError
|
If |
InvalidGeometryError
|
If either operand lacks a Z ordinate on every vertex. |
See Also
distance : The 2D sibling, with the same unit override.
length_3d : Total 3D length under the same metric.
Examples:
>>> import gometry as gm
>>> gm.distance_3d(gm.from_wkt('POINT Z (0 0 0)'), gm.from_wkt('POINT Z (0 0 3)'))
3.0
frechet_distance
¶
Accepted call forms
frechet_distance(left: Geometry, right: Geometry, *, densify: float | None = None, unit: Literal['planar', 'meters'] | None = None) -> float
frechet_distance(left: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], right: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], *, densify: FloatInput | None = None, unit: Literal['planar', 'meters'] | None = None) -> NDArray[float64]
frechet_distance(left: Geometry, right: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], *, densify: FloatInput | None = None, unit: Literal['planar', 'meters'] | None = None) -> NDArray[float64]
frechet_distance(left: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], right: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], *, densify: FloatInput | None = None, unit: Literal['planar', 'meters'] | None = None) -> float | NDArray[float64]
Discrete Fréchet distance between two linestrings.
Measured for the CRS like distance: geodesic meters on a geographic
CRS, native linear units on a projected CRS, raw coordinate units when CRS-free.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
left
|
Geometry, GeometryArray, or iterable of Geometry or None
|
The line operands; scalar and sequence inputs broadcast pairwise. |
required |
right
|
Geometry, GeometryArray, or iterable of Geometry or None
|
The line operands; scalar and sequence inputs broadcast pairwise. |
required |
densify
|
float
|
Subdivide every segment into pieces no longer than this
fraction of its length (in |
None
|
unit
|
('planar', 'meters')
|
|
'planar'
|
Returns:
| Type | Description |
|---|---|
float or ndarray
|
One result per input pair. |
Raises:
| Type | Description |
|---|---|
GeometryError
|
If |
CRSMismatchError
|
If the operands' CRS or coordinate-epoch metadata differ. |
InvalidGeometryError
|
If the linework is empty. |
GeometryTypeError
|
If either geometry is not a single line. |
See Also
distance : Minimum pairwise distance. hausdorff_distance : Hausdorff (set-to-set) similarity distance. dwithin : Within-distance test. nearest_points : Closest-pair witness points. shortest_line : Connecting line between closest points.
Examples:
>>> import gometry as gm
>>> a = gm.LineString([(0, 0), (10, 0)])
>>> b = gm.LineString([(0, 1), (10, 1)])
>>> gm.frechet_distance(a, b)
1.0
hausdorff_distance
¶
Accepted call forms
hausdorff_distance(left: Geometry, right: Geometry, *, max_error: float | None = None, unit: Literal['planar', 'meters'] | None = None) -> float
hausdorff_distance(left: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], right: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], *, max_error: float | None = None, unit: Literal['planar', 'meters'] | None = None) -> NDArray[float64]
hausdorff_distance(left: Geometry, right: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], *, max_error: float | None = None, unit: Literal['planar', 'meters'] | None = None) -> NDArray[float64]
hausdorff_distance(left: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], right: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], *, max_error: float | None = None, unit: Literal['planar', 'meters'] | None = None) -> float | NDArray[float64]
Compute the continuous Hausdorff (set-to-set) distance between left
and right.
CRS-aware: geodesic meters on a geographic CRS, native linear units on a
projected CRS, raw coordinate units when CRS-free. Geographic Hausdorff
ranges continuously over straight chart edges and supports point and
linework operands only; filled polygon interiors require unit='planar'
or a projected CRS. Planar results use a certified relative bound by
default or a caller-supplied absolute bound.
Planar polygons are filled sets, including their interiors. For example,
a square [-2, 2] by [-2, 2] and the same square with a diamond hole at
(0, 1), (1, 0), (0, -1), (-1, 0) have filled-set Hausdorff distance
1 / sqrt(2), whereas their boundary Hausdorff distance is 1.5.
Shapely's discrete and densified Hausdorff forms measure boundaries instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
left
|
Geometry, GeometryArray, or iterable of Geometry or None
|
Scalar and sequence operands broadcast pairwise; sequences must have equal length and compatible CRS/epoch frames. |
required |
right
|
Geometry, GeometryArray, or iterable of Geometry or None
|
Scalar and sequence operands broadcast pairwise; sequences must have equal length and compatible CRS/epoch frames. |
required |
max_error
|
float
|
Positive finite scalar absolute error bound in final result units.
Planar results default to a certified relative error of at most
|
None
|
unit
|
('planar', 'meters')
|
|
'planar'
|
Returns:
| Type | Description |
|---|---|
float or ndarray
|
One result per input pair. A planar result is zero exactly when the
operands have equal closed support; unequal positive distances remain
positive even when smaller than the effective error bound. An empty
operand yields |
Raises:
| Type | Description |
|---|---|
CRSError
|
If the CRS lacks linear axis units for a metric result, or a geographic operand includes a filled polygon interior, or the geographic source frontier cannot close its numerical gap before binary64 parameter refinement stops. |
CRSMismatchError
|
If the operands' CRS or coordinate-epoch metadata differ. |
GeometryError
|
If |
See Also
distance : Minimum pairwise distance. frechet_distance : Curve-to-curve similarity (linestrings). dwithin : Within-distance test. nearest_points : Closest-pair witness points. shortest_line : Connecting line between closest points.
Examples:
>>> import gometry as gm
>>> a = gm.LineString([(0, 0), (10, 0)])
>>> b = gm.LineString([(0, 1), (10, 3)])
>>> abs(gm.hausdorff_distance(a, b, max_error=1e-12) - 3.0) <= 1e-12
True
length
¶
Accepted call forms
length(geom: Geometry, *, unit: Literal['planar', 'meters'] | None = None) -> float
length(geom: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], *, unit: Literal['planar', 'meters'] | None = None) -> NDArray[float64]
length(geom: Iterable[Geometry | Buffer | Mapping[str, Any] | SupportsGeoInterface | None], *, unit: Literal['planar', 'meters'] | None = None) -> NDArray[float64]
length(geom: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None] | Iterable[Geometry | Buffer | Mapping[str, Any] | SupportsGeoInterface | None], *, unit: Literal['planar', 'meters'] | None = None) -> float | NDArray[float64]
Compute length in CRS-natural units or with a unit override.
For a GeometryCollection, length sums every member's length or
perimeter, including overlapping members.
For geographic geometries, length and perimeter are measured along edges straight in longitude/latitude on the CRS ellipsoid.
Geographic polygon perimeter removes chart-cut copies only: within one ring, antiparallel coincident arcs at different longitude lifts cancel; on the canonical seam meridian, opposite-interior copies cancel across all rings, including a ring with itself. Same-side seam duplicates, off-seam same-lift retraces, and every other stored overlap remain in the perimeter. This seam convention is tied to the canonical seam: rotating the longitude origin can change which arcs are seam cuts.
Arc identity uses exact canonical longitudes and admitted latitudes; no tolerance is applied. Between the two seam spellings, the longitude step is degenerate; differing latitudes still trace a meridian arc. An explicit one-period edge between non-seam longitudes follows the full circle. Planar and projected perimeter rules are unchanged.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
geom
|
Geometry, GeometryArray, or iterable of geometry-like values or None
|
Input geometry, array, or iterable materialized as a row-preserving
array. Missing rows return |
required |
unit
|
('planar', 'meters')
|
|
'planar'
|
Returns:
| Type | Description |
|---|---|
float or ndarray
|
Scalar length or one value per row. |
Raises:
| Type | Description |
|---|---|
CRSError
|
If the CRS lacks linear axis units for a metric result. |
GeometryError
|
If |
Examples:
>>> import gometry as gm
>>> gm.length(gm.LineString([(0, 0), (3, 4)]), unit='planar')
5.0
length_3d
¶
Accepted call forms
length_3d(geom: Geometry, *, unit: Literal['planar', 'meters'] | None = None) -> float
length_3d(geom: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], *, unit: Literal['planar', 'meters'] | None = None) -> NDArray[float64]
length_3d(geom: Iterable[Geometry | Buffer | Mapping[str, Any] | SupportsGeoInterface | None], *, unit: Literal['planar', 'meters'] | None = None) -> NDArray[float64]
length_3d(geom: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None] | Iterable[Geometry | Buffer | Mapping[str, Any] | SupportsGeoInterface | None], *, unit: Literal['planar', 'meters'] | None = None) -> float | NDArray[float64]
Compute 3D length in CRS-natural units or with a unit override.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
geom
|
Geometry, GeometryArray, or iterable of geometry-like values or None
|
Input geometry, array, or iterable materialized as a row-preserving
array. Missing rows return |
required |
unit
|
('planar', 'meters')
|
Geographic CRSs are not supported by 3D Euclidean metrics. |
'planar'
|
Returns:
| Type | Description |
|---|---|
float or ndarray
|
Scalar 3D length or one value per row. |
Raises:
| Type | Description |
|---|---|
CRSError
|
If the CRS lacks linear axis units for a metric result. |
GeometryError
|
If |
InvalidGeometryError
|
If a scalar geometry lacks Z on every vertex. |
See Also
length_3d : CRS-natural property form.
length : The 2D sibling, with the same unit override.
distance_3d : Pairwise 3D distance under the same metric.
Examples:
>>> import gometry as gm
>>> gm.length_3d(gm.from_wkt('LINESTRING Z (0 0 0, 3 4 0)'), unit='planar')
5.0
nearest_points
¶
Accepted call forms
nearest_points(left: Geometry, right: Geometry, *, unit: Literal['planar', 'meters'] | None = None) -> tuple[Point, Point]
nearest_points(left: Geometry, right: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryT], *, unit: Literal['planar', 'meters'] | None = None) -> tuple[GeometryArray[Point], GeometryArray[Point]]
nearest_points(left: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryT], right: Geometry, *, unit: Literal['planar', 'meters'] | None = None) -> tuple[GeometryArray[Point], GeometryArray[Point]]
nearest_points(left: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryT], right: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryOtherT], *, unit: Literal['planar', 'meters'] | None = None) -> tuple[GeometryArray[Point], GeometryArray[Point]]
nearest_points(left: Geometry, right: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryT | None], *, unit: Literal['planar', 'meters'] | None = None) -> tuple[GeometryArray[Point | None], GeometryArray[Point | None]]
nearest_points(left: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryT | None], right: Geometry, *, unit: Literal['planar', 'meters'] | None = None) -> tuple[GeometryArray[Point | None], GeometryArray[Point | None]]
nearest_points(left: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryT | None], right: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryOtherT | None], *, unit: Literal['planar', 'meters'] | None = None) -> tuple[GeometryArray[Point | None], GeometryArray[Point | None]]
nearest_points(left: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], right: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], *, unit: Literal['planar', 'meters'] | None = None) -> tuple[Point, Point] | tuple[GeometryArray[Point | None], GeometryArray[Point | None]]
Return the closest pair of points between two geometries.
Realizes the same minimizer as distance: point-to-point distance is
geodesic on a geographic CRS, planar on a projected one, and in coordinate
space when CRS-free. Geographic shape edges are straight in the CRS's
longitude/latitude chart, using short-way longitude across the antimeridian;
filled polygon interiors participate. Planar and projected metrics accept
any geometry pair, not only points (the witness on a polygon/line may be an
edge-interior point). The connecting line is shortest_line.
An empty operand yields
(POINT EMPTY, POINT EMPTY), and the pair is dropped to the operands'
common axes so it matches shortest_line's endpoints exactly.
Equal-distance witnesses prefer an interior projection over a point or endpoint, then source order. Geographic metrics apply this order only to equal evaluated backend distances; analytic branches retain their available candidate. This does not assert an exact geodesic minimum.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
left
|
Geometry, GeometryArray, or iterable of Geometry or None
|
Scalar and sequence operands broadcast pairwise; sequences must have
equal length and compatible CRS/epoch frames. Unpack order is point on
|
required |
right
|
Geometry, GeometryArray, or iterable of Geometry or None
|
Scalar and sequence operands broadcast pairwise; sequences must have
equal length and compatible CRS/epoch frames. Unpack order is point on
|
required |
unit
|
('planar', 'meters')
|
|
'planar'
|
Returns:
| Type | Description |
|---|---|
tuple of Point or tuple of GeometryArray
|
A |
Raises:
| Type | Description |
|---|---|
CRSMismatchError
|
If the operands' CRS or coordinate-epoch metadata differ. |
See Also
distance : Minimum pairwise distance. shortest_line : Connecting line between closest points. dwithin : Within-distance test. hausdorff_distance : Hausdorff (set-to-set) similarity distance. frechet_distance : Curve-to-curve similarity (linestrings).
Examples:
>>> import gometry as gm
>>> square = gm.box(0, 0, 1, 1)
>>> a, b = gm.nearest_points(square, gm.Point(3, 0.5))
>>> (a.to_wkt(), b.to_wkt())
('POINT (1 0.5)', 'POINT (3 0.5)')
shortest_line
¶
Accepted call forms
shortest_line(left: Geometry, right: Geometry, *, unit: Literal['planar', 'meters'] | None = None) -> LineString
shortest_line(left: Geometry, right: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryT], *, unit: Literal['planar', 'meters'] | None = None) -> GeometryArray[LineString]
shortest_line(left: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryT], right: Geometry, *, unit: Literal['planar', 'meters'] | None = None) -> GeometryArray[LineString]
shortest_line(left: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryT], right: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryOtherT], *, unit: Literal['planar', 'meters'] | None = None) -> GeometryArray[LineString]
shortest_line(left: Geometry, right: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryT | None], *, unit: Literal['planar', 'meters'] | None = None) -> GeometryArray[LineString | None]
shortest_line(left: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryT | None], right: Geometry, *, unit: Literal['planar', 'meters'] | None = None) -> GeometryArray[LineString | None]
shortest_line(left: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryT | None], right: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryOtherT | None], *, unit: Literal['planar', 'meters'] | None = None) -> GeometryArray[LineString | None]
shortest_line(left: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], right: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], *, unit: Literal['planar', 'meters'] | None = None) -> LineString | GeometryArray[LineString | None]
Return the shortest connecting line between two geometries (CRS-aware).
nearest_points as a connecting LineString — degenerate when the
geometries touch. Planar and projected metrics accept any geometry pair, not
only points, and the witness is the closest approach, so an endpoint may
land on an edge interior rather than a vertex.
On a geographic CRS, point-to-point separation uses ellipsoidal geodesics. Shape edges are straight in the CRS-native periodic longitude/latitude chart: admitted ordinary edges use their shortest periodic step, while an explicitly stored full-period circle edge retains its full turn. See the CRS guide's polar-ring and full-turn-edge rules. Filled polygon interiors participate.
The returned line follows the chart-edge model. With the CRS-aware
geographic metric, its ellipsoidal length is no shorter than the witness
separation in exact geometry, subject to binary64 rounding. If
unit='planar' overrides the metric, measure the line with the same
unit when comparing lengths. Publication may add vertices to preserve
the computed chart edge; do not assume the line always stores exactly two
coordinates.
An empty operand yields
LINESTRING EMPTY (the output-type sentinel, like
distance's inf). Output ordinates are the operands' common axes (an
XYZM line versus an XY point gives an XY line). See nearest_points for
the witnesses and distance for their metric separation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
left
|
Geometry, GeometryArray, or iterable of Geometry or None
|
Scalar and sequence operands broadcast pairwise; sequences must have equal length and compatible CRS/epoch frames. |
required |
right
|
Geometry, GeometryArray, or iterable of Geometry or None
|
Scalar and sequence operands broadcast pairwise; sequences must have equal length and compatible CRS/epoch frames. |
required |
unit
|
('planar', 'meters')
|
|
'planar'
|
Returns:
| Type | Description |
|---|---|
Geometry or GeometryArray
|
One connecting |
Raises:
| Type | Description |
|---|---|
CRSMismatchError
|
If the operands' CRS or coordinate-epoch metadata differ. |
See Also
distance : Minimum pairwise distance. nearest_points : Closest-pair witness points. dwithin : Within-distance test. hausdorff_distance : Hausdorff (set-to-set) similarity distance. frechet_distance : Curve-to-curve similarity (linestrings).
Examples:
>>> import gometry as gm
>>> square = gm.box(0, 0, 1, 1)
>>> gm.shortest_line(square, gm.Point(3, 0.5)).to_wkt()
'LINESTRING (1 0.5, 3 0.5)'
>>> # The near point can fall mid-edge, not on a vertex:
>>> a = gm.from_wkt('POLYGON ((0 0, 2 0, 2 2, 0 2, 0 0))')
>>> b = gm.from_wkt('POLYGON ((4 1, 5 0, 6 1, 5 2, 4 1))')
>>> gm.shortest_line(a, b).to_wkt()
'LINESTRING (2 1, 4 1)'