Typed GIS quality-control toolkit for Python
Project description
GeoQC
GeoQC is a typed Python toolkit for quality control of geospatial data. It detects common geometry defects and provides reusable building blocks for CRS, datum, axis-order, attribute, batch, and reporting workflows.
Release status:
0.1.0(alpha). The top-levelvalidate_geometry()API is ready for evaluation. Advanced APIs may evolve before1.0and changes will be documented in the changelog.
Two ways to use GeoQC
GeoQC exposes one validation engine through several surfaces, so results are identical no matter how you call it:
- Developers install the package (
pip install geoqc) and use the Python API or thegeoqcCLI. - Everyone else runs the bundled web app (
apps/web) in a browser. It uploads datasets to the FastAPI backend, which validates them with the samegeoqcengine — no validation logic is reimplemented in JavaScript. See API and deployment to run the backend and client locally.
Because the web API, CLI, and Python API all call
ShapelyGeometryValidator through the same audit engine, the Website, CLI, and
library always agree on what is valid. See Architecture.
Features
- Validate Shapely geometries for empty or invalid values, self-intersections, ring errors, and duplicate vertices.
- Repair topology with minimal shape change — self-intersections, invalid rings, duplicate vertices, slivers, overlaps, and enclosed gaps — with before/after geometry, a repair report, and preview/apply/undo. See intelligent topology repair.
- Read common vector datasets through GeoPandas and Pyogrio, including Shapefile, GeoJSON, GeoPackage, and FlatGeobuf.
- Stream GeoPackage, Shapefile, GeoJSON, and GeoParquet audits in bounded Arrow chunks without loading the complete dataset into RAM.
- Audit independent datasets concurrently with memory-aware process scheduling, isolated failures, and deterministic output ordering.
- Inspect CRS consistency, axis order, and possible datum shifts.
- Run typed, extensible quality rules with immutable result models.
- Process bounded batches and generate optional HTML or interactive reports.
- Expose a hardened FastAPI upload endpoint and a responsive React client.
GeoQC does not repair or silently modify source datasets.
Requirements
- Python 3.12 or 3.13
- A platform supported by GeoPandas, Pyogrio, Shapely, and PyProj wheels
Installation
Install the core library and CLI from PyPI:
python -m pip install geoqc
Install optional delivery and reporting dependencies only when needed:
python -m pip install "geoqc[api]" # FastAPI and Uvicorn
python -m pip install "geoqc[report]" # Jinja2 and Folium
python -m pip install "geoqc[all]" # All optional features
To install a source checkout:
python -m pip install .
Quick start
Validate one Shapely geometry using the stable top-level API:
from shapely.geometry import Polygon
from geoqc import GeometryIssueType, validate_geometry
polygon = Polygon([(0, 0), (2, 2), (0, 2), (2, 0), (0, 0)])
result = validate_geometry(polygon)
print(result.is_valid) # False
for issue in result.issues:
print(issue.issue_type, issue.message)
if result.has_issue(GeometryIssueType.SELF_INTERSECTION):
print("Repair the polygon before using it downstream.")
Results are immutable, typed dataclasses. Passing an object that is not a
Shapely geometry raises TypeError so contract errors are detected early.
Command-line interface
The initial CLI exposes package information and a stable command surface:
geoqc --help
geoqc --version
geoqc audit path/to/folder
Worker count is selected automatically; use --workers N as a safe upper bound.
See parallel streaming audits and the
CLI documentation for behavior and limitations.
Optional API and web client
After installing the api extra, start the local API:
python -m uvicorn geoqc.interfaces.api.main:app --host 127.0.0.1 --port 8000
Open http://127.0.0.1:8000/docs for OpenAPI documentation. The
POST /api/geometry/validate endpoint accepts bounded Shapefile component
sets, GeoJSON, GeoPackage, FlatGeobuf, and GeoParquet uploads. Multi-layer
GeoPackages require a layer field.
The browser client is developed separately under apps/web; see its README for
local commands. Do not expose the development server publicly.
KML and GML are intentionally rejected by the public upload endpoint because XML-based formats can introduce external-resource risks. For Internet-facing deployments, place authentication, rate limiting, request-size enforcement, structured access logging, and TLS at a trusted reverse proxy or gateway.
Documentation
- Documentation index
- Architecture
- CLI reference
- API and deployment
- Developer guide
- FAQ
- Security policy
- Release checklist
Only names exported directly from geoqc are considered stable public API in
the 0.x series. Other modules are advanced APIs and may change with notice in
CHANGELOG.md.
Development
uv sync --all-extras --all-groups
uv run ruff format --check .
uv run ruff check .
uv run mypy src tests
uv run pytest
npm --prefix apps/web ci
npm --prefix apps/web run check
Read CONTRIBUTING.md before opening a pull request.
License
Copyright (c) 2026 Ananda Gunawan.
GeoQC is open-source software distributed under the MIT License.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file geoqc-0.1.0.tar.gz.
File metadata
- Download URL: geoqc-0.1.0.tar.gz
- Upload date:
- Size: 111.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fa55e0b1a772ffcc81eb95c6c853d93f79d15c512d88b72a3db3aa1a7303649c
|
|
| MD5 |
424d0efcaf9cc4f065c5bb537b3d17e4
|
|
| BLAKE2b-256 |
316c78b9a7c1f505384659245dc4f70b194514e5f16050a8aefb5946212ed0fd
|
Provenance
The following attestation bundles were made for geoqc-0.1.0.tar.gz:
Publisher:
publish.yml on nandaisnanda/GeoQC
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
geoqc-0.1.0.tar.gz -
Subject digest:
fa55e0b1a772ffcc81eb95c6c853d93f79d15c512d88b72a3db3aa1a7303649c - Sigstore transparency entry: 2255149783
- Sigstore integration time:
-
Permalink:
nandaisnanda/GeoQC@548fa727fcd587a1d220cf025ea1d23a28e2d2c3 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/nandaisnanda
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@548fa727fcd587a1d220cf025ea1d23a28e2d2c3 -
Trigger Event:
release
-
Statement type:
File details
Details for the file geoqc-0.1.0-py3-none-any.whl.
File metadata
- Download URL: geoqc-0.1.0-py3-none-any.whl
- Upload date:
- Size: 111.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dfffc050b40594b34b418eca7ddcf4cfab5245f296e79f04032e7dce1f4c1804
|
|
| MD5 |
300061a5a2dba19eba6762364ac643a6
|
|
| BLAKE2b-256 |
1c0046c6c460eeb823e55ec39958d11c87ef70af313ae955142280f1fff61e58
|
Provenance
The following attestation bundles were made for geoqc-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on nandaisnanda/GeoQC
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
geoqc-0.1.0-py3-none-any.whl -
Subject digest:
dfffc050b40594b34b418eca7ddcf4cfab5245f296e79f04032e7dce1f4c1804 - Sigstore transparency entry: 2255149787
- Sigstore integration time:
-
Permalink:
nandaisnanda/GeoQC@548fa727fcd587a1d220cf025ea1d23a28e2d2c3 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/nandaisnanda
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@548fa727fcd587a1d220cf025ea1d23a28e2d2c3 -
Trigger Event:
release
-
Statement type: