diff --git a/nominatim/api/reverse.py b/nominatim/api/reverse.py index e16742cfa..547145596 100644 --- a/nominatim/api/reverse.py +++ b/nominatim/api/reverse.py @@ -186,7 +186,7 @@ async def _find_closest_street_or_poi(self, distance: float) -> Optional[SaRow]: .where(sa.or_(sa.not_(t.c.geometry.is_area()), t.c.centroid.ST_Distance(WKT_PARAM) < diststr)) .order_by('distance') - .limit(1)) + .limit(2)) if self.has_geometries(): sql = self._add_geometry_columns(sql, t.c.geometry) @@ -212,7 +212,20 @@ async def _find_closest_street_or_poi(self, distance: float) -> Optional[SaRow]: sql = sql.where(sa.or_(*restrict)) - return (await self.conn.execute(sql, self.bind_params)).one_or_none() + # If the closest object is inside an area, then check if there is a + # POI node nearby and return that. + prev_row = None + for row in await self.conn.execute(sql, self.bind_params): + if prev_row is None: + if row.rank_search <= 27 or row.osm_type == 'N' or row.distance > 0: + return row + prev_row = row + else: + if row.rank_search > 27 and row.osm_type == 'N'\ + and row.distance < 0.0001: + return row + + return prev_row async def _find_housenumber_for_street(self, parent_place_id: int) -> Optional[SaRow]: diff --git a/test/python/api/test_api_reverse.py b/test/python/api/test_api_reverse.py index c51b3951a..8f8b2dba2 100644 --- a/test/python/api/test_api_reverse.py +++ b/test/python/api/test_api_reverse.py @@ -68,24 +68,24 @@ def test_reverse_ignore_unindexed(apiobj, frontend): (0.70003, napi.DataLayer.MANMADE | napi.DataLayer.NATURAL, 225), (5, napi.DataLayer.ADDRESS, 229)]) def test_reverse_rank_30_layers(apiobj, frontend, y, layer, place_id): - apiobj.add_placex(place_id=223, class_='place', type='house', + apiobj.add_placex(place_id=223, osm_type='N', class_='place', type='house', housenumber='1', rank_address=30, rank_search=30, centroid=(1.3, 0.70001)) - apiobj.add_placex(place_id=224, class_='amenity', type='toilet', + apiobj.add_placex(place_id=224, osm_type='N', class_='amenity', type='toilet', rank_address=30, rank_search=30, centroid=(1.3, 0.7)) - apiobj.add_placex(place_id=225, class_='man_made', type='tower', + apiobj.add_placex(place_id=225, osm_type='N', class_='man_made', type='tower', rank_address=0, rank_search=30, centroid=(1.3, 0.70003)) - apiobj.add_placex(place_id=226, class_='railway', type='station', + apiobj.add_placex(place_id=226, osm_type='N', class_='railway', type='station', rank_address=0, rank_search=30, centroid=(1.3, 0.70004)) - apiobj.add_placex(place_id=227, class_='natural', type='cave', + apiobj.add_placex(place_id=227, osm_type='N', class_='natural', type='cave', rank_address=0, rank_search=30, centroid=(1.3, 0.70005))