Skip to content

Constructive & validation

Split, snap, polygonize, and validate geometry.

Related: Validation & repair

polygonize_all

Accepted call forms
polygonize_all(values: Geometry | GeometryArray[Geometry | None] | Iterable[Geometry | Buffer | Mapping[str, Any] | SupportsGeoInterface | None], *, diagnostics: Literal[False] = False) -> GeometryArray[Polygon]
polygonize_all(values: Geometry | GeometryArray[Geometry] | Iterable[Geometry | Buffer | Mapping[str, Any] | SupportsGeoInterface], *, diagnostics: Literal[True]) -> PolygonizeResult[Never]
polygonize_all(values: Geometry | GeometryArray[Geometry | None] | Iterable[Geometry | Buffer | Mapping[str, Any] | SupportsGeoInterface | None], *, diagnostics: Literal[True]) -> PolygonizeResult[None]
polygonize_all(values: Geometry | GeometryArray[Geometry] | Iterable[Geometry | Buffer | Mapping[str, Any] | SupportsGeoInterface], *, diagnostics: bool) -> GeometryArray[Polygon] | PolygonizeResult[Never]
polygonize_all(values: Geometry | GeometryArray[Geometry | None] | Iterable[Geometry | Buffer | Mapping[str, Any] | SupportsGeoInterface | None], *, diagnostics: bool) -> GeometryArray[Polygon] | PolygonizeResult[None]

Build polygons from pooled linework, optionally returning full diagnostics.

All input geometries' edges are pooled into one linework graph, so a ring can close across inputs. diagnostics=False returns the enclosed polygons; diagnostics=True returns those same polygons together with cut edges, dangles, and invalid rings grouped by source row. Missing source rows are None groups; present rows with no diagnostic linework are empty groups.

For geographic input, polygon faces and diagnostic lines use the same classification, so an edge of a returned face is not also reported as an invalid ring. A closed polar-cap ring with no leftover linework returns a polygon with empty cut-edge, dangle, and invalid-ring groups. Planar inputs retain their planar diagnostic classification.

GeometryArray.polygonize() instead preserves one result group per input row, so use this function when different rows' edges should close together.

Parameters:

Name Type Description Default
values Geometry, GeometryArray, or iterable of Geometry-like values

One geometry or linework values to node and polygonize together. Array and iterable inputs may contain None rows; they are omitted from the pooled linework.

required
diagnostics bool

Return a PolygonizeResult containing the pooled polygons and source-row Groups for cut edges, dangles, and invalid rings. The diagnostic result form requires diagnostics=True; the polygon-only form omits the option.

required

Returns:

Type Description
GeometryArray or PolygonizeResult

With the default False, the polygons enclosed by the pooled linework. With True, the same polygons plus the leftover-linework diagnostics.

Raises:

Type Description
OverflowError

If no adjacent binary64 assignment preserves the exact polygonized output.

ResourceLimitError

If the bounded embedding search is exhausted.

See Also

Geometry.polygonize : Polygonize one geometry's own linework. GeometryArray.polygonize : Polygonize each array row independently. union_all : Union of many geometries into one. intersection_all : Common region shared by many geometries.

Examples:

>>> import gometry as gm
>>> edges = [
...     gm.LineString([(0, 0), (1, 0)]),
...     gm.LineString([(1, 0), (1, 1)]),
...     gm.LineString([(1, 1), (0, 0)]),
... ]
>>> gm.polygonize_all(edges).to_wkt()
['POLYGON ((0 0, 1 0, 1 1, 0 0))']
>>> result = gm.polygonize_all(edges, diagnostics=True)
>>> result.polygons.to_wkt()
['POLYGON ((0 0, 1 0, 1 1, 0 0))']

require

Accepted call forms
require(value: GeometryT, *, crs: CrsInput | None = None, axes: Literal['XY', 'XYZ', 'XYM', 'XYZM'] | None = None) -> GeometryT
require(value: GeometryArray[GeometryRowT], *, crs: CrsInput | None = None, axes: Literal['XY', 'XYZ', 'XYM', 'XYZM'] | None = None) -> GeometryArray[GeometryRowT]
require(value: Groups[GeometryArray[GeometryRowT]], *, crs: CrsInput | None = None, axes: Literal['XY', 'XYZ', 'XYM', 'XYZM'] | None = None) -> GeometryArray[GeometryRowT]
require(value: Groups[GeometryArray[GeometryRowT] | None], *, crs: CrsInput | None = None, axes: Literal['XY', 'XYZ', 'XYM', 'XYZM'] | None = None) -> GeometryArray[GeometryRowT]
require(value: str | Buffer | Mapping[str, Any] | SupportsGeoInterface, *, crs: CrsInput | None = None, axes: Literal['XY', 'XYZ', 'XYM', 'XYZM'] | None = None) -> Geometry
require(value: Iterable[GeometryRowT], *, crs: CrsInput | None = None, axes: Literal['XY', 'XYZ', 'XYM', 'XYZM'] | None = None) -> GeometryArray[GeometryRowT]
require(value: Iterable[Geometry | str | Buffer | Mapping[str, Any] | SupportsGeoInterface | None], *, crs: CrsInput | None = None, axes: Literal['XY', 'XYZ', 'XYM', 'XYZM'] | None = None) -> GeometryArray[Geometry | None]

Parse and require a geometry contract at an input boundary.

Parameters:

Name Type Description Default
value geometry-like or iterable of geometry-like

One geometry, a GeometryArray, a geometry-valued Groups, or an iterable. Foreign scalar inputs may be WKT, WKB, GeoJSON mappings/text, or __geo_interface__ objects. Geometry-valued groups are flattened in group order and return a GeometryArray.

required
crs CrsInput

Expected CRS for the result. CRS-free coordinates are stamped with this CRS; coordinates are never transformed. An existing CRS that is operationally equivalent is relabelled to this requested spelling, while a conflicting CRS raises CRSMismatchError. When omitted or None, no target is required and an existing CRS is preserved. Accepted forms include authority/WKT/PROJ strings, non-boolean integer-like EPSG codes, (authority, code) pairs, PROJJSON/CF mappings, objects exposing to_authority(), to_epsg(), to_wkt(), or to_json(), and objects whose crs or srs property contains another accepted form. Coordinate epochs are preserved and revalidated against the resulting CRS.

None
axes ('XY', 'XYZ', 'XYM', 'XYZM')

If given, require the geometry's coordinate axes to match exactly, otherwise raise.

'XY'

Returns:

Type Description
Geometry or GeometryArray

The validated input. Iterables return a GeometryArray.

Raises:

Type Description
CRSError

If crs is not a recognized CRS.

ParseError

If foreign GeoJSON is malformed, or its legacy crs member is unsupported or conflicts with crs (format is "geojson").

CRSMismatchError

If an already-decoded / native / non-GeoJSON geometry's CRS conflicts with crs. EWKT/EWKB embedded SRID conflicts use this error too.

InvalidGeometryError

If the geometry is invalid, or its axes differ from axes. Geographic validity uses exact quotient topology, so longitude aliases and seam cuts do not depend on stored spelling. Out-of-domain latitude is invalid. For quotient-topology issues, the location is a canonical coordinate of the issue's contact set, chosen deterministically by minimum latitude then longitude. Projected and CRS-free geometry remains planar.

See Also

Geometry.validate : Structured validity report. Geometry.repair : Fix the geometry.

Examples:

>>> import gometry as gm
>>> gm.require(gm.Point(1, 2, crs=4326), crs=4326).to_wkt()
'POINT (1 2)'

shared_paths

Accepted call forms
shared_paths(left: Geometry, right: Geometry) -> GeometryCollection
shared_paths(left: Geometry, right: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryT]) -> GeometryArray[GeometryCollection]
shared_paths(left: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryT], right: Geometry) -> GeometryArray[GeometryCollection]
shared_paths(left: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryT], right: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryOtherT]) -> GeometryArray[GeometryCollection]
shared_paths(left: Geometry, right: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryT | None]) -> GeometryArray[GeometryCollection | None]
shared_paths(left: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryT | None], right: Geometry) -> GeometryArray[GeometryCollection | None]
shared_paths(left: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryT | None], right: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryOtherT | None]) -> GeometryArray[GeometryCollection | None]
shared_paths(left: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None], right: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[Geometry | None]) -> GeometryCollection | GeometryArray[GeometryCollection | None]

Shared paths between two lineal geometries.

Parameters:

Name Type Description Default
left Geometry, GeometryArray, or iterable of Geometry or None

Two lineal operands. Scalar and sequence inputs broadcast pairwise; sequences must have equal length and compatible CRS/epoch frames.

required
right Geometry, GeometryArray, or iterable of Geometry or None

Two lineal operands. Scalar and sequence inputs broadcast pairwise; sequences must have equal length and compatible CRS/epoch frames.

required

Returns:

Type Description
Geometry or GeometryArray

The shared linework.

Raises:

Type Description
CRSMismatchError

If operands' CRS or coordinate-epoch metadata differ.

GeometryTypeError

If either operand is not lineal.

Examples:

>>> import gometry as gm
>>> gm.shared_paths(gm.LineString([(0, 0), (2, 0)]), gm.LineString([(1, 0), (3, 0)])).to_wkt()
'GEOMETRYCOLLECTION (MULTILINESTRING ((1 0, 2 0)), MULTILINESTRING EMPTY)'

snap

Accepted call forms
snap(geom: GeometryT, reference: Geometry, tolerance: float) -> GeometryT
snap(geom: MultiPoint, reference: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryOtherT], tolerance: FloatInput) -> GeometryArray[MultiPoint]
snap(geom: MultiPoint, reference: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryOtherT | None], tolerance: FloatInput) -> GeometryArray[MultiPoint | None]
snap(geom: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryT], reference: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryOtherT], tolerance: FloatInput) -> GeometryArray[GeometryT]
snap(geom: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryT | None], reference: Geometry | (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryOtherT | None], tolerance: FloatInput) -> GeometryArray[GeometryT | None]
snap(geom: GeometryT, reference: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryOtherT], tolerance: FloatInput) -> GeometryArray[GeometryT]
snap(geom: GeometryT, reference: (GeometryArray[GeometryRowT] | Iterable[GeometryRowT])[GeometryOtherT | None], tolerance: FloatInput) -> GeometryArray[GeometryT | None]
snap(geom: Geometry | GeometryArray[Geometry | None], reference: Geometry | GeometryArray[Geometry | None], tolerance: FloatInput) -> Geometry | GeometryArray[Geometry | None]

Snap vertices of geom onto reference within tolerance.

Each source vertex snaps independently to its nearest reference vertex at or below tolerance; if none is in range, it stays unchanged. An exact computed-distance tie goes to the reference vertex with the smaller X, then Y, using IEEE total order. Multiple source vertices may snap to the same reference vertex.

On each line segment, every reference vertex whose projection lies in the open segment, whose segment distance is at or below tolerance, and whose distance from both endpoints is greater than tolerance is inserted at its reference X/Y. Insertions follow segment order; equal projections are ordered by reference X/Y.

Snapped source vertices retain their own Z/M. Inserted geographic vertices keep the reference X/Y and use the source edge's ellipsoidal arclength at the exact projection parameter; Cartesian vertices interpolate along the source segment.

Consecutive line coordinates with identical X/Y are emitted once, keeping the first. If that leaves only one coordinate, the snapped start and end are retained as two endpoints, which may share X/Y. Closed rings are reclosed.

Snapping may collapse polygon rings: collapsed holes are dropped and a collapsed shell produces an empty polygon. Snapping does not validate or repair topology, so a snapped polygon may be invalid.

Parameters:

Name Type Description Default
geom Geometry, GeometryArray, or iterable of Geometry or None

Geometry whose vertices are moved. Missing rows remain missing.

required
reference Geometry, GeometryArray, or iterable of Geometry or None

Target geometry to snap onto.

required
tolerance float or sequence of float

Maximum finite non-negative snap distance in coordinate space: geographic CRSs use native angular units, projected CRSs use native linear units, and CRS-free geometries use raw coordinate units.

required

Returns:

Type Description
Geometry or GeometryArray

Snapped result(s), with missing rows preserved.

Raises:

Type Description
CRSMismatchError

If operands' CRS or coordinate-epoch metadata differ.

GeometryError

If tolerance is invalid.

Examples:

>>> import gometry as gm
>>> gm.snap(gm.Point(0.01, 0), gm.Point(0, 0), 0.1).to_wkt()
'POINT (0 0)'

split

Accepted call forms
split(geom: LineString | MultiLineString, splitter: Point | MultiPoint | GeometryArray[Point | MultiPoint | None], *, tolerance: float = 0.0) -> GeometryArray[LineString]
split(geom: GeometryArray[LineString | MultiLineString], splitter: Point | MultiPoint | GeometryArray[Point | MultiPoint], *, tolerance: float = 0.0) -> Groups[GeometryArray[LineString]]
split(geom: GeometryArray[LineString | MultiLineString | None], splitter: Point | MultiPoint | GeometryArray[Point | MultiPoint], *, tolerance: float = 0.0) -> Groups[GeometryArray[LineString] | None]
split(geom: GeometryArray[LineString | MultiLineString], splitter: GeometryArray[Point | MultiPoint | None], *, tolerance: float = 0.0) -> Groups[GeometryArray[LineString] | None]
split(geom: GeometryArray[LineString | MultiLineString | None], splitter: GeometryArray[Point | MultiPoint | None], *, tolerance: float = 0.0) -> Groups[GeometryArray[LineString] | None]
split(geom: Geometry, splitter: Geometry | GeometryArray[Geometry | None], *, tolerance: float = 0.0) -> GeometryArray[LineString]
split(geom: GeometryArray[Geometry], splitter: Geometry | GeometryArray[Geometry], *, tolerance: float = 0.0) -> Groups[GeometryArray[LineString]]
split(geom: GeometryArray[Geometry | None], splitter: Geometry | GeometryArray[Geometry | None], *, tolerance: float = 0.0) -> Groups[GeometryArray[LineString] | None]

Split lineal geometry by point splitter(s).

Each piece retains source vertices, including consecutive equal-X/Y vertices whose active Z/M ordinates differ. Inserted geographic Z/M ordinates follow the original source edge's ellipsoidal arclength.

Parameters:

Name Type Description Default
geom Geometry or GeometryArray

Lineal geometry to split.

required
splitter Geometry or GeometryArray

Point or multipoint cutter.

required
tolerance (float, keyword - only)

Coordinate-space distance within which a splitter point counts as on the line and near-equal cut offsets collapse: native angular units on geographic CRSs, native linear units on projected CRSs, and raw coordinate units when CRS-free. The default 0.0 is exact topological membership (a point splits only when it lies exactly on the linework) with identity deduplication.

0.0

Returns:

Type Description
GeometryArray or Groups[GeometryArray]

A scalar line returns all split parts in one GeometryArray, even when its cutter is an array of points. A line array returns one Groups row per source line; an array cutter is paired row by row. Missing line or cutter rows produce None groups; present rows with no split parts produce empty groups.

Raises:

Type Description
GeometryError

If tolerance is negative or non-finite.

CRSMismatchError

If operands' CRS or coordinate-epoch metadata differ.

GeometryTypeError

If geom is not lineal.

Examples:

>>> import gometry as gm
>>> gm.split(gm.LineString([(0, 0), (2, 0)]), gm.Point(1, 0)).to_wkt()
['LINESTRING (0 0, 1 0)', 'LINESTRING (1 0, 2 0)']
>>> pieces = gm.split(gm.GeometryArray([gm.LineString([(0, 0), (2, 0)])]), gm.Point(1, 0))
>>> pieces.offsets.tolist()
[0, 2]