Metadata-Version: 2.4
Name: fastpgv
Version: 0.1.0
Summary: Weighted polygon-to-grid aggregation with the native SLED algorithm
Keywords: polygon,raster,geospatial,SLED,aggregation
Author: SLED contributors
License-Expression: MIT
License-File: LICENSE
License-File: THIRD_PARTY_NOTICES.md
License-File: licenses/pybind11-LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
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 :: C++
Classifier: Topic :: Scientific/Engineering :: GIS
Requires-Python: >=3.10
Requires-Dist: numpy>=1.23
Provides-Extra: test
Requires-Dist: pytest>=8; extra == "test"
Requires-Dist: shapely>=2; extra == "test"
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: shapely>=2; extra == "dev"
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: twine>=6; extra == "dev"
Description-Content-Type: text/markdown

# fastpgv

**fastpgv** is a lightweight Python wrapper for fast density computation for Polygon-to-Grid Visualization (PGV).

This package provides an efficient way to compute density results through a simple Python interface.
Compute a density value for every pixel from weighted polygons using the C++17 SLED (Sweep-Line Edge-Difference Aggregation) algorithm.

## Features

- One Python interface: `fastpgv.run(weighted_polygons, resolution)`.
- Weighted polygons with explicit vertex coordinates.
- The polygons should be non-overlapping.
- C++ computation backend with the Python interface.

## Installation

From the `fastpgv/` source directory:

```bash
python -m pip install .
```

After version 0.1.0 is successfully published to production PyPI:

```bash
python -m pip install fastpgv==0.1.0
```

Publication is pending. The prepared wheel is for CPython 3.12 on macOS 11+
Apple Silicon (arm64). Other environments need to build the source distribution
with a C++17 compiler. Cross-platform wheels are not included in this release.

## Requirements

- Python 3.10 or newer.
- NumPy, installed automatically by pip.
- A C++17 compiler for source builds. pip installs the Python build dependencies.

Java, DuckDB, APRIL, Boost, and the original benchmark repository are not required.

## Quick Example

```python
import fastpgv

# Polygons contain ordered vertex coordinates, not just identifiers.
polygon_a = {
    "type": "Polygon",
    "coordinates": [[[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]],
}
polygon_b = {
    "type": "Polygon",
    "coordinates": [[[1, 0], [2, 0], [2, 1], [1, 1], [1, 0]]],
}

density = fastpgv.run(
    [(polygon_a, 2.0), (polygon_b, 3.0)],
    resolution=(2, 1),
)
print(density)
# [[2. 3.]]
```

## Inputs and Output

Both arguments are required:

| Argument | Meaning |
|---|---|
| `weighted_polygons` | Nonempty iterable of `(geometry, weight)` pairs |
| `resolution` | Positive integer `(X, Y)`: columns and rows |

Geometry must contain ordered vertices as a GeoJSON `Polygon` or `MultiPolygon`
dictionary, or expose `__geo_interface__` (for example, a Shapely polygon).
Consecutive vertices define edges automatically; open rings are closed internally.
No separate edge input is required or accepted. The first ring is the exterior;
additional rings are holes. MultiPolygon components share one weight.

Weights must be explicit finite numbers. Negative and zero weights are supported.
The supported use case is non-overlapping polygonal inputs: interiors must not
overlap, but shared edges and vertices are allowed. Overlaps are not automatically
checked; validate this requirement before calling `run`.
The grid covers the combined minimum
bounding rectangle of **all** supplied geometries, including zero-weight ones.

`run` returns a `numpy.ndarray` directly, with dtype `float64` and shape `(Y, X)`.
`density[v, u]` is the value of the pixel in row `v` and column `u`. Row zero is
the top row at `y_max`; columns run from `x_min` to `x_max`.

The function returns data directly; it does not write files or render a visualization.

## Notes

- Each pixel value is the sum of `weight * polygon_pixel_intersection_area`:
  **weighted area, not area-normalized density**.
- Coordinates are planar, with no CRS transformation or geodesic calculation.
  Project geographic coordinates first when metric areas are required.
- Supply valid polygon topology. Ring orientation is corrected, but invalid
  holes and self-intersections are not repaired. Empty input is rejected.
- Numerical tests use absolute tolerance `1e-9` or relative tolerance `1e-12`.
  Floating-point results can differ across platforms; extreme coordinates or
  weights may require rescaling and application-specific error analysis.
- The complete output array requires `8 * X * Y` bytes, plus polygon-edge and
  working storage. Choose a resolution that fits available memory.

## License and Further Information

MIT licensed, by **SLED contributors**.

The source archive includes `PUBLISHING.md` (build and upload instructions),
`PORTING.md` (implementation provenance), and `THIRD_PARTY_NOTICES.md`
(dependency notices).
