gendesign/data/sql/140_ekb_krt_geometry.sql
bot-backend 86b9a5a197
All checks were successful
Deploy / changes (push) Successful in 9s
Deploy / build-backend (push) Successful in 1m21s
Deploy / build-frontend (push) Has been skipped
Deploy / build-worker (push) Successful in 2m26s
Deploy / deploy (push) Successful in 1m13s
perf(sf): КРТ-геометрия в БД, _krt_at из БД вместо живого WFS (#1139)
Co-authored-by: bot-backend <bot-backend@gendsgn.local>
Co-committed-by: bot-backend <bot-backend@gendsgn.local>
2026-06-07 12:14:35 +00:00

75 lines
4.8 KiB
PL/PgSQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 140_ekb_krt_geometry.sql
-- #1130 (Site Finder v2 / GG-форсайт) — КРТ-геометрии геопортала ЕКБ в БД.
--
-- Слой portal_geo_oks_krt («Здания в границах КРТ») → ~48 WFS-фич с Polygon-геометриями.
-- Harvest-воркер (krt_geometry_sync.py) раз в неделю UPSERT-ит сюда все фичи одним bbox-запросом.
-- analyze читает _krt_at через ST_Intersects(geom, point) — без живого WFS-вызова в hot-пути.
--
-- UNIQUE-ключ: feature_id — стабильный строковый id WFS-фичи GeoServer
-- (вида «portal_geo_oks_krt.NNN»; trailing-int выделяется для numeric lookup).
-- Выбор обоснован: GeoServer feature_id стабилен между запросами одного слоя (это PK GeoServer),
-- не зависит от изменяемых атрибутов (num_oks_krt/status/area) и присутствует у каждой фичи.
-- Альтернатива (num_oks_krt+MD5(geom)) нестабильна при минимальных правках геометрии → излишний
-- DELETE+INSERT вместо UPDATE; feature_id надёжнее.
--
-- Deploy: auto-applied deploy.yml через _schema_migrations (ровно один раз по NN).
-- Idempotent (CREATE TABLE/INDEX IF NOT EXISTS + guarded DO-блок для UNIQUE).
-- Зеркалит pattern м.132 (ird_overlays) и м.137 (ekb_krt_sites).
-- Без INSERT — данные приходят из Celery-воркера krt_geometry_sync.
BEGIN;
-- ── 1. Таблица ekb_krt_geometry ──────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS ekb_krt_geometry (
id BIGSERIAL PRIMARY KEY,
feature_id TEXT NOT NULL, -- GeoServer WFS feature id («portal_geo_oks_krt.7»)
num_oks_krt INTEGER, -- порядковый номер КРТ-площадки
full_name TEXT, -- полное наименование (из свойств слоя)
status TEXT, -- статус КРТ («В работе», «Завершён» и т.п.)
geom geometry(Geometry, 4326) NOT NULL, -- полигон КРТ-территории, EPSG:4326
area NUMERIC, -- площадь из свойств (га или кв. м — как в слое)
raw_props JSONB, -- полный properties-объект WFS-фичи (forward-compat)
fetched_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
COMMENT ON TABLE ekb_krt_geometry IS
'Геометрия КРТ-территорий ЕКБ (#1130, GG-форсайт). '
'Источник: WFS-слой portal_geo_oks_krt геопортала ЕКБ (~48 фич). '
'Harvest — Celery krt_geometry_sync раз в неделю (bbox ЕКБ-агломерации). '
'analyze._krt_at читает ST_Intersects(geom, point) вместо живого WFS-вызова.';
COMMENT ON COLUMN ekb_krt_geometry.feature_id IS
'Стабильный GeoServer WFS feature id слоя («portal_geo_oks_krt.7»). UNIQUE ON CONFLICT target.';
COMMENT ON COLUMN ekb_krt_geometry.num_oks_krt IS
'Порядковый номер КРТ-площадки из свойств WFS-фичи (num_oks_krt). NULL если не задан.';
COMMENT ON COLUMN ekb_krt_geometry.geom IS
'Polygon/MultiPolygon КРТ-территории в EPSG:4326 (WFS GeoServer отдаёт в 4326 напрямую).';
-- ── 2. UNIQUE по feature_id (ON CONFLICT target для UPSERT) ─────────────────
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'uq_ekb_krt_geometry_feature_id'
) THEN
ALTER TABLE ekb_krt_geometry
ADD CONSTRAINT uq_ekb_krt_geometry_feature_id
UNIQUE (feature_id);
END IF;
END
$$;
-- ── 3. Индексы ───────────────────────────────────────────────────────────────
-- ГЛАВНЫЙ read-path: ST_Intersects(geom, point) из _krt_at в analyze hot-пути.
CREATE INDEX IF NOT EXISTS idx_ekb_krt_geometry_geom
ON ekb_krt_geometry USING GIST (geom);
-- Lookup по порядковому номеру (JOIN к ekb_krt_sites по num_oks_krt).
CREATE INDEX IF NOT EXISTS idx_ekb_krt_geometry_num_oks_krt
ON ekb_krt_geometry (num_oks_krt)
WHERE num_oks_krt IS NOT NULL;
-- Мониторинг свежести данных.
CREATE INDEX IF NOT EXISTS idx_ekb_krt_geometry_fetched_at
ON ekb_krt_geometry (fetched_at DESC);
COMMIT;