[tradein][bug] Несовпадение адресов: target point / address vs реальность по Яндекс.Картам и 2ГИС #582

Closed
opened 2026-05-25 06:10:58 +00:00 by lekss361 · 0 comments
Owner

Проблема

Для target адреса в трейд-ин flow наблюдается рассогласование:

  • Адрес в нашей БД (listings.address / houses.address / rosreestr_deals.addr_street) — одно значение.
  • Координаты (lat/lon), привязанные к этому адресу — указывают на другую точку на карте.
  • При reverse-lookup этих координат через Яндекс.Карты / 2ГИС возвращается третий вариант адреса (часто корректный, но иной нормализации).

Результат: пользователь видит на карте маркер не там, где улица из адреса; "По вашей улице" в StreetDealsCard может цеплять не ту улицу; матчинг listings ↔ rosreestr_deals по адресу страдает.

Гипотезы корня (надо проверить)

  1. Геокодинг с разных источников = разные точки — listings из avito/cian/yandex геокодятся каждым источником по-своему, мы пишем то что отдал источник. У 2ГИС координаты могут отличаться от Яндекс на 30-100м для того же здания.
  2. Нормализация адресовextract_street_name() (PR #557 уже фиксил Nominatim reverse format) может для одного и того же дома отдавать разные строки между источниками. Префиксы «г.» / «Екатеринбург» / «620XXX» — не везде вычищены.
  3. Point on building polygon mismatch — у Avito точка — entrance, у Yandex — центроид здания, у Rosreestr — центроид кадастрового участка (может быть со двором/двумя домами).
  4. rosreestr_deals.lat/lon NULL (см. #569) — пока не заполнены, fallback на улицу-уровень даёт сдвиг.

Что сделать

Phase 1 — Audit (sample 50 адресов EKB)

Эти источники для одного и того же дома:

  • avito listing(cad_num + address + lat/lon)
  • cian listing (то же)
  • yandex listing (то же)
  • rosreestr_deals (по street + cad_block)
  • наш house row (после fingerprint match)

Через mcp__playwright__*:

  • запрос reverse geocode в Яндекс.Картах по нашим lat/lon → что они скажут?
  • то же в 2ГИС

Таблица address_mismatch_audit:

| our_address | our_lat | our_lon | yandex_address_at_point | dgis_address_at_point | distance_to_yandex_point_m | distance_to_dgis_point_m |

Phase 2 — Define canonical

Решить: какой источник — source of truth для (address, point) пары?

  • Вариант A: Яндекс reverse (через Yandex Maps Geocoder API)
  • Вариант B: 2ГИС (есть REST API)
  • Вариант C: Nominatim self-hosted
  • Вариант D: ФИАС/ГАР федеральный (но не отдаёт точку)

Критерий выбора: меньшее median расстояние от "истинного входа" + полнота покрытия EKB.

Phase 3 — Backfill

Переписать lat/lon всех listings + houses + rosreestr_deals по canonical reverse-геокодеру. Запустить через scheduler (см. #559 EPIC).

Phase 4 — Address normalizer

Единая функция canonical_address(raw_addr, lat, lon) — возвращает строку из canonical источника по точке. Все scrapers вызывают её перед INSERT.

Phase 5 — UI marker

Frontend: маркер на карте должен совпадать с подписью адреса в карточке. Сейчас визуальное несоответствие — user сообщил, видит маркер не там, где улица.

Acceptance

  • 95% sample (200 random EKB houses): расстояние между our_lat/lon и Яндекс reverse-результатом для our_address ≤ 50м.
  • UI marker и текст карточки визуально совпадают (manual QA через playwright screenshots).
  • Никаких случаев когда address.street указывает на одну улицу, а point — на параллельную.

Refs

  • #557 (extract_street_name Nominatim reverse fix)
  • #569 (Rosreestr geocoding автоматизация)
  • #564 (sales-vs-listings матчинг по адресу) — этот баг ломает точность linkage
  • services/matching/houses.py (fingerprint matching)
  • house_address_aliases table
## Проблема Для target адреса в трейд-ин flow наблюдается **рассогласование**: - **Адрес в нашей БД** (`listings.address` / `houses.address` / `rosreestr_deals.addr_street`) — одно значение. - **Координаты** (`lat/lon`), привязанные к этому адресу — указывают на **другую точку** на карте. - При reverse-lookup этих координат через **Яндекс.Карты / 2ГИС** возвращается **третий вариант** адреса (часто корректный, но иной нормализации). Результат: пользователь видит на карте маркер не там, где улица из адреса; "По вашей улице" в `StreetDealsCard` может цеплять не ту улицу; матчинг listings ↔ rosreestr_deals по адресу страдает. ## Гипотезы корня (надо проверить) 1. **Геокодинг с разных источников = разные точки** — listings из avito/cian/yandex геокодятся каждым источником по-своему, мы пишем то что отдал источник. У 2ГИС координаты могут отличаться от Яндекс на 30-100м для того же здания. 2. **Нормализация адресов** — `extract_street_name()` (PR #557 уже фиксил Nominatim reverse format) может для одного и того же дома отдавать разные строки между источниками. Префиксы «г.» / «Екатеринбург» / «620XXX» — не везде вычищены. 3. **Point on building polygon mismatch** — у Avito точка — entrance, у Yandex — центроид здания, у Rosreestr — центроид кадастрового участка (может быть со двором/двумя домами). 4. **rosreestr_deals.lat/lon NULL** (см. #569) — пока не заполнены, fallback на улицу-уровень даёт сдвиг. ## Что сделать ### Phase 1 — Audit (sample 50 адресов EKB) Эти источники для одного и того же дома: - avito listing(`cad_num` + `address` + `lat/lon`) - cian listing (то же) - yandex listing (то же) - rosreestr_deals (по street + cad_block) - наш house row (после fingerprint match) Через `mcp__playwright__*`: - запрос reverse geocode в Яндекс.Картах по нашим `lat/lon` → что они скажут? - то же в 2ГИС Таблица `address_mismatch_audit`: ``` | our_address | our_lat | our_lon | yandex_address_at_point | dgis_address_at_point | distance_to_yandex_point_m | distance_to_dgis_point_m | ``` ### Phase 2 — Define canonical Решить: какой источник — source of truth для (address, point) пары? - Вариант A: Яндекс reverse (через Yandex Maps Geocoder API) - Вариант B: 2ГИС (есть REST API) - Вариант C: Nominatim self-hosted - Вариант D: ФИАС/ГАР федеральный (но не отдаёт точку) Критерий выбора: меньшее median расстояние от "истинного входа" + полнота покрытия EKB. ### Phase 3 — Backfill Переписать `lat/lon` всех listings + houses + rosreestr_deals по canonical reverse-геокодеру. Запустить через scheduler (см. #559 EPIC). ### Phase 4 — Address normalizer Единая функция `canonical_address(raw_addr, lat, lon)` — возвращает строку из canonical источника по точке. Все scrapers вызывают её перед INSERT. ### Phase 5 — UI marker Frontend: маркер на карте должен совпадать с подписью адреса в карточке. Сейчас визуальное несоответствие — user сообщил, видит маркер не там, где улица. ## Acceptance - 95% sample (200 random EKB houses): расстояние между `our_lat/lon` и Яндекс reverse-результатом для `our_address` ≤ 50м. - UI marker и текст карточки визуально совпадают (manual QA через playwright screenshots). - Никаких случаев когда `address.street` указывает на одну улицу, а point — на параллельную. ## Refs - #557 (`extract_street_name` Nominatim reverse fix) - #569 (Rosreestr geocoding автоматизация) - #564 (sales-vs-listings матчинг по адресу) — этот баг ломает точность linkage - `services/matching/houses.py` (fingerprint matching) - `house_address_aliases` table
lekss361 added the
data
bug
tradein
labels 2026-05-25 06:10:58 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#582
No description provided.