Last active
July 8, 2023 06:03
-
-
Save jcrist/3e74af6ae329111955ad6696c3134519 to your computer and use it in GitHub Desktop.
A simple implementation of GeoJSON using msgspec
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
A simple implementation of GeoJSON (RFC 7946) using msgspec | |
(https://jcristharif.com/msgspec/) for parsing and validation. | |
The `loads` and `dumps` methods work like normal `json.loads`/`json.dumps`, | |
but: | |
- Will result in high-level GeoJSON types | |
- Will error nicely if a field is missing or the wrong type | |
- Will fill in default values for optional fields | |
- Decodes much faster than the stdlib json | |
- Integrates well with editor tooling like mypy or pyright | |
""" | |
from __future__ import annotations | |
import msgspec | |
Position = tuple[float, float] | |
class Point(msgspec.Struct, tag=True): | |
coordinates: Position | |
class MultiPoint(msgspec.Struct, tag=True): | |
coordinates: list[Position] | |
class LineString(msgspec.Struct, tag=True): | |
coordinates: list[Position] | |
class MultiLineString(msgspec.Struct, tag=True): | |
coordinates: list[list[Position]] | |
class Polygon(msgspec.Struct, tag=True): | |
coordinates: list[list[Position]] | |
class MultiPolygon(msgspec.Struct, tag=True): | |
coordinates: list[list[list[Position]]] | |
class GeometryCollection(msgspec.Struct, tag=True): | |
geometries: list[Geometry] | |
Geometry = ( | |
Point | |
| MultiPoint | |
| LineString | |
| MultiLineString | |
| Polygon | |
| MultiPolygon | |
| GeometryCollection | |
) | |
class Feature(msgspec.Struct, tag=True): | |
geometry: Geometry | None = None | |
properties: dict | None = None | |
id: str | int | None = None | |
class FeatureCollection(msgspec.Struct, tag=True): | |
features: list[Feature] | |
GeoJSON = Geometry | Feature | FeatureCollection | |
loads = msgspec.json.Decoder(GeoJSON).decode | |
dumps = msgspec.json.Encoder().encode |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example usage & quick benchmark: