aio_overpass.spatial

Basic definitions for (groups of) geospatial objects.

 1"""Basic definitions for (groups of) geospatial objects."""
 2
 3from abc import ABC, abstractmethod
 4from collections.abc import Iterator
 5from dataclasses import dataclass
 6from typing import Any, TypeAlias
 7
 8
 9__docformat__ = "google"
10__all__ = (
11    "GeoJsonDict",
12    "SpatialDict",
13    "Spatial",
14)
15
16
17GeoJsonDict: TypeAlias = dict[str, Any]
18"""A dictionary representing a GeoJSON object."""
19
20
21@dataclass(kw_only=True, slots=True)
22class SpatialDict:
23    """
24    Mapping of spatial objects with the ``__geo_interface__`` property.
25
26    Objects of this class have the ``__geo_interface__`` property following a protocol
27    [proposed](https://gist.github.com/sgillies/2217756) by Sean Gillies, which can make
28    it easier to use spatial data in other Python software. An example of this is the ``shape()``
29    function that builds Shapely geometries from any object with the ``__geo_interface__`` property.
30
31    Attributes:
32        __geo_interface__: this is the proposed property that contains the spatial data
33    """
34
35    __geo_interface__: dict
36
37
38class Spatial(ABC):
39    """
40    Base class for (groups of) geospatial objects.
41
42    Classes that represent spatial features extend this class and implement the
43    ``geojson`` property. Exporting objects in the GeoJSON format should make it possible
44    to integrate them with other tools for visualization, or further analysis.
45    The ability to re-import the exported GeoJSON structures as ``Spatial`` objects is not
46    considered here.
47    """
48
49    __slots__ = ("__validated__",)  # we use that field in tests
50
51    @property
52    @abstractmethod
53    def geojson(self) -> GeoJsonDict:
54        """
55        A mapping of this object, using the GeoJSON format.
56
57        The coordinate reference system for all GeoJSON coordinates is ``CRS:84``,
58        which means every coordinate is a tuple of longitude and latitude (in that order)
59        on the WGS 84 ellipsoid. Note that this order is flipped for all Shapely geometries
60        that represent OpenStreetMap elements (latitude first, then longitude).
61
62        References:
63            - https://osmdata.openstreetmap.de/info/projections.html
64            - https://tools.ietf.org/html/rfc7946#section-4
65        """
66        raise NotImplementedError
67
68    @property
69    def geo_interfaces(self) -> Iterator[SpatialDict]:
70        """A mapping of this object to ``SpatialDict``s that implement ``__geo_interface__``."""
71        geojson = self.geojson
72        match geojson["type"]:
73            case "FeatureCollection":
74                for feature in geojson["features"]:
75                    yield SpatialDict(__geo_interface__=feature)
76            case _:
77                yield SpatialDict(__geo_interface__=geojson)
GeoJsonDict: TypeAlias = dict[str, typing.Any]

A dictionary representing a GeoJSON object.

@dataclass(kw_only=True, slots=True)
class SpatialDict:
22@dataclass(kw_only=True, slots=True)
23class SpatialDict:
24    """
25    Mapping of spatial objects with the ``__geo_interface__`` property.
26
27    Objects of this class have the ``__geo_interface__`` property following a protocol
28    [proposed](https://gist.github.com/sgillies/2217756) by Sean Gillies, which can make
29    it easier to use spatial data in other Python software. An example of this is the ``shape()``
30    function that builds Shapely geometries from any object with the ``__geo_interface__`` property.
31
32    Attributes:
33        __geo_interface__: this is the proposed property that contains the spatial data
34    """
35
36    __geo_interface__: dict

Mapping of spatial objects with the __geo_interface__ property.

Objects of this class have the __geo_interface__ property following a protocol proposed by Sean Gillies, which can make it easier to use spatial data in other Python software. An example of this is the shape() function that builds Shapely geometries from any object with the __geo_interface__ property.

Attributes:
  • __geo_interface__: this is the proposed property that contains the spatial data
SpatialDict(*, __geo_interface__: dict)
class Spatial(abc.ABC):
39class Spatial(ABC):
40    """
41    Base class for (groups of) geospatial objects.
42
43    Classes that represent spatial features extend this class and implement the
44    ``geojson`` property. Exporting objects in the GeoJSON format should make it possible
45    to integrate them with other tools for visualization, or further analysis.
46    The ability to re-import the exported GeoJSON structures as ``Spatial`` objects is not
47    considered here.
48    """
49
50    __slots__ = ("__validated__",)  # we use that field in tests
51
52    @property
53    @abstractmethod
54    def geojson(self) -> GeoJsonDict:
55        """
56        A mapping of this object, using the GeoJSON format.
57
58        The coordinate reference system for all GeoJSON coordinates is ``CRS:84``,
59        which means every coordinate is a tuple of longitude and latitude (in that order)
60        on the WGS 84 ellipsoid. Note that this order is flipped for all Shapely geometries
61        that represent OpenStreetMap elements (latitude first, then longitude).
62
63        References:
64            - https://osmdata.openstreetmap.de/info/projections.html
65            - https://tools.ietf.org/html/rfc7946#section-4
66        """
67        raise NotImplementedError
68
69    @property
70    def geo_interfaces(self) -> Iterator[SpatialDict]:
71        """A mapping of this object to ``SpatialDict``s that implement ``__geo_interface__``."""
72        geojson = self.geojson
73        match geojson["type"]:
74            case "FeatureCollection":
75                for feature in geojson["features"]:
76                    yield SpatialDict(__geo_interface__=feature)
77            case _:
78                yield SpatialDict(__geo_interface__=geojson)

Base class for (groups of) geospatial objects.

Classes that represent spatial features extend this class and implement the geojson property. Exporting objects in the GeoJSON format should make it possible to integrate them with other tools for visualization, or further analysis. The ability to re-import the exported GeoJSON structures as Spatial objects is not considered here.

geojson: dict[str, typing.Any]
52    @property
53    @abstractmethod
54    def geojson(self) -> GeoJsonDict:
55        """
56        A mapping of this object, using the GeoJSON format.
57
58        The coordinate reference system for all GeoJSON coordinates is ``CRS:84``,
59        which means every coordinate is a tuple of longitude and latitude (in that order)
60        on the WGS 84 ellipsoid. Note that this order is flipped for all Shapely geometries
61        that represent OpenStreetMap elements (latitude first, then longitude).
62
63        References:
64            - https://osmdata.openstreetmap.de/info/projections.html
65            - https://tools.ietf.org/html/rfc7946#section-4
66        """
67        raise NotImplementedError

A mapping of this object, using the GeoJSON format.

The coordinate reference system for all GeoJSON coordinates is CRS:84, which means every coordinate is a tuple of longitude and latitude (in that order) on the WGS 84 ellipsoid. Note that this order is flipped for all Shapely geometries that represent OpenStreetMap elements (latitude first, then longitude).

References:
geo_interfaces: Iterator[SpatialDict]
69    @property
70    def geo_interfaces(self) -> Iterator[SpatialDict]:
71        """A mapping of this object to ``SpatialDict``s that implement ``__geo_interface__``."""
72        geojson = self.geojson
73        match geojson["type"]:
74            case "FeatureCollection":
75                for feature in geojson["features"]:
76                    yield SpatialDict(__geo_interface__=feature)
77            case _:
78                yield SpatialDict(__geo_interface__=geojson)

A mapping of this object to SpatialDicts that implement __geo_interface__.