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