1 # SPDX-License-Identifier: GPL-3.0-or-later
3 # This file is part of Nominatim. (https://nominatim.org)
5 # Copyright (C) 2024 by the Nominatim developer community.
6 # For a full list of authors see the git log.
8 Hard-coded information about tag categories.
10 These tables have been copied verbatim from the old PHP code. For future
11 version a more flexible formatting is required.
13 from typing import Tuple, Optional, Mapping, Union
15 from ..results import ReverseResult, SearchResult
16 from ..types import Bbox
19 def get_label_tag(category: Tuple[str, str], extratags: Optional[Mapping[str, str]],
20 rank: int, country: Optional[str]) -> str:
21 """ Create a label tag for the given place that can be used as an XML name.
23 if rank < 26 and extratags and 'place' in extratags:
24 label = extratags['place']
25 elif rank < 26 and extratags and 'linked_place' in extratags:
26 label = extratags['linked_place']
27 elif category == ('boundary', 'administrative'):
28 label = ADMIN_LABELS.get((country or '', int(rank/2)))\
29 or ADMIN_LABELS.get(('', int(rank/2)))\
31 elif category[1] == 'postal_code':
34 label = category[1] if category[1] != 'yes' else category[0]
37 elif (category[0] == 'place'
38 and category[1] in ('house_number', 'house_name', 'country_code')):
43 return label.lower().replace(' ', '_')
46 def bbox_from_result(result: Union[ReverseResult, SearchResult]) -> Bbox:
47 """ Compute a bounding box for the result. For ways and relations
48 a given boundingbox is used. For all other object, a box is computed
49 around the centroid according to dimensions derived from the
52 if result.category == ('place', 'postcode') and result.bbox is None:
53 return Bbox.from_point(result.centroid,
54 0.05 - 0.012 * (result.rank_search - 21))
56 if (result.osm_object and result.osm_object[0] == 'N') or result.bbox is None:
58 extent = NODE_EXTENT.get(result.category, 0.00005)
59 return Bbox.from_point(result.centroid, extent)
64 # pylint: disable=line-too-long
65 OSM_ATTRIBUTION = 'Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright'
80 ('', 5): 'State District',
82 ('', 7): 'Municipality',
84 ('', 9): 'City District',
86 ('', 11): 'Neighbourhood',
87 ('', 12): 'City Block',
96 ('boundary', 'administrative'): 'poi_boundary_administrative',
97 ('place', 'city'): 'poi_place_city',
98 ('place', 'town'): 'poi_place_town',
99 ('place', 'village'): 'poi_place_village',
100 ('place', 'hamlet'): 'poi_place_village',
101 ('place', 'suburb'): 'poi_place_village',
102 ('place', 'locality'): 'poi_place_village',
103 ('place', 'airport'): 'transport_airport2',
104 ('aeroway', 'aerodrome'): 'transport_airport2',
105 ('railway', 'station'): 'transport_train_station2',
106 ('amenity', 'place_of_worship'): 'place_of_worship_unknown3',
107 ('amenity', 'pub'): 'food_pub',
108 ('amenity', 'bar'): 'food_bar',
109 ('amenity', 'university'): 'education_university',
110 ('tourism', 'museum'): 'tourist_museum',
111 ('amenity', 'arts_centre'): 'tourist_art_gallery2',
112 ('tourism', 'zoo'): 'tourist_zoo',
113 ('tourism', 'theme_park'): 'poi_point_of_interest',
114 ('tourism', 'attraction'): 'poi_point_of_interest',
115 ('leisure', 'golf_course'): 'sport_golf',
116 ('historic', 'castle'): 'tourist_castle',
117 ('amenity', 'hospital'): 'health_hospital',
118 ('amenity', 'school'): 'education_school',
119 ('amenity', 'theatre'): 'tourist_theatre',
120 ('amenity', 'library'): 'amenity_library',
121 ('amenity', 'fire_station'): 'amenity_firestation3',
122 ('amenity', 'police'): 'amenity_police2',
123 ('amenity', 'bank'): 'money_bank2',
124 ('amenity', 'post_office'): 'amenity_post_office',
125 ('tourism', 'hotel'): 'accommodation_hotel2',
126 ('amenity', 'cinema'): 'tourist_cinema',
127 ('tourism', 'artwork'): 'tourist_art_gallery2',
128 ('historic', 'archaeological_site'): 'tourist_archaeological2',
129 ('amenity', 'doctors'): 'health_doctors',
130 ('leisure', 'sports_centre'): 'sport_leisure_centre',
131 ('leisure', 'swimming_pool'): 'sport_swimming_outdoor',
132 ('shop', 'supermarket'): 'shopping_supermarket',
133 ('shop', 'convenience'): 'shopping_convenience',
134 ('amenity', 'restaurant'): 'food_restaurant',
135 ('amenity', 'fast_food'): 'food_fastfood',
136 ('amenity', 'cafe'): 'food_cafe',
137 ('tourism', 'guest_house'): 'accommodation_bed_and_breakfast',
138 ('amenity', 'pharmacy'): 'health_pharmacy_dispensing',
139 ('amenity', 'fuel'): 'transport_fuel',
140 ('natural', 'peak'): 'poi_peak',
141 ('natural', 'wood'): 'landuse_coniferous_and_deciduous',
142 ('shop', 'bicycle'): 'shopping_bicycle',
143 ('shop', 'clothes'): 'shopping_clothes',
144 ('shop', 'hairdresser'): 'shopping_hairdresser',
145 ('shop', 'doityourself'): 'shopping_diy',
146 ('shop', 'estate_agent'): 'shopping_estateagent2',
147 ('shop', 'car'): 'shopping_car',
148 ('shop', 'garden_centre'): 'shopping_garden_centre',
149 ('shop', 'car_repair'): 'shopping_car_repair',
150 ('shop', 'bakery'): 'shopping_bakery',
151 ('shop', 'butcher'): 'shopping_butcher',
152 ('shop', 'apparel'): 'shopping_clothes',
153 ('shop', 'laundry'): 'shopping_laundrette',
154 ('shop', 'beverages'): 'shopping_alcohol',
155 ('shop', 'alcohol'): 'shopping_alcohol',
156 ('shop', 'optician'): 'health_opticians',
157 ('shop', 'chemist'): 'health_pharmacy',
158 ('shop', 'gallery'): 'tourist_art_gallery2',
159 ('shop', 'jewelry'): 'shopping_jewelry',
160 ('tourism', 'information'): 'amenity_information',
161 ('historic', 'ruins'): 'tourist_ruin',
162 ('amenity', 'college'): 'education_school',
163 ('historic', 'monument'): 'tourist_monument',
164 ('historic', 'memorial'): 'tourist_monument',
165 ('historic', 'mine'): 'poi_mine',
166 ('tourism', 'caravan_site'): 'accommodation_caravan_park',
167 ('amenity', 'bus_station'): 'transport_bus_station',
168 ('amenity', 'atm'): 'money_atm2',
169 ('tourism', 'viewpoint'): 'tourist_view_point',
170 ('tourism', 'guesthouse'): 'accommodation_bed_and_breakfast',
171 ('railway', 'tram'): 'transport_tram_stop',
172 ('amenity', 'courthouse'): 'amenity_court',
173 ('amenity', 'recycling'): 'amenity_recycling',
174 ('amenity', 'dentist'): 'health_dentist',
175 ('natural', 'beach'): 'tourist_beach',
176 ('railway', 'tram_stop'): 'transport_tram_stop',
177 ('amenity', 'prison'): 'amenity_prison',
178 ('highway', 'bus_stop'): 'transport_bus_stop2'
182 ('place', 'continent'): 25,
183 ('place', 'country'): 7,
184 ('place', 'state'): 2.6,
185 ('place', 'province'): 2.6,
186 ('place', 'region'): 1.0,
187 ('place', 'county'): 0.7,
188 ('place', 'city'): 0.16,
189 ('place', 'municipality'): 0.16,
190 ('place', 'island'): 0.32,
191 ('place', 'postcode'): 0.16,
192 ('place', 'town'): 0.04,
193 ('place', 'village'): 0.02,
194 ('place', 'hamlet'): 0.02,
195 ('place', 'district'): 0.02,
196 ('place', 'borough'): 0.02,
197 ('place', 'suburb'): 0.02,
198 ('place', 'locality'): 0.01,
199 ('place', 'neighbourhood'): 0.01,
200 ('place', 'quarter'): 0.01,
201 ('place', 'city_block'): 0.01,
202 ('landuse', 'farm'): 0.01,
203 ('place', 'farm'): 0.01,
204 ('place', 'airport'): 0.015,
205 ('aeroway', 'aerodrome'): 0.015,
206 ('railway', 'station'): 0.005