]> git.openstreetmap.org Git - nominatim.git/blob - src/nominatim_api/v1/classtypes.py
Merge pull request #3587 from danieldegroot2/lookup-spelling
[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
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.
22     """
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)))\
30                 or 'Administrative'
31     elif category[1] == 'postal_code':
32         label = 'postcode'
33     elif rank < 26:
34         label = category[1] if category[1] != 'yes' else category[0]
35     elif rank < 28:
36         label = 'road'
37     elif (category[0] == 'place'
38           and category[1] in ('house_number', 'house_name', 'country_code')):
39         label = category[1]
40     else:
41         label = category[0]
42
43     return label.lower().replace(' ', '_')
44
45
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
50         search rank.
51     """
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))
55
56     if (result.osm_object and result.osm_object[0] == 'N') or result.bbox is None:
57
58         extent = NODE_EXTENT.get(result.category, 0.00005)
59         return Bbox.from_point(result.centroid, extent)
60
61     return result.bbox
62
63
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 }