Skip to main content

GridForge

CI Python 3.11+ License: Apache-2.0

GridForge is a Python toolkit and CLI for building canonical spatial grids and aligning point, polygon, and raster data to them. It produces complete, deterministic grid feature datasets that can be joined, validated, and traced back to the spatial transformation settings.

Ordinary spatial joins answer questions such as which features intersect a geometry. They do not by themselves define stable cell IDs, edge behavior, coverage calculations, raster resampling, missing-cell policy, or whether two outputs use the same grid. GridForge makes those choices explicit.

GridForge was extracted from spatial data engineering patterns developed for real-world digital-twin and environmental data pipelines. It is independent of those systems and does not depend on their schemas or private data.

Install

The PyPI distribution is named gridforge-spatial because gridforge is already used by an unrelated package. The Python import and executable remain gridforge.

python -m pip install gridforge-spatial
gridforge --help

For development, install the project and its tools with uv:

uv sync --all-groups
uv run gridforge --help

Quick start

Run the bundled synthetic workflow to build a 4 × 4 grid, align points, polygons, and a raster, join their features, and validate the result:

gridforge demo --output-dir ./gridforge-demo

The demo writes only synthetic files under the requested directory. It completes locally without downloads or project-specific inputs. Expected uncovered cells and point nodata are reported as warnings; validation exits with status 0 unless it finds an error.

Canonical grids

A canonical grid is a fixed-origin set of square cells with one projected CRS, one cell size, stable row and column indices, and a stable identity. Create a YAML specification:

crs: EPSG:3857
cell_size: 20
bounds:
  min_x: 0
  min_y: 0
  max_x: 80
  max_y: 80
origin:
  x: 0
  y: 80

The origin is the top-left cell corner; columns increase east and rows increase south. Bounds include cells with positive-area overlap and expand outward to cell boundaries. Coordinates and cell size use the units of the projected CRS. Geographic CRSs are rejected for canonical grids.

Cell IDs are stable row:column pairs, including negative indices when the grid extends west or south of its origin. Grid rows are ordered by row and then column. Grid fingerprints identify the normalized CRS, cell size, origin, and covered index extent, so different requested bounds that resolve to the same cells have the same logical grid identity.

Point assignment uses cells [left, right) × (bottom, top]: a point on a shared vertical edge belongs to the cell to its east, and a point on a shared horizontal edge belongs to the cell to its south. Coordinates within the configured boundary_tolerance (default 1e-9 CRS units) of a grid line snap to that line before assignment.

Build and save the grid as GeoParquet:

gridforge grid create grid.yaml --output grid.parquet

GridForge writes the cell geometry, row and column, grid ID, fingerprint, CRS, and specification. It also writes a grid.parquet.gridforge.json spatial provenance sidecar.

Inspect inputs and CRS rules

inspect reads vector files, GeoParquet, CSV or Parquet coordinate tables, and raster files without guessing a CRS:

gridforge inspect stations.csv --source-crs EPSG:3826 --json
gridforge inspect landuse.geojson
gridforge inspect dem.tif

CSV and ordinary Parquet tables need explicit --source-crs; use --x-column and --y-column if their coordinate fields are not named x and y. Vector and raster files use embedded CRS metadata when available. If a file has no CRS, pass --source-crs; if an explicit CRS conflicts with embedded metadata, GridForge returns an error. It never silently assumes WGS84.

Align points

For each point, GridForge reprojects into the grid CRS, assigns the point to a containing cell, and aggregates requested columns. Supported operations are count, sum, mean, min, and max:

gridforge align points stations.csv \
  --grid grid.parquet \
  --source-crs EPSG:3826 \
  --value rainfall_mm \
  --agg mean \
  --output rainfall.parquet

The output keeps every grid cell. point_count is zero in empty cells; empty numeric aggregates remain null. A count aggregation counts non-null values in the selected column.

Align polygons

Polygon and MultiPolygon features are reprojected to the grid CRS and intersected with cells. The output includes polygon_count and polygon_coverage_ratio; coverage is the union of intersected area divided by cell area, so overlapping polygons cannot inflate total coverage above one. Category coverage is calculated as a separate union for each category, so ratios across different categories may sum above one when categories overlap. Dominant category ties are resolved by normalized category name in lexical order. Numeric attributes use an intersection-area weighted mean over features with non-null values.

gridforge align vector landuse.geojson \
  --grid grid.parquet \
  --category landuse \
  --numeric-column impervious_fraction \
  --output landuse.parquet

Use repeated --numeric-column options for multiple numeric fields. To produce coverage only, omit --category and --numeric-column.

Align rasters

Raster alignment first warps the selected band into the grid CRS, then aggregates valid pixels in each canonical cell using mean, min, or max. Reprojection resampling defaults to nearest; choose bilinear or cubic explicitly when appropriate. Nodata and cells outside the raster footprint remain null.

gridforge align raster dem.tif \
  --grid grid.parquet \
  --agg mean \
  --resampling bilinear \
  --output elevation.parquet

The aggregation maps to Rasterio's average, min, or max resampler. Reprojection resampling and cell aggregation are distinct operations and both are recorded in the output metadata and provenance sidecar.

Join and validate

Join one or more GridForge-aligned GeoParquet datasets after checking grid fingerprint, CRS, cell geometry, complete cell coverage, and duplicate feature names:

gridforge join grid.parquet rainfall.parquet landuse.parquet elevation.parquet \
  --output features.parquet

Validate an output against its canonical grid. JSON output is suitable for CI scripts:

gridforge validate features.parquet --grid grid.parquet --json

Validation reports PASS, WARNING, or ERROR. Null or nodata feature values are warnings; structural problems, invalid geometry, mismatched grid identity, impossible coverage ratios, and infinite numeric values are errors. The command exits 0 for PASS or WARNING and 2 for ERROR, making it usable as a CI gate.

Python API

The same operations are available without invoking the CLI:

from gridforge.align.points import align_points
from gridforge.align.raster import align_raster
from gridforge.align.vector import align_polygons
from gridforge.grid import GridSpec, create_grid
from gridforge.io.datasets import load_points, load_vector, read_dataset, write_dataset
from gridforge.io.grid import read_grid, write_grid
from gridforge.join import join_features
from gridforge.validation import validate_dataset

spec = GridSpec.from_yaml("grid.yaml")
grid = create_grid(spec)
write_grid(grid, "grid.parquet")

points = load_points("stations.csv", source_crs="EPSG:3826")
polygons = load_vector("landuse.geojson")
rain = align_points(points, grid, aggregations={"rainfall_mm": "mean"})
land = align_polygons(polygons, grid, category_column="landuse")
dem = align_raster("dem.tif", grid, aggregation="mean", resampling="bilinear")

features = join_features(grid, rain, land, dem)
report = validate_dataset(features, grid=grid)
write_dataset(features, "features.parquet")
assert report.exit_code == 0, report.to_dict()
reloaded = read_dataset("features.parquet")

GridSpec.from_mapping(...) is also available when the specification comes from a Python dictionary. Input loaders and aligners accept source_crs only when needed; an embedded CRS is checked rather than overwritten.

GIS libraries and boundaries

GridForge uses GeoPandas and PyArrow for vector and GeoParquet I/O, Shapely for geometry operations, PyProj for CRS interpretation and transformation, Rasterio for raster warping and nodata handling, and NumPy and Pandas for data operations. Those libraries provide the underlying GIS primitives; GridForge defines canonical grid identity, boundary rules, aggregation behavior, validation, and transformation metadata.

For Taiwan-specific coordinate and address convenience functions, see TaiGeotrans. GridForge can consume data prepared with it, but does not depend on it or include country-specific CRS helpers in its core.

GridForge does not provide map rendering, a server, an ETL scheduler, a machine-learning framework, or country-specific CRS transformation helpers. Its provenance sidecars capture spatial transformation settings and output identity; full dataset lineage and artifact release integrity belong in dedicated tools.

License

GridForge is licensed under Apache-2.0. See LICENSE.

Metadata

Release files for gridforge-spatial 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gridforge-spatial 0.1.0
File Size Uploaded
gridforge_spatial-0.1.0.tar.gz 102.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gridforge-spatial 0.1.0
File Interpreter ABI Platform
gridforge_spatial-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 139.7 kB

Release files / gridforge_spatial-0.1.0.tar.gz

Download URL gridforge_spatial-0.1.0.tar.gz
Size 102.0 kB
Tags Source
SHA-256 checksum
How to use checksums
48e56f9d42d6ca4d16abc33ab71c52bd82e761354944e1c8e506efb5c38760e1
BLAKE2b-256 checksum
How to use checksums
4f7c8d5a602c74d4c7caef3f5fdf0273d5dfb38f1625f85828283d3b3d569c18
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release files / gridforge_spatial-0.1.0-py3-none-any.whl

Download URL gridforge_spatial-0.1.0-py3-none-any.whl
Size 37.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dacbb4f1657d743157f8c9e1d37ab09d4287e6dd41e417adc22f88e639e14f92
BLAKE2b-256 checksum
How to use checksums
c0ccece9405b42d87852e14b3a34c45f51925e195cbc98d577d4d3bf1e7b4fec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page