Metadata-Version: 2.1
Name: geojson-validator
Version: 0.4.0
Summary: Validates and fixes GeoJSON
Home-page: https://github.com/chrieke/geojson-validator
Author: Christoph Rieke
Author-email: christoph.k.rieke@gmail.com
License: MIT
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: shapely
Requires-Dist: json_source_map
Requires-Dist: loguru

<img src="./repo-images/header_img.jpeg">

**Validate and automatically fix invalid GeoJSON. 🌎 Webapp and 🐍 Python package.** 

The only tool that reliably addresses all issues:
- Detects **invalid** geometries (GeoJSON specification): *duplicate nodes, wrong winding order, ...* 
- Detects **problematic** geometries (for some tools & APIs): *self-intersection, crossing anti-meridian, ...*
- Checks against **GeoJSON schema** if all required JSON elements exist 
- Automatically **fixes** invalid geometry issues 

<br>

<h3 align="center">
    🎈 <a href="https://geojson-validator.streamlit.app/">Try it out: geojson-validator webapp 🎈 </a>
</h3>

<br>

### Quickstart

```bash
# Installation
pip install geojson-validator
```

See the three main functions below. Data input can be any type of GeoJSON dictionary, a filepath/url to a GeoJSON, shapely geometries and anything with a `__geo_interface__` (e.g. Geopandas GeoDataFrame).

```python
import geojson_validator

geojson_input = {'type': 'FeatureCollection',
                 'features': [{'type': 'Feature', 'geometry':
                     {'type': 'Polygon', 'coordinates': [[[-59.758285, 8.367035], ...]]}}]}

geojson_validator.validate_schema(geojson_input)

geojson_validator.validate_geometries(geojson_input)

geojson_validator.fix_geometries(geojson_input)
```
<br>

### 1. Validate GeoJSON schema 📚

Checks the structure & formatting of the GeoJSON, e.g. if all required elements exist.

```python
errors = geojson_validator.validate_schema(geojson_input)
```

If the input conforms to the GeoJSON schema returns an empty list, otherwise all the reasons and respective
line/feature position where it is invalid: e.g. `{"Missing 'type'": {"lines": [4], "features": [0]}`.


### 2. Validate geometries 🟥

Checks the GeoJSON geometry objects for inconsistencies and geometric issues. See 
[geojson-invalid-geometry](https://github.com/chrieke/geojson-invalid-geometry) for a detailed description of all 
invalid and problematic criteria.

```python
result = geojson_validator.validate_geometries(geojson_input)
```
The result gives the reason and positional indices of the invalid geometries e.g. `[0, 3]`. 
It also shows which of the sub-geometries within a MultiType geometry make it invalid e.g. `{2:[0, 5]}`.

```
{"invalid": 
      {"duplicate_nodes": [0, 3],
       "exterior_not_ccw":  [{2:[0, 5]}],  
 "problematic":
      {"crosses_antimeridian": [1]},
 "count_geometry_types": 
      {"Polygon": 3,
       "MultiPolygon": 1}}
```

You can choose to validate only selected criteria, by default all are checked.
```python
# Invalid according to the GeoJSON specification
criteria_invalid = ["unclosed", "duplicate_nodes", "less_three_unique_nodes", "exterior_not_ccw",
                    "interior_not_cw", "inner_and_exterior_ring_intersect", "crs_defined",
                    "outside_lat_lon_boundaries"]

# Problematic with some tools & APIs
criteria_problematic = ["holes", "self_intersection", "excessive_coordinate_precision",
                        "3d_coordinates", "crosses_antimeridian"]

geojson_validator.validate_geometries(geojson, criteria_invalid, criteria_problematic)
```



### 3. Fix GeoJSON geometries 🟩

Fixes 6 of the most common categories of invalid geometries.
All other criteria can not be fixed in a programmatic way, they require user decisions 
(e.g. which part of a self-intersecting geometry should be dropped). More helper-functions for this coming soon!

```python
# Fixes "unclosed", "duplicate_nodes", "exterior_not_ccw", "interior_not_cw"
fixed_fc = geojson_validator.fix_geometries(geojson_input)
```

The result is a FeatureCollection with the fixed geometries. The `check_crs` parameter is `False` by default, the test is optional.

<br>
<br>

<details><summary>TODO</summary>
<p>

- additional reasons invalidaity
- advanced fix (e.g. coordinate preicisoon)
- 
High:
- Improve app & gif. 
  - jsondecode
  - Map? 
  - Checkboxes? 
  - Options? 
  - just one button for validation. 
  - What was fixed & validate after again. 
  - https://geojson.yanzi.dev/
  - infos re file

Medium:
  - more fixes?
  - fc bbox order, feature bbox, geometry bbox order and other criteria

- Low:
  - Multihtreading?
  - versioning?
  - fastapi as connector, not hosted just in package for others to run.

Notes:
- Does not require a feature id, and it doesnt need to be unique

Don't:
- jsondecodeerror

</p>
</details>



