-- Phase 6: cached proximity scores for fast filter / sort. -- Refreshed by `OsmRefreshViewsCron` (Sun 03:00 ICT) and on admin-trigger. -- For each industrial park, the 3 nearest POI of each priority category. CREATE MATERIALIZED VIEW IF NOT EXISTS "mv_park_nearest_poi" AS SELECT p.id AS park_id, poi.category::text AS category, poi.id AS poi_id, poi.name AS poi_name, ROUND(ST_Distance(p.location::geography, poi.location::geography)::numeric, 0)::int AS distance_m, ROW_NUMBER() OVER ( PARTITION BY p.id, poi.category ORDER BY ST_Distance(p.location::geography, poi.location::geography) ) AS rank FROM "IndustrialPark" p CROSS JOIN LATERAL ( SELECT id, name, category, location FROM "Poi" WHERE "isPublic" = true AND category::text IN ('HOSPITAL','BANK','GAS_STATION','BUS_STATION','METRO_STATION','POLICE') AND ST_DWithin(location::geography, p.location::geography, 5000) ) poi; CREATE INDEX IF NOT EXISTS "mv_park_nearest_poi_park_cat" ON "mv_park_nearest_poi"(park_id, category, rank); CREATE UNIQUE INDEX IF NOT EXISTS "mv_park_nearest_poi_uq" ON "mv_park_nearest_poi"(park_id, category, poi_id); -- Per-province POI density (count by category) for analytics heatmaps. CREATE MATERIALIZED VIEW IF NOT EXISTS "mv_poi_density_by_province" AS SELECT "provinceCode", category::text AS category, COUNT(*)::int AS poi_count FROM "Poi" WHERE "isPublic" = true AND "provinceCode" IS NOT NULL GROUP BY "provinceCode", category; CREATE INDEX IF NOT EXISTS "mv_poi_density_by_province_idx" ON "mv_poi_density_by_province"("provinceCode", category);