Code Monkey home page Code Monkey logo

geojson-validator's Introduction

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


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 line location and feature index to more quickly localize the issues. Example: {"Missing 'type' member": {"line": [4], "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", "inner_and_exterior_ring_intersect"]

# Problematic with some tools & APIs
criteria_problematic = ["holes", "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}}

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. More fixes and helper-functions (for issues that require user descisions) coming soon!

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 schema validation? pydantic error messages a bit convulted (if one coordinate is issing error 4 times), very schema like, not custom, not easy to understand for no nprogrammers. often would need to be translated.

geojson-validator's People

Contributors

chrieke avatar nielsbom avatar

Stargazers

Veerakit SlothPete Prasertpol avatar  avatar Adnan Abbas Shah avatar James Harrison avatar Umang Kalra avatar Karan avatar François B avatar Matthieu Rigal avatar Matthieu Viry avatar Caerisse avatar Hazem Fahmi avatar Benjamin avatar Andreas Motl avatar Nikolaus Schlemm avatar Bennett Murphy avatar Mykola Kozyr avatar Daniel Sczepansky avatar Johannes Rieke avatar

Watchers

Flo J avatar  avatar  avatar

Forkers

nielsbom

geojson-validator's Issues

Crashes on Multipolygon

This MultiPolygon crashes both when I run fix_geometries in Jupyter and in your stream-lit.app validater. Error message below.

{"coordinates": [[[[-124.10446826928252, 49.27193446446772], [-124.11750419994368, 49.27994147270371], [-124.12689606250484, 49.283874318593504], [-124.13464711227414, 49.29214509115894], [-124.14549408624137, 49.29522284280057], [-124.15657343692958, 49.293878893523974], [-124.16313668808009, 49.29676320209966], [-124.17199342506395, 49.30457633545649], [-124.17996561227646, 49.31036985552304], [-124.18381829948783, 49.3129531477033], [-124.18944008624155, 49.312941393652146], [-124.19754592984458, 49.31002756751067], [-124.20830542276448, 49.315187127826356], [-124.2157292038376, 49.315804848301774], [-124.213650977996, 49.309927613111284], [-124.21511095124066, 49.30491482633213], [-124.23680696694304, 49.31647329071863], [-124.25376626008281, 49.31906544575372], [-124.26188005551055, 49.32742273735604], [-124.285720616853, 49.33287145201783], [-124.29341814488355, 49.332411470718576], [-124.29073517061933, 49.32399879415149], [-124.28276976773437, 49.31411048701645], [-124.28352004347738, 49.307629708767315], [-124.27957535751122, 49.303269964754975], [-124.28796716204519, 49.27903030082543], [-124.3099401620452, 49.273654300825434], [-124.33740616204518, 49.26290130082543], [-124.35663216204519, 49.246766300825435], [-124.37311116204519, 49.22524630082543], [-124.41705616204518, 49.209099300825436], [-124.4692411620452, 49.20551030082543], [-124.51593316204519, 49.21448230082543], [-124.54339916204519, 49.234214300825435], [-124.58185116204518, 49.23062730082543], [-124.61481016204519, 49.216276300825434], [-124.62305016204519, 49.19474230082543], [-124.61481016204519, 49.17858630082544], [-124.5791051620452, 49.15164630082543], [-124.5736121620452, 49.13008430082543], [-124.5681181620452, 49.12109730082543], [-124.55438616204519, 49.094127300825434], [-124.55713216204519, 49.076138300825434], [-124.55713216204519, 49.058143300825435], [-124.55438616204519, 49.036540300825436], [-124.54889216204519, 49.03113830082543], [-124.5626251620452, 49.01853130082544], [-124.55987916204519, 48.99150530082543], [-124.54889216204519, 48.96807030082543], [-124.53515916204519, 48.98790030082543], [-124.51868016204519, 49.000515300825434], [-124.4774811620452, 49.01673030082544], [-124.41431016204518, 49.00952430082543], [-124.4033241620452, 48.99510930082543], [-124.3950841620452, 48.978887300825434], [-124.37585816204519, 48.971676300825436], [-124.32092616204518, 48.96085730082543], [-124.28522016204519, 48.975282300825434], [-124.18634416204519, 48.92838630082543], [-124.14789116204518, 48.92658230082543], [-124.08746716204519, 48.91936330082543], [-124.03528216204519, 48.89408830082543], [-124.00506916204519, 48.87060830082543], [-123.97760316204518, 48.84350130082543], [-123.93365816204519, 48.83084730082543], [-123.88971316204518, 48.827230300825434], [-123.85400716204519, 48.83627030082543], [-123.83052981616392, 48.83407251118054], [-123.82171671087983, 48.84960392957647], [-123.80911738000694, 48.870224043302386], [-123.79233189467973, 48.88515826703711], [-123.77681440013899, 48.88686861253589], [-123.76783115136001, 48.893057678064906], [-123.7641048404061, 48.89524625835304], [-123.76037852945772, 48.89481840233615], [-123.75728384182052, 48.8962824050798], [-123.75650181144167, 48.8990268828025], [-123.75694428255323, 48.904387178926555], [-123.7553633777716, 48.90495554479307], [-123.75048221580158, 48.90514663564133], [-123.74782040818488, 48.90709833169876], [-123.74616302666524, 48.90791821778012], [-123.74303006390397, 48.90711999392033], [-123.7409613694671, 48.9071452901762], [-123.73824078494236, 48.90795420221514], [-123.73722769915064, 48.907987998664765], [-123.73681692437766, 48.907467553248495], [-123.7368578828882, 48.90584848701732], [-123.7354532949299, 48.904268959764465], [-123.72366898159117, 48.89656631280471], [-123.71839341408776, 48.895011720315324], [-123.7168346613717, 48.892241241244875], [-123.71178190338948, 48.88825433822389], [-123.71172620951424, 48.886428361163894], [-123.71036247186575, 48.88500291361751], [-123.70860173519964, 48.883907359819545], [-123.70584662093523, 48.88299304786446], [-123.70411438214296, 48.88230264669809], [-123.70461632058165, 48.88075787803007], [-123.7043099329056, 48.87941899850895], [-123.70309269408938, 48.87828302187512], [-123.70076074149124, 48.87801343657501], [-123.69932094296544, 48.87907870638699], [-123.69872429206343, 48.87992215732976], [-123.69815955838428, 48.882798625626066], [-123.69585552427971, 48.88329947292803], [-123.69289731064386, 48.881966199043546], [-123.69014717660521, 48.88169548333286], [-123.68592532684967, 48.88212864452191], [-123.68653857744548, 48.88532679955213], [-123.68483891215783, 48.88894719789863], [-123.6852944413965, 48.89263906131413], [-123.68282380415442, 48.894780568155795], [-123.6803531669007, 48.89692198327043], [-123.6770213551821, 48.90360616669658], [-123.69435869427039, 48.91748513537439], [-123.71169603337212, 48.9313602488726], [-123.72871943407414, 48.93757220132457], [-123.7493189340768, 48.95653262591241], [-123.7624550934978, 48.964093677333686], [-123.79414587854424, 48.975420647914035], [-123.80222946539136, 48.98694377860292], [-123.80480010695044, 48.99504349301637], [-123.81110871363427, 48.99707231362922], [-123.82080761809041, 49.00419269131285], [-123.83436880917517, 49.010774214580344], [-123.84218494177684, 49.016014261353774], [-123.84766642724416, 49.01876585038369], [-123.85337644213722, 49.02044134465413], [-123.85604154517338, 49.02302649152793], [-123.85374552306263, 49.02522884879755], [-123.85144950094964, 49.025134798491194], [-123.8462862994529, 49.02345756603577], [-123.83645380369461, 49.0179525744052], [-123.81503766305067, 49.00566472324593], [-123.77609624196465, 48.9817183714918], [-123.75328853951072, 48.985405417749725], [-123.76062316204519, 49.02213330082543], [-123.73951626921736, 49.0362635738048], [-123.63773095863095, 49.01980077243934], [-123.61829426755024, 49.01271257899602], [-123.60207626995889, 49.01070363883434], [-123.58191342831688, 49.01710365205906], [-123.5910821124053, 49.03456430196013], [-123.6068151620452, 49.05094330082543], [-123.62329416204518, 49.081535300825436], [-123.63153416204518, 49.11031130082544], [-123.64526716204519, 49.14266330082543], [-123.70976034744741, 49.16615667599995], [-123.74878207328973, 49.17154488535907], [-123.78726861635316, 49.18537210155567], [-123.82190325080062, 49.21014930323308], [-123.8677401620452, 49.219864300825435], [-123.91168516204519, 49.22524630082543], [-123.98374010029633, 49.24582735587967], [-124.03479105089856, 49.252682713856906], [-124.07244728554492, 49.257532143592584], [-124.09555333494384, 49.258266423374785], [-124.12495425466685, 49.2560506335062], [-124.15647733620148, 49.25601920231696], [-124.18024031893718, 49.25915322927615], [-124.18585875475434, 49.26687454471484], [-124.170361150497, 49.26849575671696], [-124.14770546066919, 49.26518657060704], [-124.13417691120077, 49.2639502953848], [-124.11547863325129, 49.26556859469935], [-124.10599673705812, 49.26862188977475], [-124.10446826928252, 49.27193446446772]]], [[[-123.20366412400031, 49.123428495036165], [-123.23996181835875, 49.13423483908312], [-123.23313491268677, 49.1358284897417], [-123.20556019858563, 49.13606464929612], [-123.2012429010334, 49.13970424532238], [-123.20454280875938, 49.16200739653192], [-123.20784271649477, 49.17566758897465], [-123.19662303022699, 49.177609155130796], [-123.19288313479812, 49.172647293127454], [-123.18849634152625, 49.124532468852834], [-123.19244936628289, 49.12330158370361], [-123.20366412400031, 49.123428495036165]]], [[[-122.66743487789853, 49.1881614957822], [-122.67170722482153, 49.19533040857388], [-122.67182269366643, 49.20370541518429], [-122.65507971242758, 49.21245616503853], [-122.63417985311065, 49.216981787698415], [-122.6176678095465, 49.217811444433494], [-122.60485076875031, 49.2162275438871], [-122.60115576599443, 49.20521426100066], [-122.60716014547009, 49.19661316468526], [-122.63706657400357, 49.189821758973096], [-122.66743487789853, 49.1881614957822]]]], "type": "MultiPolygon"}

Error

File "/home/adminuser/venv/lib/python3.9/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 542, in _run_script exec(code, module.__dict__) File "/mount/src/geojson-validator/streamlit-webapp/app.py", line 104, in <module> fixed_fc = geojson_validator.fix_geometries(json_json) File "/home/adminuser/venv/lib/python3.9/site-packages/geojson_validator/main.py", line 101, in fix_geometries fixed_fc = process_fix(fc, geometry_validation_results, criteria) File "/home/adminuser/venv/lib/python3.9/site-packages/geojson_validator/fixes_utils.py", line 32, in process_fix fc_copy["features"][idx]["geometry"] = geom_fixed.__geo_interface__

TODO & Roadmap

Just to keep track of some TODOs for me personally:

Readme:

  • GIF

App:

  • jsondecode
  • Map?
  • Checkboxes?
  • Options?
  • just one button for validation?
  • What was fixed & validate after again?
  • Inspiration https://geojson.yanzi.dev/
  • infos re file

Code:

  • json can also be given as str?
  • No holes intersecting/outside the outer ring (expensive)
  • advanced fix (e.g. coordinate preicisoon)
  • min. positions geometry (short etc) in schema
  • more fixes?
  • move invalid schema examples to other repo
  • For Polygons with more than one of these rings, the first MUST be
    the exterior ring, and any others MUST be interior rings. The
    exterior ring bounds the surface, and the interior rings (if
    present) bound holes within the surface.
  • To maximize interoperability, implementations SHOULD avoid nested
    GeometryCollections

Low Priority

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

NOT:

  • Does not require a feature id, and it doesnt need to be unique
  • The check_crs parameter is False by default, the test is optional.
  • jsondecodeerror

Reproject to `CRS84`

One constant issue I have with GeoJSON is, that people export whatever Projection they are currently using in QGIS and the resulting file does not conform to the specification which is explicit in requiring urn:ogc:def:crs:OGC::CRS84

https://stevage.github.io/geojson-spec/#section-4

image

It would be awesome, if the validator could fix this automatically.

Suggestion: Integrate with pydantic

Hi,

pydantic is known to be a blazing fast model validator. There is already this tool to validate GeoJSON using it. Maybe both tools/functionalities could be merged, as pydantic is probably the best way to validate, but considering that you add also fixing.

Maybe you could contribute fixing to the other library and focus here on using pydantic at core but offering fixing GeoJSONs in the streamlit app.

Best and thanks for the work,
Matthieu

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.