Московская область в реестре регионов, обход — по специфичности вместо кода #3501
Merged
lekss361
merged 1 commit from 2026-09-12 13:59:44 +00:00
feat/region-50-registry into main
1 commit
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
18add6d667 |
feat(regions): регион 50 в реестре + обход по специфичности вместо кода региона
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / changes (pull_request) Successful in 12s
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 5m36s
Московская область заводится в реестр покрытия. Это предусловие для импорта 411 056 сделок Росреестра, которые лежат в FDW нетронутыми: импорт валидирует region_code по REGIONS, и без записи в реестре не стартует. ## Обход реестра больше не по коду региона region_for_point шёл по sorted(REGIONS) — «первый по коду выигрывает». Докстринг называл это страховкой «на случай, если регионы когда-нибудь пересекутся». Случай наступил прямо здесь: прямоугольник области содержит прямоугольник Москвы целиком, а 50 меньше 77. Наивное добавление отправило бы ВСЕ московские точки в регион 50, включая центр — и это доехало бы до оценки, estimator.py:4862 берёт отсюда скоуп коридора ДКП, а сделок по области ноль. Ключ сортировки — площадь bbox_region по возрастанию: вложенный регион всегда проверяется раньше объемлющего, и следующий новый регион встанет на место сам, без правки этого места. Порядок стал (77, 50, 66). region_by_city оставлен по коду осознанно: там точное сравнение строки, а не вложенность прямоугольников, и тот же класс бага возможен только при дубле имени города между регионами. Дублей нет, это закреплено тестом. ## Границы области — по данным, а не по карте У области нет города-ядра, поэтому tight/wide/product_core здесь не «город плюс отступ», а эмпирический пояс: разброс координат 45 294 подмосковных карточек Циана. product_core взят по перцентилям 0.5..99.5, wide — полный наблюдённый диапазон. Административный bbox стоит только в bbox_region, где он и нужен как fallback-accept. Обещать охват продукта там, где нет ни одного объявления, нельзя — поэтому product_code намеренно уже административной границы. Тиров обогащения у области нет ни одного, frozenset() пуст намеренно. canonical_city=None: источники по области несут настоящий город (Химки, Балашиха), в отличие от Москвы, где Росреестр отдаёт округ или поселение. ## Известное ограничение, которое этот PR НЕ чинит По координате Химки и Балашиха резолвятся в 77, а не в 50. Это свойство прямоугольника, а не выбранного порядка: любой прямоугольник, содержащий и Зеленоград, и центр Москвы, покоординатно содержит Химки. Замер по собранным московским карточкам ДомКлика подтверждает — Москва реально дотягивается до долготы 37.95 (восточнее центра Балашихи) и до широты 56.01. Масштаб: из 24 784 подмосковных объявлений Циана 18 288 лежат внутри московского прямоугольника. Хуже от этого PR не стало — до него они резолвились туда же, просто без конкурента. Оставшиеся 6 496 раньше не резолвились никуда и падали в дефолтный регион 66, то есть в Свердловскую область; теперь встают в 50. Практическое следствие для следующего шага: импорт подмосковных объявлений обязан брать регион из города, а не из координаты. По имени Химки, Балашиха и Красногорск разрешаются верно. Настоящее решение — граница полигоном вместо прямоугольника (#3052). ## Тесты Регрессия на порядок: центр Москвы, Зеленоград и Новая Москва остаются в 77; Серпухов, Дмитров, Электросталь встают в 50; Екатеринбург не тронут. Известное ограничение закреплено отдельным тестом, а не замолчано. Существующий test_regions_do_not_overlap получил исключение для пары (50,77) — вложенность реальна. Исключение не голословно: перед ним стоит проверка, что bbox_region(50) действительно содержит bbox_region(77) как множество. Выедет 77 за границы области — тест упадёт с понятной причиной, а не пропустит настоящее пересечение через список исключений. 81 passed по регионным файлам, ruff чистый. Claude-Session: https://claude.ai/code/session_01NQb6WeJtagZwZnUsSjDizs |