Геокодирование сделок области: ключ (регион, НП, улица) вместо голой улицы #3532

Merged
lekss361 merged 1 commit from fix/oblast-deal-geocoding into main 2026-09-15 17:28:09 +00:00
Owner

Пункт 2 долга: 25 789 сделок области из 113 351 без координат; существующий скрипт строит центроид по названию улицы без города — в области это схлопывает одноимённые улицы разных городов (Центральная, Советская, Молодёжная есть почти везде).

geocode_deals_from_houses.py

  • _street_key понижен до отчётного: ключ сопоставления теперь _address_key(address, region_code, city) → (region_code, НП, улица).
  • Населённый пункт берётся, по приоритету: из типа сегмента адреса (г Химки, д Сабурово, снт …) → из REGIONS[rc].cities → позиционным fallback. deals.city, когда заполнен, перебивает разбор.
  • Пустой НП: у ЕКБ подставляется city_token (город один — ключ осмыслен), у региона 50 ключ отбрасывается, а не склеивается с чужим городом.
  • Хардкод ^екатеринбург$ убран в реестр регионов.
  • Фильтр по региону добавлен в SELECT кандидатов, в запрос домов и в UPDATE — раньше центроид-карта строилась без него.
  • houses.region_code IS NULL принимается через bbox_region; deals.region_code IS NULL — только для 66 (историческая ЕКБ-выборка).
  • Новый --max-spread-km (по умолчанию 5): бакет отбрасывается, если дома в нём дальше порога от центроида — защита от остаточного схлопывания.

geocoder.py

  • _REGION_STATE_MARKERS[50] = "московская" — намеренно НЕ «москва», чтобы московский результат по адресу области честно отклонялся.
  • _DADATA_REGION_NAMES[50] = "Московская" (раньше ValueError).
  • Новое поле Region.has_city_core (False только у 50): _nominatim_query_city_aware перестаёт приклеивать суффикс главного города — раньше склеивало «Сабурово, Луговая, Красногорск».

57 тестов + 3 passed / 1 skipped.

Прогон по проду (--region-code 50, сначала --dry-run) — отдельным шагом после деплоя, в этом PR только код.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NQb6WeJtagZwZnUsSjDizs

Пункт 2 долга: 25 789 сделок области из 113 351 без координат; существующий скрипт строит центроид по названию улицы **без города** — в области это схлопывает одноимённые улицы разных городов (Центральная, Советская, Молодёжная есть почти везде). ## `geocode_deals_from_houses.py` - `_street_key` понижен до отчётного: ключ сопоставления теперь `_address_key(address, region_code, city) → (region_code, НП, улица)`. - Населённый пункт берётся, по приоритету: из типа сегмента адреса (`г Химки`, `д Сабурово`, `снт …`) → из `REGIONS[rc].cities` → позиционным fallback. `deals.city`, когда заполнен, перебивает разбор. - Пустой НП: у ЕКБ подставляется `city_token` (город один — ключ осмыслен), у региона 50 ключ отбрасывается, а не склеивается с чужим городом. - Хардкод `^екатеринбург$` убран в реестр регионов. - Фильтр по региону добавлен в SELECT кандидатов, в запрос домов и в UPDATE — раньше центроид-карта строилась без него. - `houses.region_code IS NULL` принимается через `bbox_region`; `deals.region_code IS NULL` — только для 66 (историческая ЕКБ-выборка). - Новый `--max-spread-km` (по умолчанию 5): бакет отбрасывается, если дома в нём дальше порога от центроида — защита от остаточного схлопывания. ## `geocoder.py` - `_REGION_STATE_MARKERS[50] = "московская"` — намеренно НЕ «москва», чтобы московский результат по адресу области честно отклонялся. - `_DADATA_REGION_NAMES[50] = "Московская"` (раньше `ValueError`). - Новое поле `Region.has_city_core` (False только у 50): `_nominatim_query_city_aware` перестаёт приклеивать суффикс главного города — раньше склеивало «Сабурово, Луговая, Красногорск». 57 тестов + 3 passed / 1 skipped. Прогон по проду (`--region-code 50`, сначала `--dry-run`) — отдельным шагом после деплоя, в этом PR только код. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01NQb6WeJtagZwZnUsSjDizs
lekss361 added 1 commit 2026-09-15 17:09:25 +00:00
Ключ центроида — (регион, НП, улица), иначе Луговая из Сабурово садится в Красногорск
All checks were successful
CI Trade-In / changes (pull_request) Successful in 12s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 15s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 5m32s
6e184fe8fc
geocode_deals_from_houses строил карту центроидов по ВСЕМ houses без фильтра
региона, а ключом было голое имя улицы. По Свердловской области это безвредно
(скрипт жил ЕКБ-only, с хардкодом ^екатеринбург$), по Московской — тихая
катастрофа: «Ленина» / «Центральная» / «Луговая» есть почти в каждом из ~970
НП области, дома со всех одноимённых улиц слипались бы в одно ведро, а среднее
их координат — правдоподобная точка ПОСЕРЕДИНЕ между городами.

- ключ join'а = (region_code, населённый пункт, улица); НП разбирается по типу
  («г Химки», «д Сабурово») или по реестру REGIONS[rc].cities, плюс позиционный
  fallback под формат deals.address по области («Сабурово, Луговая»);
  у deals НП берётся из колонки city (заполнена на 100%).
- фильтр региона в выборке кандидатов, в карте центроидов и в UPDATE;
  houses.region_code IS NULL принимается по bbox_region реестра, deals.region_code
  IS NULL — только для 66 (строки до миграции 177 по построению екатеринбургские).
- sanity-чек разброса: ведро, где дом отстоит от центроида дальше --max-spread-km
  (5 км), выбрасывается — это склейка нескольких НП, а не улица.
- пустой НП у региона без города-ядра (50) → ключа нет; подставлять «Красногорск»
  нельзя, это та же ловушка уровнем выше.

geocoder: регион 50 получил маркер state «московская» (не «москва» — иначе
результат внутри города Москвы, который щедрый bbox_region области накрывает
целиком, принимался бы за областной), имя региона DaData «Московская» и запрет
dual-query с суффиксом главного города (Region.has_city_core=False).
lekss361 merged commit ce60fc214d into main 2026-09-15 17:28:09 +00:00
lekss361 deleted branch fix/oblast-deal-geocoding 2026-09-15 17:28:10 +00:00
Sign in to join this conversation.
No reviewers
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#3532
No description provided.