from struct import unpack
from binascii import unhexlify
-import sqlalchemy as sa
-
from nominatim.errors import UsageError
# pylint: disable=no-member,too-many-boolean-expressions,too-many-instance-attributes
@dataclasses.dataclass
class PlaceID:
- """ Reference an object by Nominatim's internal ID.
+ """ Reference a place by Nominatim's internal ID.
+
+ A PlaceID may reference place from the main table placex, from
+ the interpolation tables or the postcode tables. Place IDs are not
+ stable between installations. You may use this type theefore only
+ with place IDs obtained from the same database.
"""
place_id: int
+ """
+ The internal ID of the place to reference.
+ """
@dataclasses.dataclass
class OsmID:
- """ Reference by the OSM ID and potentially the basic category.
+ """ Reference a place by its OSM ID and potentially the basic category.
+
+ The OSM ID may refer to places in the main table placex and OSM
+ interpolation lines.
"""
osm_type: str
+ """ OSM type of the object. Must be one of `N`(node), `W`(way) or
+ `R`(relation).
+ """
osm_id: int
+ """ The OSM ID of the object.
+ """
osm_class: Optional[str] = None
+ """ The same OSM object may appear multiple times in the database under
+ different categories. The optional class parameter allows to distinguish
+ the different categories and corresponds to the key part of the category.
+ If there are multiple objects in the database and `osm_class` is
+ left out, then one of the objects is returned at random.
+ """
def __post_init__(self) -> None:
if self.osm_type not in ('N', 'W', 'R'):
WKB_BBOX_HEADER_BE = b'\x00\x20\x00\x00\x03\x00\x00\x10\xe6\x00\x00\x00\x01\x00\x00\x00\x05'
class Bbox:
- """ A bounding box in WSG84 projection.
+ """ A bounding box in WGS84 projection.
The coordinates are available as an array in the 'coord'
property in the order (minx, miny, maxx, maxy).
"""
def __init__(self, minx: float, miny: float, maxx: float, maxy: float) -> None:
+ """ Create a new bounding box with the given coordinates in WGS84
+ projection.
+ """
self.coords = (minx, miny, maxx, maxy)
""" Return the WKT representation of the Bbox. This
is a simple polygon with four points.
"""
- return 'POLYGON(({0} {1},{0} {3},{2} {3},{2} {1},{0} {1}))'.format(*self.coords)
+ return 'POLYGON(({0} {1},{0} {3},{2} {3},{2} {1},{0} {1}))'\
+ .format(*self.coords) # pylint: disable=consider-using-f-string
@staticmethod
def from_wkb(wkb: Union[None, str, bytes]) -> 'Optional[Bbox]':
""" Create a Bbox from a bounding box polygon as returned by
- the database. Return s None if the input value is None.
+ the database. Returns `None` if the input value is None.
"""
if wkb is None:
return None
except ValueError as exc:
raise UsageError('Bounding box parameter needs to be numbers.') from exc
- if x1 < -180.0 or x1 > 180.0 or y1 < -90.0 or y1 > 90.0 \
- or x2 < -180.0 or x2 > 180.0 or y2 < -90.0 or y2 > 90.0:
- raise UsageError('Bounding box coordinates invalid.')
+ x1 = min(180, max(-180, x1))
+ x2 = min(180, max(-180, x2))
+ y1 = min(90, max(-90, y1))
+ y2 = min(90, max(-90, y2))
if x1 == x2 or y1 == y2:
raise UsageError('Bounding box with invalid parameters.')
class GeometryFormat(enum.Flag):
- """ Geometry output formats supported by Nominatim.
+ """ All search functions support returning the full geometry of a place in
+ various formats. The internal geometry is converted by PostGIS to
+ the desired format and then returned as a string. It is possible to
+ request multiple formats at the same time.
"""
NONE = 0
+ """ No geometry requested. Alias for a empty flag.
+ """
GEOJSON = enum.auto()
+ """
+ [GeoJSON](https://geojson.org/) format
+ """
KML = enum.auto()
+ """
+ [KML](https://en.wikipedia.org/wiki/Keyhole_Markup_Language) format
+ """
SVG = enum.auto()
+ """
+ [SVG](http://www.w3.org/TR/SVG/paths.html) format
+ """
TEXT = enum.auto()
+ """
+ [WKT](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry) format
+ """
class DataLayer(enum.Flag):
"""
excluded: List[int] = dataclasses.field(default_factory=list,
metadata={'transform': format_excluded})
- """ List of OSM objects to exclude from the results. Currenlty only
+ """ List of OSM objects to exclude from the results. Currently only
works when the internal place ID is given.
An empty list (the default) will disable this filter.
"""
""" Restrict search to places with one of the given class/type categories.
An empty list (the default) will disable this filter.
"""
+ viewbox_x2: Optional[Bbox] = None
def __post_init__(self) -> None:
if self.viewbox is not None:
yext = (self.viewbox.maxlat - self.viewbox.minlat)/2
self.viewbox_x2 = Bbox(self.viewbox.minlon - xext, self.viewbox.minlat - yext,
self.viewbox.maxlon + xext, self.viewbox.maxlat + yext)
- else:
- self.viewbox_x2 = None
def restrict_min_max_rank(self, new_min: int, new_max: int) -> None: