From 35060164abbc35c14ea7fa748735b433f7a209fa Mon Sep 17 00:00:00 2001 From: Sarah Hoffmann Date: Sun, 7 Dec 2025 11:00:23 +0100 Subject: [PATCH] reverse: only return housenumbers near street --- src/nominatim_api/reverse.py | 19 +++++++++++------- test/bdd/features/db/query/reverse.feature | 23 ++++++++++++++++++++-- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/nominatim_api/reverse.py b/src/nominatim_api/reverse.py index 9a538446..7b00d7ad 100644 --- a/src/nominatim_api/reverse.py +++ b/src/nominatim_api/reverse.py @@ -210,7 +210,10 @@ class ReverseGeocoder: sa.func.first_value(inner.c.distance) .over(order_by=inner.c.distance) .label('_min_distance'), - sa.func.first_value(inner.c._geometry.ST_ClosestPoint(WKT_PARAM)) + sa.func.first_value( + sa.case((inner.c.rank_search <= 27, + inner.c._geometry.ST_ClosestPoint(WKT_PARAM)), + else_=None)) .over(order_by=inner.c.distance) .label('_closest_point'), sa.func.first_value(sa.case((sa.or_(inner.c.rank_search <= 27, @@ -221,8 +224,10 @@ class ReverseGeocoder: .subquery() outer = sa.select(*(c for c in windowed.c if not c.key.startswith('_')), - windowed.c.centroid.ST_Distance(windowed.c._closest_point) - .label('best_distance'), + sa.case((sa.or_(windowed.c._closest_point == None, + windowed.c.housenumber == None), None), + else_=windowed.c.centroid.ST_Distance(windowed.c._closest_point)) + .label('distance_from_best'), sa.case((sa.or_(windowed.c._best_geometry == None, windowed.c.rank_search <= 27, windowed.c.osm_type != 'N'), False), @@ -337,13 +342,13 @@ class ReverseGeocoder: # If the closest result was a street but an address was requested, # see if we can refine the result with a housenumber closeby. elif parent_street is not None \ - and row.rank_address > 27 \ - and row.best_distance < 0.001 \ - and (hnr_distance is None or hnr_distance > row.best_distance) \ + and row.distance_from_best is not None \ + and row.distance_from_best < 0.001 \ + and (hnr_distance is None or hnr_distance > row.distance_from_best) \ and row.parent_place_id == parent_street: log().var_dump('Housenumber to closest result', row) result = row - hnr_distance = row.best_distance + hnr_distance = row.distance_from_best distance = row.distance # If the closest object is inside an area, then check if there is # a POI nearby and return that with preference. diff --git a/test/bdd/features/db/query/reverse.feature b/test/bdd/features/db/query/reverse.feature index 55c2162d..95852124 100644 --- a/test/bdd/features/db/query/reverse.feature +++ b/test/bdd/features/db/query/reverse.feature @@ -9,13 +9,32 @@ Feature: Reverse searches And the places | osm | class | type | geometry | | W1 | aeroway | terminal | (1,2,3,4,1) | - | N1 | amenity | restaurant | 9 | + | N9 | amenity | restaurant | 9 | When importing And reverse geocoding 1.0001,1.0001 Then the result contains | object | - | N1 | + | N9 | When reverse geocoding 1.0003,1.0001 Then the result contains | object | | W1 | + + + Scenario: Find closest housenumber for street matches + Given the 0.0001 grid with origin 1,1 + | | 1 | | | + | | | 2 | | + | 10 | | | 11 | + And the places + | osm | class | type | name | geometry | + | W1 | highway | service | Goose Drive | 10,11 | + | N2 | tourism | art_work | Beauty | 2 | + And the places + | osm | class | type | housenr | geometry | + | N1 | place | house | 23 | 1 | + When importing + When reverse geocoding 1.0002,1.0002 + Then the result contains + | object | + | N1 | -- 2.39.5