From 90bfd00a821ae9aac9f9716e2587fbaae69f9047 Mon Sep 17 00:00:00 2001 From: Kyle Pope Date: Tue, 17 Mar 2026 13:28:02 +0800 Subject: [PATCH] Fix Nominatim stripping house numbers from location names Use addressdetails=1 to get structured address components and build the name as "123 Example St" instead of splitting display_name on the first comma (which isolated the house number from the road). Co-Authored-By: Claude Opus 4.6 (1M context) --- backend/app/routers/locations.py | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/backend/app/routers/locations.py b/backend/app/routers/locations.py index 30ab340..ed09b32 100644 --- a/backend/app/routers/locations.py +++ b/backend/app/routers/locations.py @@ -57,7 +57,7 @@ async def search_locations( # Nominatim proxy search (run in thread executor to avoid blocking event loop) def _fetch_nominatim() -> list: encoded_q = urllib.parse.quote(q) - url = f"https://nominatim.openstreetmap.org/search?q={encoded_q}&format=json&limit=5" + url = f"https://nominatim.openstreetmap.org/search?q={encoded_q}&format=json&addressdetails=1&limit=5" req = urllib.request.Request(url, headers={"User-Agent": "UMBRA-LifeManager/1.0"}) with urllib.request.urlopen(req, timeout=5) as resp: return json.loads(resp.read().decode()) @@ -67,9 +67,26 @@ async def search_locations( osm_data = await loop.run_in_executor(None, _fetch_nominatim) for item in osm_data: display_name = item.get("display_name", "") - name_parts = display_name.split(",", 1) - name = name_parts[0].strip() - address = name_parts[1].strip() if len(name_parts) > 1 else display_name + addr = item.get("address", {}) + house_number = addr.get("house_number", "") + road = addr.get("road", "") + # Build a name that preserves the house number + if house_number and road: + name = f"{house_number} {road}" + elif road: + name = road + else: + # Fallback: first comma-separated segment + name = display_name.split(",", 1)[0].strip() + # Address: everything after the street portion + name_prefix = f"{house_number}, " if house_number else "" + road_prefix = f"{road}, " if road else "" + strip_prefix = name_prefix + road_prefix + if strip_prefix and display_name.startswith(strip_prefix): + address = display_name[len(strip_prefix):].strip() + else: + name_parts = display_name.split(",", 1) + address = name_parts[1].strip() if len(name_parts) > 1 else display_name results.append( LocationSearchResult( source="nominatim",