fix(tradein): map-picker подставляет уличный адрес, а не название POI #418

Merged
lekss361 merged 1 commit from fix/tradein-reverse-geocode-street into main 2026-05-22 08:36:29 +00:00
Showing only changes of commit a7a3831ce7 - Show all commits

View file

@ -536,11 +536,46 @@ async def geocode(address: str, db: Session) -> GeocodeResult | None:
# ── Reverse: координаты → адрес (для map-picker'а) ──────────────────────────
def _format_reverse_address(addr: dict) -> str | None:
"""Собирает чистый уличный адрес из Nominatim address-объекта.
Nominatim `display_name` ведёт с названия ближайшего POI/организации
(«NataliOlympic, 2к1, Трамвайный переулок, »). Для map-picker'а это
ломает кейс: такой адрес нельзя forward-геокодировать обратно и оценка
не находит аналогов. Берём именно улицу + дом + город.
Возвращает None если в объекте нет улицы тогда вызывающий код
откатывается на display_name.
"""
road = (
addr.get("road")
or addr.get("pedestrian")
or addr.get("footway")
)
if not road:
return None
house = addr.get("house_number")
city = (
addr.get("city")
or addr.get("town")
or addr.get("village")
or addr.get("municipality")
)
parts: list[str] = [str(road)]
if house:
parts.append(str(house))
if city:
parts.append(str(city))
return ", ".join(parts)
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=1, max=8))
async def reverse_geocode(lat: float, lon: float) -> str | None:
"""Обратный геокодинг: координаты → адрес (Nominatim /reverse).
Клик по дому на карте ЕКБ адрес подставляется в форму оценки.
Возвращаем уличный адрес (улица, дом, город), а не `display_name`
тот начинается с названия POI/организации и не геокодируется обратно.
"""
headers = {
"User-Agent": f"TradeInMVP/0.1 (contact: {settings.contact_email})",
@ -562,4 +597,9 @@ async def reverse_geocode(lat: float, lon: float) -> str | None:
data = response.json()
if not isinstance(data, dict) or "error" in data:
return None
addr = data.get("address")
if isinstance(addr, dict):
street = _format_reverse_address(addr)
if street:
return street
return data.get("display_name")