# SPDX-License-Identifier: GPL-3.0-or-later # # This file is part of Nominatim. (https://nominatim.org) # # Copyright (C) 2023 by the Nominatim developer community. # For a full list of authors see the git log. """ Complex datatypes used by the Nominatim API. """ from typing import Optional, Union, NamedTuple import dataclasses import enum from struct import unpack @dataclasses.dataclass class PlaceID: """ Reference an object by Nominatim's internal ID. """ place_id: int @dataclasses.dataclass class OsmID: """ Reference by the OSM ID and potentially the basic category. """ osm_type: str osm_id: int osm_class: Optional[str] = None def __post_init__(self) -> None: if self.osm_type not in ('N', 'W', 'R'): raise ValueError(f"Illegal OSM type '{self.osm_type}'. Must be one of N, W, R.") PlaceRef = Union[PlaceID, OsmID] class Point(NamedTuple): """ A geographic point in WGS84 projection. """ x: float y: float @property def lat(self) -> float: """ Return the latitude of the point. """ return self.y @property def lon(self) -> float: """ Return the longitude of the point. """ return self.x def to_geojson(self) -> str: """ Return the point in GeoJSON format. """ return f'{{"type": "Point","coordinates": [{self.x}, {self.y}]}}' @staticmethod def from_wkb(wkb: bytes) -> 'Point': """ Create a point from EWKB as returned from the database. """ if len(wkb) != 25: raise ValueError("Point wkb has unexpected length") if wkb[0] == 0: gtype, srid, x, y = unpack('>iidd', wkb[1:]) elif wkb[0] == 1: gtype, srid, x, y = unpack('