1 # SPDX-License-Identifier: GPL-3.0-or-later
3 # This file is part of Nominatim. (https://nominatim.org)
5 # Copyright (C) 2025 by the Nominatim developer community.
6 # For a full list of authors see the git log.
8 Tests for running the POI searcher.
12 from nominatim_api.types import SearchDetails
13 from nominatim_api.search.db_searches import PoiSearch
14 from nominatim_api.search.db_search_fields import WeightedStrings, WeightedCategories
17 def run_search(apiobj, frontend, global_penalty, poitypes, poi_penalties=None,
18 ccodes=[], details=SearchDetails()):
19 if poi_penalties is None:
20 poi_penalties = [0.0] * len(poitypes)
23 penalty = global_penalty
24 qualifiers = WeightedCategories(poitypes, poi_penalties)
25 countries = WeightedStrings(ccodes, [0.0] * len(ccodes))
27 search = PoiSearch(MySearchData())
29 api = frontend(apiobj, options=['search'])
32 async with api._async_api.begin() as conn:
33 return await search.lookup(conn, details)
35 return api._loop.run_until_complete(run())
38 @pytest.mark.parametrize('coord,pid', [('34.3, 56.100021', 2),
40 def test_simple_near_search_in_placex(apiobj, frontend, coord, pid):
41 apiobj.add_placex(place_id=1, class_='highway', type='bus_stop',
43 apiobj.add_placex(place_id=2, class_='highway', type='bus_stop',
44 centroid=(34.3, 56.1))
46 details = SearchDetails.from_kwargs({'near': coord, 'near_radius': 0.001})
48 results = run_search(apiobj, frontend, 0.1, [('highway', 'bus_stop')], [0.5], details=details)
50 assert [r.place_id for r in results] == [pid]
53 @pytest.mark.parametrize('coord,pid', [('34.3, 56.100021', 2),
56 def test_simple_near_search_in_classtype(apiobj, frontend, coord, pid):
57 apiobj.add_placex(place_id=1, class_='highway', type='bus_stop',
59 apiobj.add_placex(place_id=2, class_='highway', type='bus_stop',
60 centroid=(34.3, 56.1))
61 apiobj.add_class_type_table('highway', 'bus_stop')
63 details = SearchDetails.from_kwargs({'near': coord, 'near_radius': 0.5})
65 results = run_search(apiobj, frontend, 0.1, [('highway', 'bus_stop')], [0.5], details=details)
67 assert [r.place_id for r in results] == [pid]
70 class TestPoiSearchWithRestrictions:
72 @pytest.fixture(autouse=True, params=["placex", "classtype"])
73 def fill_database(self, apiobj, request):
74 apiobj.add_placex(place_id=1, class_='highway', type='bus_stop',
76 centroid=(34.3, 56.10003))
77 apiobj.add_placex(place_id=2, class_='highway', type='bus_stop',
79 centroid=(34.3, 56.1))
80 if request.param == 'classtype':
81 apiobj.add_class_type_table('highway', 'bus_stop')
82 self.args = {'near': '34.3, 56.4', 'near_radius': 0.5}
84 self.args = {'near': '34.3, 56.100021', 'near_radius': 0.001}
86 def test_unrestricted(self, apiobj, frontend):
87 results = run_search(apiobj, frontend, 0.1, [('highway', 'bus_stop')], [0.5],
88 details=SearchDetails.from_kwargs(self.args))
90 assert [r.place_id for r in results] == [1, 2]
92 def test_restict_country(self, apiobj, frontend):
93 results = run_search(apiobj, frontend, 0.1, [('highway', 'bus_stop')], [0.5],
95 details=SearchDetails.from_kwargs(self.args))
97 assert [r.place_id for r in results] == [2]
99 def test_restrict_by_viewbox(self, apiobj, frontend):
100 args = {'bounded_viewbox': True, 'viewbox': '34.299,56.0,34.3001,56.10001'}
101 args.update(self.args)
102 results = run_search(apiobj, frontend, 0.1, [('highway', 'bus_stop')], [0.5],
104 details=SearchDetails.from_kwargs(args))
106 assert [r.place_id for r in results] == [2]