feat(analyze): per-category OSRM routing — foot vs driving (#39 A3) #1935

Merged
bot-backend merged 1 commit from feat/39-osrm-per-category into main 2026-06-26 23:43:29 +00:00
Collaborator

Что (A3)

Per-category routing: пешеходные POI считаются по пешему OSRM-графу, авто-POI — по driving. Это убирает завышение пешей доступности driving-профилем (валидация #39: driving-медиана 1.6–2.9× straight-line до близких-пешком POI).

  • walk → foot-граф (osrm-walk, profile=foot): shop_small, pharmacy, shop_supermarket, kindergarten, school, park, bus_stop, tram_stop, metro_stop
  • drive → car-граф (osrm, profile=driving): shop_mall, hospital + любая неизвестная/None категория (безопасный дефолт)

Изменения

  • config: osrm_walk_local_url="http://osrm-walk:5000" + osrm_walk_categories (frozenset, 9 кат).
  • osrm_client_local: опц. base_url на get_road_distances_m (default None → прежнее поведение байт-в-байт).
  • parcels.py _apply_osrm_road_distances: split POI по категории, независимый per-group вызов OSRM с graceful fallback (упал один сервер → его группа остаётся straight-line, другая всё равно заменена), in-place write-back по исходному индексу; никогда не бросает; flag-OFF путь без изменений.
  • docker-compose: сервис osrm-walk (foot-граф, internal-only, mem_limit 1.5g, TCP-healthcheck).
  • build_osrm.sh: CAR=0 гейт — foot-only refresh не трогает живой car-граф.
  • docs/osrm-routing.md: walking-профиль + per-category задокументированы как live.

Состояние графа (прод)

Пеший граф sverdlovsk-foot.osrm* уже собран на VPS (CAR=0 WALK=1, 27 файлов, 1.1G data/osrm) и проверенosrm-routed грузит его и держит (валидный MLD-граф). Полная per-category A/B-валидация (foot vs drive vs straight на реальных POI) — сразу после деплоя, когда osrm-walk поднят.

Проверки

  • ruff check app/ · полный suite 3585 passed · per-category subset 18 passed (вкл. asymmetric intra-group write-back тест).
  • code-reviewer: APPROVE, 0 critical (index write-back / per-group fallback / flag-OFF / null-safe классификация — все трассированы корректными).

Важно

Остаётся flag-gated (use_osrm_distances OFF). Включение — продуктовое решение (см. #39). Этот PR делает флаг честным к включению: при флипе пешие POI получат пешие дистанции, а не завышенные авто.

Refs #39

## Что (A3) Per-category routing: пешеходные POI считаются по **пешему** OSRM-графу, авто-POI — по **driving**. Это убирает завышение пешей доступности driving-профилем (валидация #39: driving-медиана **1.6–2.9×** straight-line до близких-пешком POI). - **walk → foot-граф** (`osrm-walk`, `profile=foot`): `shop_small, pharmacy, shop_supermarket, kindergarten, school, park, bus_stop, tram_stop, metro_stop` - **drive → car-граф** (`osrm`, `profile=driving`): `shop_mall, hospital` + любая неизвестная/None категория (безопасный дефолт) ## Изменения - **config**: `osrm_walk_local_url="http://osrm-walk:5000"` + `osrm_walk_categories` (frozenset, 9 кат). - **osrm_client_local**: опц. `base_url` на `get_road_distances_m` (default None → прежнее поведение байт-в-байт). - **parcels.py `_apply_osrm_road_distances`**: split POI по категории, **независимый** per-group вызов OSRM с graceful fallback (упал один сервер → его группа остаётся straight-line, другая всё равно заменена), in-place write-back по исходному индексу; **никогда не бросает**; flag-OFF путь без изменений. - **docker-compose**: сервис `osrm-walk` (foot-граф, internal-only, `mem_limit 1.5g`, TCP-healthcheck). - **build_osrm.sh**: `CAR=0` гейт — foot-only refresh не трогает живой car-граф. - **docs/osrm-routing.md**: walking-профиль + per-category задокументированы как live. ## Состояние графа (прод) Пеший граф `sverdlovsk-foot.osrm*` **уже собран** на VPS (`CAR=0 WALK=1`, 27 файлов, 1.1G data/osrm) и **проверен** — `osrm-routed` грузит его и держит (валидный MLD-граф). Полная per-category A/B-валидация (foot vs drive vs straight на реальных POI) — сразу после деплоя, когда `osrm-walk` поднят. ## Проверки - `ruff check app/` ✅ · полный suite **3585 passed** · per-category subset **18 passed** (вкл. asymmetric intra-group write-back тест). - `code-reviewer`: **✅ APPROVE**, 0 critical (index write-back / per-group fallback / flag-OFF / null-safe классификация — все трассированы корректными). ## Важно Остаётся **flag-gated** (`use_osrm_distances` OFF). Включение — продуктовое решение (см. #39). Этот PR делает флаг *честным к включению*: при флипе пешие POI получат пешие дистанции, а не завышенные авто. Refs #39
bot-backend added 1 commit 2026-06-26 23:30:55 +00:00
feat(analyze): per-category OSRM routing (foot vs driving) (#39 A3)
All checks were successful
CI / changes (pull_request) Successful in 6s
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 1m46s
CI / backend-tests (pull_request) Successful in 11m55s
8a3bae0cda
Walk-relevant POIs (school/shop/park/kindergarten/pharmacy/stops) now route
via a FOOT OSRM graph (osrm-walk service), car-relevant POIs (mall/hospital +
unknown) keep the DRIVING graph. Validation showed driving overstated
pedestrian-proximity distance — median 1.6-2.9x straight-line (#39).

- config: osrm_walk_local_url + osrm_walk_categories (frozenset, 9 walk cats)
- osrm_client_local: base_url override on get_road_distances_m (default unchanged)
- _apply_osrm_road_distances: split POIs by category, per-group OSRM call with
  independent graceful fallback (one server down -> its group keeps straight-line),
  in-place write-back by original index; never raises; flag-OFF byte-identical
- docker-compose: osrm-walk service (foot graph, internal, mem_limit 1.5g)
- build_osrm.sh: CAR=0 gate for foot-only refresh (doesn't touch live car graph)
- tests: per-category split, per-group fallback, asymmetric intra-group write-back

Still flag-gated (use_osrm_distances OFF) — enabling is a product decision.
Refs #39
bot-backend merged commit 94d3a981c8 into main 2026-06-26 23:43:29 +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#1935
No description provided.