fix(tradein): map-picker подставляет уличный адрес, а не название POI #418
1 changed files with 40 additions and 0 deletions
|
|
@ -536,11 +536,46 @@ async def geocode(address: str, db: Session) -> GeocodeResult | None:
|
||||||
|
|
||||||
|
|
||||||
# ── Reverse: координаты → адрес (для map-picker'а) ──────────────────────────
|
# ── 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))
|
@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:
|
async def reverse_geocode(lat: float, lon: float) -> str | None:
|
||||||
"""Обратный геокодинг: координаты → адрес (Nominatim /reverse).
|
"""Обратный геокодинг: координаты → адрес (Nominatim /reverse).
|
||||||
|
|
||||||
Клик по дому на карте ЕКБ → адрес подставляется в форму оценки.
|
Клик по дому на карте ЕКБ → адрес подставляется в форму оценки.
|
||||||
|
Возвращаем уличный адрес (улица, дом, город), а не `display_name` —
|
||||||
|
тот начинается с названия POI/организации и не геокодируется обратно.
|
||||||
"""
|
"""
|
||||||
headers = {
|
headers = {
|
||||||
"User-Agent": f"TradeInMVP/0.1 (contact: {settings.contact_email})",
|
"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()
|
data = response.json()
|
||||||
if not isinstance(data, dict) or "error" in data:
|
if not isinstance(data, dict) or "error" in data:
|
||||||
return None
|
return None
|
||||||
|
addr = data.get("address")
|
||||||
|
if isinstance(addr, dict):
|
||||||
|
street = _format_reverse_address(addr)
|
||||||
|
if street:
|
||||||
|
return street
|
||||||
return data.get("display_name")
|
return data.get("display_name")
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue