Skip to content

GeoJSON AOI Parser

HOT

Parse and normalize a GeoJSON area of interest, using pure Python.

Publish Docs Publish Test Package version Downloads License


📖 Documentation: https://hotosm.github.io/geojson-aoi-parser/

🖥️ Source Code: https://github.com/hotosm/geojson-aoi-parser


Why do we need this?

  • We generally need an Area of Interest (AOI) specified for software to run on a geospatial area.
  • GeoJSON is a simple exchange format to communicate this AOI.
  • We only care about Polygon data types, but GeoJSON data can be quite variable, with many options for presenting data.
  • The goal of this package is to receive GeoJSON data in various forms, then produce a normalised output that can be used for further processing.

Priorities

  • Flexible data input: file bytes, dict, string JSON.
  • Flexible geometry input:
  • Polygon
  • MultiPolygons
  • Feature
  • FeatureCollection
  • Handle multigeometries with an optional merge to single polygon, or split into featcol of individual polygons.
  • Handle geometries nested inside GeometryCollection*.
  • Remove any z-dimension coordinates.
  • Warn user if CRS is provided, in a coordinate system other than EPSG:4326.
  • Normalised output: FeatureCollection containing Polygon geoms.

[!WARNING]
*We typically advise against using the GeometryCollection type, and support in this library may not be fully functional.

However sometimes geometries may need to be returned wrapped in GeometryCollection, for example due to idiosyncrasies of PostGIS.

In this scenario, we support stripping out the first geometry from inside each GeometryCollection object (that may be nested in a FeatureCollection).

Capturing The Warnings

If the GeoJSON has an invalid CRS, or coordinates seem off, a warning will be raised.

To halt execution when a warning is raised and act on it:

try:
    featcol = parse_aoi(raw_geojson)
except UserWarning as warning:
    log.error(warning.message)
    msg = "Using a valid CRS is mandatory!"
    log.error(msg)
    raise HTTPException(HTTPStatus.BAD_REQUEST, detail=msg)

To record warnings, but allow execution to continue:

import warnings

with warnings.catch_warnings(record=True) as recorded_warnings:
    featcol = parse_aoi(raw_geojson)

if recorded_warnings:
    for warning in recorded_warnings:
        if isinstance(warning.message, UserWarning)
            # do stuff with warning
            logger.warning(f"A warning was encountered: {warning.message}")