Metadata-Version: 2.4
Name: polymetrics
Version: 0.2.1
Summary: Fast object-level (polygon) metrics for geospatial ML: precision, recall, F1, IoU, mAP, shape stats.
Keywords: geospatial,metrics,polygon,iou,map,object-detection,segmentation
Author: Kshitij Raj Sharma
Author-email: Kshitij Raj Sharma <krschap@duck.com>
License-Expression: Apache-2.0
License-File: LICENSE
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
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: Topic :: Scientific/Engineering :: GIS
Classifier: Typing :: Typed
Requires-Dist: geopandas>=1.0
Requires-Dist: scipy>=1.10
Requires-Python: >=3.11
Project-URL: Homepage, https://github.com/kshitijrajsharma/polymetrics
Project-URL: Repository, https://github.com/kshitijrajsharma/polymetrics
Project-URL: Issues, https://github.com/kshitijrajsharma/polymetrics/issues
Project-URL: Changelog, https://github.com/kshitijrajsharma/polymetrics/blob/main/CHANGELOG.md
Description-Content-Type: text/markdown

# polymetrics

Fast object-level (polygon) accuracy metrics for geospatial ML. Compare two GeoJSONs and get precision, recall, F1, IoU, mAP, and polygon-shape statistics in one call.

```bash
uvx polymetrics truth.geojson pred.geojson
```

```python
from polymetrics import evaluate

result = evaluate("truth.geojson", "pred.geojson", iou_threshold=0.5)
print(result.precision, result.recall, result.f1, result.mean_iou)
result.to_geojson("annotated.geojson")
```

## What it computes

| Metric | Definition |
|---|---|
| `precision`, `recall`, `f1` | Standard object-level scores after one-to-one Hungarian matching on IoU |
| `mean_iou` | Mean IoU across matched (TP) pairs |
| `map_50` | Mean Average Precision at IoU=0.5, 101-point AP integration (COCO-style) |
| `map_50_95` | Mean of mAP at IoU thresholds 0.5, 0.55, ..., 0.95 |
| `avg_vertices` | Mean exterior vertex count across predicted polygons |
| `orthogonality` | Mean fraction of edges within 5° of each polygon's MBR dominant axis |

## How it differs from pixel metrics

Pixel IoU pools every pixel and asks "what fraction did you get right?". Object IoU asks "did you find each building, and how well-shaped is each one?" which is what users actually see on a map. Both are useful for different reasons; this library only does object-level.

## CRS handling

Inputs are always reprojected to **EPSG:3857** before any geometric computation. If the prediction and truth GeoJSONs declare different source CRSs, a warning is emitted and both are projected. A missing CRS is treated as EPSG:4326 (the GeoJSON 2008 default).

## Matching algorithm

Hungarian bipartite assignment (`scipy.optimize.linear_sum_assignment`) on a `-IoU` cost matrix, with `gdf.sindex` (STRtree) pruning to skip non-overlapping pairs. Each prediction matches at most one truth; pairs below `iou_threshold` are dropped (the prediction becomes FP, the truth FN).

## mAP

mAP requires each prediction feature to carry a `score` or `confidence` property in `[0, 1]`. If neither is present, mAP is reported as `null` and a warning is emitted; the other metrics still compute.

## Install

```bash
uv pip install polymetrics
```

## CLI

```text
polymetrics truth.geojson pred.geojson [options]

positional arguments:
  truth                 ground-truth GeoJSON
  pred                  prediction GeoJSON

options:
  --iou FLOAT           IoU threshold for TP (default: 0.5)
  --no-map              skip mAP computation
  --out PATH            write annotated GeoJSON (TP/FP/FN per feature)
  --json                emit metrics as JSON on stdout
```

## License

Apache-2.0.
