Metadata-Version: 2.4
Name: topology-checker
Version: 0.1.0
Classifier: Development Status :: 4 - Beta
Classifier: Topic :: Scientific/Engineering :: GIS
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Rust
Classifier: Typing :: Typed
Requires-Dist: shapely>=2,<3
Requires-Dist: pyproj>=3.4,<4
Requires-Dist: geopandas>=0.14,<2 ; extra == 'geopandas'
Provides-Extra: geopandas
License-File: LICENSE
License-File: THIRD-PARTY-NOTICES.txt
Summary: Native planar topology validation with typed Python rules and Shapely geometries
Keywords: GIS,topology,validation,geospatial,shapely,geopandas
Author: Alex-Andrei Cuvuliuc
License-Expression: Apache-2.0 AND Apache-2.0 WITH LLVM-exception AND MIT AND Unicode-DFS-2016
Requires-Python: >=3.10
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Documentation, https://alecsandrei.github.io/topology-checker/
Project-URL: Issues, https://github.com/alecsandrei/topology-checker/issues
Project-URL: Repository, https://github.com/alecsandrei/topology-checker

Validate planar GIS data with 24 typed constraints powered by 38 native Rust rules.

```sh
uv add 'topology-checker[geopandas]'
```

```python
import geopandas as gpd
from topology_checker import Rule, Topology

roads_gdf = gpd.read_file("roads.gpkg")
topology = Topology(tolerance=0.001)
topology.add_rule(Rule.MUST_NOT_HAVE_DANGLES, roads_gdf)
buildings_gdf = gpd.read_file("buildings.gpkg")
topology.add_rule(Rule.MUST_NOT_OVERLAP, roads_gdf, other=buildings_gdf)
report = topology.validate()
errors = report.to_geodataframe()
```

```python
from shapely.geometry import Point, box
from topology_checker import GeometryKind, Rule, Topology

topology = Topology()
points = topology.add_layer([Point(0.5, 0.5)], fids=[42], crs="EPSG:28992")
areas = topology.add_layer([box(0, 0, 1, 1)], name="parcels", crs="EPSG:28992")
topology.add_rule(Rule.MUST_BE_INSIDE, points, other=areas)
report = topology.validate()
print(report.is_valid, report.error_count, report.warnings)
print(report.to_dict())
print(topology.layer(points).name)
print(report.rules[0].resolved_rule.description)
empty_lines = topology.add_layer([], kind=GeometryKind.LINE)
topology.add_rule(Rule.MUST_NOT_HAVE_DANGLES, empty_lines)
```

```python
from shapely.geometry import LineString
from topology_checker import explode_lines, merge_lines

lines = [LineString([(0, 0), (1, 0)]), LineString([(1, 0), (2, 0)])]
merged = merge_lines(lines, tolerance=0.001)
segments = explode_lines(merged)
```

