GeoJSON Validator
Validate GeoJSON and automatically fix invalid geometries. Like geojsonhint, but with geometry checks & fixes!
- 🔴 Detects invalid geometries & 🟢 fixes them : Unclosed, wrong winding order etc.
- 🟨 Problematic geometries (for many tools & APIs): Self-intersection, crossing anti-meridian etc.
- Checks 🧬 structure according to GeoJSON specification
- Use Website or Python package
🎈 geojson-validator.streamlit.app in the Browser 🎈
Also see the geojson-invalid-geometry list for detailed explanations of all possible GeoJSON issues.
Quickstart Python
# Installation
pip install geojson-validator
Data input can be any type of GeoJSON object, a filepath/url, and anything with a __geo_interface__ (shapely, geopandas etc.).
import geojson_validator
geojson_input = {'type': 'FeatureCollection',
'features': [{'type': 'Feature', 'geometry':
{'type': 'Point', 'coordinates': [-59.758285, 8.367035]}}]}
geojson_validator.validate_structure(geojson_input)
geojson_validator.validate_geometries(geojson_input)
geojson_validator.fix_geometries(geojson_input)
1. Validate GeoJSON structure 🧬
Checks the structure & formatting of the GeoJSON, e.g. required elements, data & geometry types, coordinate array depth etc.
geojson_validator.validate_structure(geojson_input, check_crs=False)
Returns the reasons why the input does not conform to the GeoJSON specification.
Also gives the JSON path and feature index to more quickly localize the issues.
Example: {"Missing 'type' member": {"path": ["/features/0"], "feature": [0]}}.
2. Validate geometries 🟥
Checks the GeoJSON geometry objects for inconsistencies and geometric issues. See geojson-invalid-geometry for a detailed description of all invalid and problematic criteria. You can choose to validate only specific criteria, by default all are selected.
# Invalid according to the GeoJSON specification
criteria_invalid = ["unclosed", "less_three_unique_nodes", "exterior_not_ccw",
"interior_not_cw"]
# Problematic with some tools & APIs
criteria_problematic = ["holes", "inner_and_exterior_ring_intersect", "self_intersection",
"duplicate_nodes", "excessive_coordinate_precision", "excessive_vertices",
"3d_coordinates", "outside_lat_lon_boundaries", "crosses_antimeridian"]
geojson_validator.validate_geometries(geojson, criteria_invalid, criteria_problematic)
Returns the reasons (example below) and positional indices of the invalid geometries, e.g. features [0, 3]. Also indicates if a
sub-geometry of a MultiType geometry make it invalid e.g. {2:[0, 5]}.
{"invalid":
{"unclosed": [0, 3],
"exterior_not_ccw": [{2: [0, 5]}]},
"problematic":
{"crosses_antimeridian": [1]},
"count_geometry_types":
{"Polygon": 3,
"MultiPolygon": 1},
"skipped_validation": []}
skipped_validation lists the indices of features that could not be checked, e.g. a null
geometry, an unsupported geometry type, or a geometry whose structure is broken. Use
validate_structure to find out what is wrong with those. A MultiType geometry is listed
if any of its sub-geometries could not be checked, so it can appear both here and under a
violated criterium.
3. Fix GeoJSON geometries 🟩
Automatically repairs some of the most common categories of invalid geometries.
Always fixes ["unclosed", "exterior_not_ccw", "interior_not_cw"].
Select additional, non-essential fixes with the parameter optional.
Currently only Polygon geometries are fixed, other geometry types are left unchanged.
geojson_validator.fix_geometries(geojson_input, optional=["duplicate_nodes"])
The result is a GeoJSON FeatureCollection with the fixed geometries.
FAQ:
- Why not use geojson-pydantic for the structure validation? Its error messages are schema-shaped and hard to act on: a single missing coordinate is reported four times, and the wording usually has to be translated before it can be shown to a non-programmer. This library reports each problem once, in plain language, with the JSON path and feature index.
- Too many logging messages, can I disable them? You can disable or configure the logging behavior via
geojson_validator.configure_logging(enabled=True, level="DEBUG")which also returns the logger instance. - Does it ship type hints? Yes, the package is PEP 561 typed, so mypy/pyright pick up the annotations without extra stubs.
Metadata
Release files for geojson-validator 0.7.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| geojson_validator-0.7.0.tar.gz | 24.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| geojson_validator-0.7.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 42.6 kB
Release files / geojson_validator-0.7.0.tar.gz
| Download URL | geojson_validator-0.7.0.tar.gz |
|---|---|
| Size | 24.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f5869d1e18e66fb56e83d3f6796a3c87f3bccb08f740516f9b1ec92ea5d0e4b2
|
|
BLAKE2b-256 checksum How to use checksums |
1ab53b41962745f903f68e2a27bbc7b9f5acd7bdf237b51ae4708169c2106678
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / geojson_validator-0.7.0-py3-none-any.whl
| Download URL | geojson_validator-0.7.0-py3-none-any.whl |
|---|---|
| Size | 17.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
251eb912e4a645cc3e8b1e9791b991f01da35208d730dd5be303a152fcf1600a
|
|
BLAKE2b-256 checksum How to use checksums |
c882bb7c047f020564f924043edfccf3c442e9b6be746c4a7e6003f59471567f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|