🐛 NSPD WMS GetFeatureInfo НЕ bulk — Sprint 2 grid sampling fix #126

Closed
opened 2026-05-14 20:26:56 +00:00 by lekss361 · 2 comments
lekss361 commented 2026-05-14 20:26:56 +00:00 (Migrated from github.com)

TL;DR

Sprint 1.1 #94 part 2 shipped с критическим архитектурным дефектом: NSPDClient.get_features_in_bbox НЕ делает bulk fetch как заявлено в docstring. WMS GetFeatureInfo по OGC стандарту возвращает features под одним пикселем (I, J), не во всём BBOX → 0-3 features в типичном квартале вместо ожидаемых десятков.

См. полный post-mortem: vault fixes/Bug_NSPD_WMS_NotBulk_2026_May14.md

Impact

  1. harvest_quarter Celery task пишет почти пустые dumps в nspd_quarter_dumps
  2. quarter_dump_lookup.get_quarter_dump_dataanalyze_parcel отдаёт пустые nspd_zoning / nspd_zouit_overlaps / nspd_engineering_nearby для большинства cad
  3. Mock tests в test_nspd_client.py прошли green — тестировали shape кода, не API contract

Mitigation (already done)

  • Beat schedule nspd-harvest-stale-quarters DISABLED (PR #121, merge pending) — Monday 04:00 МСК запуск не сольёт rate-limit
  • ⚠️ harvest_quarter task code остался — manual trigger через admin endpoint всё ещё пишет пустые dumps. Не использовать до Sprint 2 fix.

Sprint 2 Fix Strategy

Из vault post-mortem — recommended Combo C+B:

Option C — Per-cad enumeration (для buildings/structures)

У нас есть cad_buildings + rosreestr_deals = list cad-номеров. Для каждого делаем search_by_cad(cad_num) — точечно. Покрывает 100% known cads. ~1 день.

Option B — Adaptive grid (для linear infrastructure)

7×7 → если найден feature, плотная 30×30 вокруг hits. Меньше requests при разреженных объектах (ЗОУИТ, red lines, газопроводы). ~2-3 дня.

Tested data quality (1км² test, 15×15 grid step 50м, 225 cells, ~2 мин)

{
  "water":0, "sewage":1, "gas":4, "heat":3, "electric":1, "roads_other":3, "zouit17":8
}

Реальные данные: "Газопровод высокого давления ext=6880м", "КЛ 10/0.4 кВ ТП 64102 → пр-т Седова 53", и т.д.

Classifier (regex по cyrillic — готов из post-mortem)

- r'10[\.\) ].*коммунальн|водопровод|водоснабж'  water
- r'канализ|сток|ливнев'  sewage
- r'газопровод|газоснабж|ГРП|ГК\b'  gas
- r'теплов(ая|ой|ые)|теплосеть|теплоснабж|котельн|ТЭЦ'  heat
- r'электроэнерг|ВЛ[\s-]|ВЛ-?\d|КЛ[\s-]|ЛЭП|подстанц|трансформ|ТП[\s-]?\d'  electric

Acceptance Criteria

  • NSPDClient.get_features_in_bbox → переименовать в sample_features_grid(layer_id, bbox, grid_n=15, step_m=50)
  • Implement adaptive grid (Option B) — 7×7 coarse → 30×30 dense вокруг hits
  • Implement per-cad enumeration (Option C) — для buildings/structures с known cads
  • Add cyrillic classifier для params_purpose → water/sewage/gas/heat/electric
  • Update harvest_quarter task to use new methods + classifier
  • Live test 5+ kvартал ЕКБ перед re-enable beat
  • Re-enable beat schedule в celery_app.py (uncomment) после verify
  • Update mock tests + добавить live API contract test
  • Bug post-mortem: fixes/Bug_NSPD_WMS_NotBulk_2026_May14.md
  • Beat disable PR: #121 (pending merge)
  • Original Sprint 1.1 PRs: #109 / #110 / #111 / #116
  • Vault: research/NSPD_API_Map_May12.md Update part 6 (search-by-quarter works)
  • Foundation issue: #94 (Sprint 1.1 successful, Sprint 1.2 = this fix)
## TL;DR Sprint 1.1 #94 part 2 shipped с критическим архитектурным дефектом: `NSPDClient.get_features_in_bbox` НЕ делает bulk fetch как заявлено в docstring. WMS `GetFeatureInfo` по OGC стандарту возвращает features **под одним пикселем (I, J)**, не во всём BBOX → 0-3 features в типичном квартале вместо ожидаемых десятков. См. полный post-mortem: vault `fixes/Bug_NSPD_WMS_NotBulk_2026_May14.md` ## Impact 1. `harvest_quarter` Celery task пишет **почти пустые dumps** в `nspd_quarter_dumps` 2. `quarter_dump_lookup.get_quarter_dump_data` → `analyze_parcel` отдаёт пустые `nspd_zoning` / `nspd_zouit_overlaps` / `nspd_engineering_nearby` для большинства cad 3. Mock tests в `test_nspd_client.py` прошли green — тестировали shape кода, не API contract ## Mitigation (already done) - ✅ Beat schedule `nspd-harvest-stale-quarters` **DISABLED** (PR #121, merge pending) — Monday 04:00 МСК запуск не сольёт rate-limit - ⚠️ `harvest_quarter` task code остался — manual trigger через admin endpoint всё ещё пишет пустые dumps. Не использовать до Sprint 2 fix. ## Sprint 2 Fix Strategy Из vault post-mortem — recommended **Combo C+B**: ### Option C — Per-cad enumeration (для buildings/structures) У нас есть `cad_buildings` + `rosreestr_deals` = list cad-номеров. Для каждого делаем `search_by_cad(cad_num)` — точечно. Покрывает 100% known cads. ~1 день. ### Option B — Adaptive grid (для linear infrastructure) 7×7 → если найден feature, плотная 30×30 вокруг hits. Меньше requests при разреженных объектах (ЗОУИТ, red lines, газопроводы). ~2-3 дня. ### Tested data quality (1км² test, 15×15 grid step 50м, 225 cells, ~2 мин) ```json { "water":0, "sewage":1, "gas":4, "heat":3, "electric":1, "roads_other":3, "zouit17":8 } ``` Реальные данные: `"Газопровод высокого давления ext=6880м"`, `"КЛ 10/0.4 кВ ТП 64102 → пр-т Седова 53"`, и т.д. ### Classifier (regex по cyrillic — готов из post-mortem) ```python - r'10[\.\) ].*коммунальн|водопровод|водоснабж' → water - r'канализ|сток|ливнев' → sewage - r'газопровод|газоснабж|ГРП|ГК\b' → gas - r'теплов(ая|ой|ые)|теплосеть|теплоснабж|котельн|ТЭЦ' → heat - r'электроэнерг|ВЛ[\s-]|ВЛ-?\d|КЛ[\s-]|ЛЭП|подстанц|трансформ|ТП[\s-]?\d' → electric ``` ## Acceptance Criteria - [ ] `NSPDClient.get_features_in_bbox` → переименовать в `sample_features_grid(layer_id, bbox, grid_n=15, step_m=50)` - [ ] Implement adaptive grid (Option B) — 7×7 coarse → 30×30 dense вокруг hits - [ ] Implement per-cad enumeration (Option C) — для buildings/structures с known cads - [ ] Add cyrillic classifier для `params_purpose` → water/sewage/gas/heat/electric - [ ] Update `harvest_quarter` task to use new methods + classifier - [ ] Live test 5+ kvартал ЕКБ перед re-enable beat - [ ] Re-enable beat schedule в `celery_app.py` (uncomment) после verify - [ ] Update mock tests + добавить live API contract test ## Related - Bug post-mortem: `fixes/Bug_NSPD_WMS_NotBulk_2026_May14.md` - Beat disable PR: #121 (pending merge) - Original Sprint 1.1 PRs: #109 / #110 / #111 / #116 - Vault: `research/NSPD_API_Map_May12.md` Update part 6 (search-by-quarter works) - Foundation issue: #94 (Sprint 1.1 successful, Sprint 1.2 = this fix)
Owner

Status update — issue частично mooted альтернативным путём.

Sprint 2 fix (Option B adaptive grid + Option C per-cad enumeration) НЕ был реализован буквально. Вместо этого выбран прямой bulk cadastre re-ingest через NSPDBulkClient (#168):

  • bulk_harvest_quarter Celery task делает per-category snapshot для известных layer'ов (Phase 1.5 PR #180 — ZOUIT/ENK работают)
  • Grid-walk остаётся только для residual cases (skip для broken quarter geom в PR #179)
  • Cyrillic classifier (water/sewage/gas/heat/electric) пока НЕ реализован — engineering networks остаются TODO

Что ещё нужно сделать (если останется в scope):

  • Cyrillic classifier для params_purpose (см. regex в issue body)
  • Per-cad enumeration (Option C) — для buildings/structures с known cads
  • Re-enable beat schedule nspd-harvest-stale-quarters (всё ещё disabled с PR #121)

Если bulk ingest перекрывает потребности — этот issue можно close.

Status update — issue частично mooted альтернативным путём. Sprint 2 fix (Option B adaptive grid + Option C per-cad enumeration) НЕ был реализован буквально. Вместо этого выбран **прямой bulk cadastre re-ingest** через NSPDBulkClient (#168): - `bulk_harvest_quarter` Celery task делает per-category snapshot для известных layer'ов (Phase 1.5 PR #180 — ZOUIT/ENK работают) - Grid-walk остаётся только для residual cases (skip для broken quarter geom в PR #179) - Cyrillic classifier (water/sewage/gas/heat/electric) пока НЕ реализован — engineering networks остаются TODO **Что ещё нужно сделать (если останется в scope):** - Cyrillic classifier для `params_purpose` (см. regex в issue body) - Per-cad enumeration (Option C) — для buildings/structures с known cads - Re-enable beat schedule `nspd-harvest-stale-quarters` (всё ещё disabled с PR #121) Если bulk ingest перекрывает потребности — этот issue можно close.
Collaborator

DRIFT — реализовано (ground-truth 2026-06-13), трекер отставал.

Grid sampling fix реализован+merged: get_features_in_bbox_grid (adaptive), commits #247+#231 Sub-PR B (fdced94 grid-walk для area layers). nspd_quarter_dumps наполнен. Closed.

**DRIFT — реализовано (ground-truth 2026-06-13), трекер отставал.** Grid sampling fix реализован+merged: get_features_in_bbox_grid (adaptive), commits #247+#231 Sub-PR B (fdced94 grid-walk для area layers). nspd_quarter_dumps наполнен. Closed.
Sign in to join this conversation.
No milestone
No project
No assignees
3 participants
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#126
No description provided.