Commit graph

2 commits

Author SHA1 Message Date
lekss361
2a47084ee5 feat(#126): Sub-PR A — NSPDClient.get_features_in_bbox_grid + engineering classifier
Add get_features_in_bbox_grid(layer_id, bbox, *, grid_n=7, step_m=50) to NSPDClient:
delegates grid_n×grid_n WMS GetFeatureInfo calls via NSPDBulkClient.wms_feature_info
(async httpx + Semaphore(3)), deduplicates by feature_id/cad_num/reg_numb_border.

Deprecate get_features_in_bbox (single-pixel, 0-3 results) in docstring — not removed,
used by search_by_quarter (Sub-PR B).

Add classify_engineering_kind(properties) in nspd_denorm.py — regex classifier for
layer 36328 structures: water/sewage/gas/heat/electric/other.

Tests: 31 unit tests (mock-based, no live HTTP), 1 integration skip placeholder.
Foundation only — no behaviour change in harvest_quarter (Sub-PR B).
2026-05-17 08:44:01 +03:00
lekss361
db1ff5b1fc feat(nspd): denorm nspd_parcels + nspd_buildings tables (#94 PR3 of 4)
- data/sql/99_nspd_entities_denorm.sql: 2 tables (cad_num PK) + 6 indexes
  (quarter_cad, GIST geom, partial WHERE purpose ILIKE '%многокв%')
- nspd_denorm.py: denorm_parcel_feature / denorm_building_feature / denorm_dump
  - SAVEPOINT per row via with db.begin_nested()
  - ST_Transform(ST_SetSRID(ST_GeomFromGeoJSON(:geom), 3857), 4326)
  - json.dumps(geom, ensure_ascii=False) for psycopg bind
  - All CAST(:x AS type) — no :type
- nspd_sync.py: inline denorm after _upsert_dump in harvest_quarter (non-fatal)
- nspd_denorm_backfill.py: Celery one-shot task (per-quarter commit)
- admin_etl.py: POST /api/v1/admin/etl/nspd-denorm-backfill (AdminTokenAuth)
- 19 tests: coerce helpers, denorm parcel/building, aggregate counts

Foundation for downstream features (МКД neighbors lookup, parcel attrs).

Part of #94
2026-05-16 20:20:03 +03:00