Skip to content

Python API

Native planar topology checks for Python GIS workflows.

Topology

Topology(tolerance: float = 0.0)

Own planar layers, ordered rules, and reusable native topology caches.

Parameters:

Name Type Description Default
tolerance float

Nonnegative finite distance in input coordinate units.

0.0

Raises:

Type Description
ValueError

Tolerance is negative or nonfinite.

tolerance property

tolerance: float

Return the planar tolerance in caller-supplied coordinate units.

layers property

layers: tuple[Layer, ...]

Return immutable layer snapshots in registration order.

layer

layer(id: LayerId) -> Layer

Return a registered layer, rejecting IDs from other topologies.

add_layer

add_layer(data: Any, *, name: str | None = None, fids: Iterable[int] | None = None, crs: Any = None, kind: GeometryKind | None = None) -> LayerId

Snapshot and register GIS data as a planar layer.

Parameters:

Name Type Description Default
data Any

Geometry iterable, GeoSeries, GeoDataFrame, GeoJSON mapping, or object implementing geo_interface.

required
name str | None

Optional display label. Defaults to layer_N using registration order.

None
fids Iterable[int] | None

Unique signed 64-bit IDs for all original input positions.

None
crs Any

Optional CRS, which must agree with input and known layer metadata.

None
kind GeometryKind | None

Optional POINT, LINE, or POLYGON declaration for ambiguous data.

None

Returns:

Type Description
LayerId

An identity scoped to this topology.

Raises:

Type Description
TypeError

Input data, the name, or the declaration has an unsupported type.

ValueError

Coordinates, FIDs, geometry, or CRS metadata are invalid.

RuntimeError

An input callback tries to register on this topology.

add_rule

add_rule(rule: Rule, data: Any, *, other: Any = None) -> RuleSpec

Snapshot raw GIS inputs or reuse IDs, then atomically register a rule.

Each raw input creates a fresh snapshot. Pass a LayerId to reuse a layer.

Parameters:

Name Type Description Default
rule Rule

Rule member. Deserialize strings explicitly with Rule(value).

required
data Any

Primary GIS input or a LayerId from this topology.

required
other Any

Optional secondary GIS input or distinct registered LayerId.

None

Returns:

Type Description
RuleSpec

The immutable specification, including reusable IDs and native semantics.

Raises:

Type Description
TypeError

The rule or input has an unsupported type.

ValueError

IDs, families, arity, coordinates, FIDs, or CRS are invalid. Failed calls leave registrations and visible warnings unchanged.

RuntimeError

An input callback tries to register on this topology.

warnings

warnings() -> tuple[str, ...]

Return input, degenerate-part, and combined CRS warnings.

validate

validate() -> Report

Run Rust validation with the GIL released and return a typed snapshot.

Returns:

Type Description
Report

A report whose violations are data, including when rules fail.

Raises:

Type Description
RuntimeError

An unexpected native failure prevents validation.

ErrorType

Bases: Enum

Deterministically ordered topology violation categories.

OVERLAP class-attribute instance-attribute

OVERLAP = 'overlap'

OUTSIDE class-attribute instance-attribute

OUTSIDE = 'outside'

DANGLE class-attribute instance-attribute

DANGLE = 'dangle'

PSEUDO_NODE class-attribute instance-attribute

PSEUDO_NODE = 'pseudo-node'

CROSSING class-attribute instance-attribute

CROSSING = 'crossing'

TOUCH_INTERIOR class-attribute instance-attribute

TOUCH_INTERIOR = 'touch-interior'

SELF_OVERLAP class-attribute instance-attribute

SELF_OVERLAP = 'self-overlap'

SELF_CROSSING class-attribute instance-attribute

SELF_CROSSING = 'self-crossing'

GAP class-attribute instance-attribute

GAP = 'gap'

OUTER_BOUNDARY class-attribute instance-attribute

OUTER_BOUNDARY = 'outer-boundary'

MULTIPART class-attribute instance-attribute

MULTIPART = 'multipart'

NOT_COVERED class-attribute instance-attribute

NOT_COVERED = 'not-covered'

MISSING_POINT class-attribute instance-attribute

MISSING_POINT = 'missing-point'

POINT_COUNT class-attribute instance-attribute

POINT_COUNT = 'point-count'

CONTAINED class-attribute instance-attribute

CONTAINED = 'contained'

INTERSECTION class-attribute instance-attribute

INTERSECTION = 'intersection'

GeometryKind

Bases: Enum

Geometry families accepted by a rule.

POINT class-attribute instance-attribute

POINT = 'point'

LINE class-attribute instance-attribute

LINE = 'line'

POLYGON class-attribute instance-attribute

POLYGON = 'polygon'

COLLECTION class-attribute instance-attribute

COLLECTION = 'collection'

ANY class-attribute instance-attribute

ANY = 'any'

Rule

Bases: Enum

Geometry-independent rules in first-occurrence Rust registry order.

MUST_NOT_OVERLAP class-attribute instance-attribute

MUST_NOT_OVERLAP = 'must-not-overlap'

MUST_BE_INSIDE class-attribute instance-attribute

MUST_BE_INSIDE = 'must-be-inside'

MUST_NOT_HAVE_DANGLES class-attribute instance-attribute

MUST_NOT_HAVE_DANGLES = 'must-not-have-dangles'

MUST_NOT_HAVE_PSEUDO_NODES class-attribute instance-attribute

MUST_NOT_HAVE_PSEUDO_NODES = 'must-not-have-pseudo-nodes'

MUST_NOT_SELF_OVERLAP class-attribute instance-attribute

MUST_NOT_SELF_OVERLAP = 'must-not-self-overlap'

MUST_NOT_INTERSECT class-attribute instance-attribute

MUST_NOT_INTERSECT = 'must-not-intersect'

MUST_NOT_INTERSECT_OR_TOUCH_INTERIOR class-attribute instance-attribute

MUST_NOT_INTERSECT_OR_TOUCH_INTERIOR = 'must-not-intersect-or-touch-interior'

MUST_NOT_SELF_INTERSECT class-attribute instance-attribute

MUST_NOT_SELF_INTERSECT = 'must-not-self-intersect'

MUST_NOT_HAVE_GAPS class-attribute instance-attribute

MUST_NOT_HAVE_GAPS = 'must-not-have-gaps'

MUST_NOT_BE_MULTIPART class-attribute instance-attribute

MUST_NOT_BE_MULTIPART = 'must-not-be-multipart'

MUST_BE_COVERED_BY class-attribute instance-attribute

MUST_BE_COVERED_BY = 'must-be-covered-by'

MUST_BE_COVERED_BY_ENDPOINTS class-attribute instance-attribute

MUST_BE_COVERED_BY_ENDPOINTS = 'must-be-covered-by-endpoints'

MUST_BE_COVERED_BY_BOUNDARIES class-attribute instance-attribute

MUST_BE_COVERED_BY_BOUNDARIES = 'must-be-covered-by-boundaries'

ENDPOINTS_MUST_BE_COVERED_BY class-attribute instance-attribute

ENDPOINTS_MUST_BE_COVERED_BY = 'endpoints-must-be-covered-by'

BOUNDARIES_MUST_BE_COVERED_BY class-attribute instance-attribute

BOUNDARIES_MUST_BE_COVERED_BY = 'boundaries-must-be-covered-by'

MUST_CONTAIN class-attribute instance-attribute

MUST_CONTAIN = 'must-contain'

MUST_CONTAIN_ONE class-attribute instance-attribute

MUST_CONTAIN_ONE = 'must-contain-one'

MUST_NOT_CROSS_BOUNDARIES class-attribute instance-attribute

MUST_NOT_CROSS_BOUNDARIES = 'must-not-cross-boundaries'

MUST_NOT_BE_CONTAINED_BY class-attribute instance-attribute

MUST_NOT_BE_CONTAINED_BY = 'must-not-be-contained-by'

MUST_NOT_BE_INSIDE class-attribute instance-attribute

MUST_NOT_BE_INSIDE = 'must-not-be-inside'

MUST_BE_PROPERLY_INSIDE class-attribute instance-attribute

MUST_BE_PROPERLY_INSIDE = 'must-be-properly-inside'

MUST_NOT_OVERLAP_BOUNDARIES class-attribute instance-attribute

MUST_NOT_OVERLAP_BOUNDARIES = 'must-not-overlap-boundaries'

ENDPOINTS_MUST_BE_COVERED_BY_BOUNDARIES class-attribute instance-attribute

ENDPOINTS_MUST_BE_COVERED_BY_BOUNDARIES = 'endpoints-must-be-covered-by-boundaries'

MUST_NOT_CONTAIN class-attribute instance-attribute

MUST_NOT_CONTAIN = 'must-not-contain'

description property

description: str

Return a geometry-independent description of this constraint.

variants property

variants: tuple[RuleVariant, ...]

Return concrete semantics in Rust registry order.

RuleVariant dataclass

RuleVariant(value: str, inputs: tuple[GeometryKind, GeometryKind | None], description: str, arcgis: str | None, qgis: str | None)

Canonical Rust rule semantics and ordered input families.

value instance-attribute

value: str

inputs instance-attribute

inputs: tuple[GeometryKind, GeometryKind | None]

description instance-attribute

description: str

arcgis instance-attribute

arcgis: str | None

qgis instance-attribute

qgis: str | None

FeatureRef dataclass

FeatureRef(layer: LayerId, fid: int, part: int | None)

Original feature and depth-first part position in a registered layer.

layer instance-attribute

layer: LayerId

fid instance-attribute

fid: int

part instance-attribute

part: int | None

to_dict

to_dict() -> dict[str, int | None]

Serialize a reference using its registration index.

Layer dataclass

Layer(id: LayerId, name: str, fids: tuple[int, ...], geometries: tuple[BaseGeometry, ...], crs: CRS | None, _parts: Mapping[int, tuple[int, ...]], warnings: tuple[str, ...], kind: GeometryKind | None)

Immutable XY snapshot of retained features and layer metadata.

The kind is a concrete retained family, COLLECTION for mixed families, or None when unknown. Empty inputs can retain a typed hint or an explicit kind.

id instance-attribute

id: LayerId

name instance-attribute

name: str

fids instance-attribute

fids: tuple[int, ...]

geometries instance-attribute

geometries: tuple[BaseGeometry, ...]

crs instance-attribute

crs: CRS | None

warnings class-attribute instance-attribute

warnings: tuple[str, ...] = field(repr=False)

kind instance-attribute

kind: GeometryKind | None

reference

reference(fid: int, part: int | None) -> FeatureRef

Map a native part index to original feature provenance.

LayerId dataclass

LayerId()

Opaque identity scoped to the Topology that registered a layer.

index property

index: int

Return the zero-based registration index.

belongs_to

belongs_to(owner: object) -> bool

Check the internal topology identity token.

Report dataclass

Report(tolerance: float, warnings: tuple[str, ...], rules: tuple[RuleReport, ...], crs: CRS | None)

A validation snapshot, independent of subsequent registrations.

tolerance instance-attribute

tolerance: float

warnings instance-attribute

warnings: tuple[str, ...]

rules instance-attribute

rules: tuple[RuleReport, ...]

crs instance-attribute

crs: CRS | None

violations property

violations: tuple[Violation, ...]

Flatten violations in rule order and native deterministic order.

errors property

errors: tuple[Violation, ...]

Return flattened violations, matching Rust's report terminology.

is_valid property

is_valid: bool

Return whether every registered rule passed.

error_count property

error_count: int

Return the total number of aggregated violations.

to_dict

to_dict() -> dict[str, Any]

Return JSON-compatible metadata, GeoJSON geometries, and enum values.

to_geodataframe

to_geodataframe() -> GeoDataFrame

Export one row per violation, with scalar provenance columns.

Returns:

Type Description
GeoDataFrame

A GeoDataFrame retaining a common known CRS, including for no errors.

Raises:

Type Description
ImportError

The optional GeoPandas dependency is unavailable.

RuleReport dataclass

RuleReport(rule: Rule, layer: LayerId, other: LayerId | None, layer_name: str, other_name: str | None, counts: Mapping[ErrorType, int], violations: tuple[Violation, ...], spec: RuleSpec)

One registered rule's ordered violations and category counts.

rule instance-attribute

rule: Rule

layer instance-attribute

layer: LayerId

other instance-attribute

other: LayerId | None

layer_name instance-attribute

layer_name: str

other_name instance-attribute

other_name: str | None

counts instance-attribute

counts: Mapping[ErrorType, int]

violations instance-attribute

violations: tuple[Violation, ...]

spec instance-attribute

spec: RuleSpec

resolved_rule property

resolved_rule: RuleVariant

Return the concrete rule selected during registration.

errors property

errors: tuple[Violation, ...]

Return the violations, matching Rust's report terminology.

is_valid property

is_valid: bool

Return whether this rule reported no violations.

error_count property

error_count: int

Return the number of aggregated violations.

to_dict

to_dict() -> dict[str, Any]

Serialize this ordered rule result.

RuleSpec dataclass

RuleSpec(rule: Rule, layer: LayerId, other: LayerId | None, resolved_rule: RuleVariant)

A registered generic constraint and its selected native semantics.

rule instance-attribute

rule: Rule

layer instance-attribute

layer: LayerId

other instance-attribute

other: LayerId | None

resolved_rule instance-attribute

resolved_rule: RuleVariant

Violation dataclass

Violation(rule: Rule, error_type: ErrorType, geometry: BaseGeometry, origin: FeatureRef | None, destination: FeatureRef | None, resolved_rule: RuleVariant)

A topology violation with Shapely geometry and original provenance.

rule instance-attribute

rule: Rule

error_type instance-attribute

error_type: ErrorType

geometry instance-attribute

geometry: BaseGeometry

origin instance-attribute

origin: FeatureRef | None

destination instance-attribute

destination: FeatureRef | None

resolved_rule instance-attribute

resolved_rule: RuleVariant

to_dict

to_dict() -> dict[str, Any]

Serialize enums as values and geometry as a GeoJSON mapping.

explode_lines

explode_lines(data: Any) -> tuple[LineString, ...]

Return native line segments preserving input part order and direction.

Parameters:

Name Type Description Default
data Any

Any supported layer input containing only line geometries.

required

Returns:

Type Description
tuple[LineString, ...]

Shapely LineStrings, with degenerate parts skipped.

merge_lines

merge_lines(data: Any, tolerance: float = 0.0) -> tuple[LineString, ...]

Merge line parts through degree-two endpoint joins in native Rust.

Parameters:

Name Type Description Default
data Any

Any supported layer input containing only line geometries.

required
tolerance float

Nonnegative finite distance in planar coordinate units.

0.0

Returns:

Type Description
tuple[LineString, ...]

Shapely LineStrings in deterministic contributing-part order.