]> git.openstreetmap.org Git - nominatim.git/blob - src/nominatim_db/data/place_info.py
Merge pull request #3586 from lonvia/reduce-lookup-calls
[nominatim.git] / src / nominatim_db / data / place_info.py
1 # SPDX-License-Identifier: GPL-3.0-or-later
2 #
3 # This file is part of Nominatim. (https://nominatim.org)
4 #
5 # Copyright (C) 2024 by the Nominatim developer community.
6 # For a full list of authors see the git log.
7 """
8 Wrapper around place information the indexer gets from the database and hands to
9 the tokenizer.
10 """
11 from typing import Optional, Mapping, Any, Tuple
12
13
14 class PlaceInfo:
15     """ This data class contains all information the tokenizer can access
16         about a place.
17     """
18
19     def __init__(self, info: Mapping[str, Any]) -> None:
20         self._info = info
21
22     @property
23     def name(self) -> Optional[Mapping[str, str]]:
24         """ A dictionary with the names of the place. Keys and values represent
25             the full key and value of the corresponding OSM tag. Which tags
26             are saved as names is determined by the import style.
27             The property may be None if the place has no names.
28         """
29         return self._info.get('name')
30
31     @property
32     def address(self) -> Optional[Mapping[str, str]]:
33         """ A dictionary with the address elements of the place. They key
34             usually corresponds to the suffix part of the key of an OSM
35             'addr:*' or 'isin:*' tag. There are also some special keys like
36             `country` or `country_code` which merge OSM keys that contain
37             the same information. See [Import Styles][1] for details.
38
39             The property may be None if the place has no address information.
40
41             [1]: ../customize/Import-Styles.md
42         """
43         return self._info.get('address')
44
45     @property
46     def country_code(self) -> Optional[str]:
47         """ The country code of the country the place is in. Guaranteed
48             to be a two-letter lower-case string. If the place is not inside
49             any country, the property is set to None.
50         """
51         return self._info.get('country_code')
52
53     @property
54     def rank_address(self) -> int:
55         """ The [rank address][1] before any rank correction is applied.
56
57             [1]: ../customize/Ranking.md#address-rank
58         """
59         return self._info.get('rank_address', 0)
60
61     @property
62     def centroid(self) -> Optional[Tuple[float, float]]:
63         """ A center point of the place in WGS84. May be None when the
64             geometry of the place is unknown.
65         """
66         x, y = self._info.get('centroid_x'), self._info.get('centroid_y')
67         return None if x is None or y is None else (x, y)
68
69     def is_a(self, key: str, value: str) -> bool:
70         """ Set to True when the place's primary tag corresponds to the given
71             key and value.
72         """
73         return self._info.get('class') == key and self._info.get('type') == value
74
75     def is_country(self) -> bool:
76         """ Set to True when the place is a valid country boundary.
77         """
78         return self.rank_address == 4 \
79             and self.is_a('boundary', 'administrative') \
80             and self.country_code is not None