DO $$ DECLARE layer RECORD; BEGIN FOR layer IN SELECT * FROM (VALUES ('fx_20200423_drain_valves', 'fx_20200423_drain_valves', 'Point'), ('fx_20200423_service_connections', 'fx_20200423_service_connections', 'Point'), ('fx_20200423_flow_meters', 'fx_20200423_flow_meters', 'Point'), ('fx_20200423_hydrants', 'fx_20200423_hydrants', 'Point'), ('fx_20200423_customer_meters', 'fx_20200423_customer_meters', 'Point'), ('fx_20200423_pipes', 'fx_20200423_pipes', 'LineString'), ('fx_20200423_valves', 'fx_20200423_valves', 'Point'), ('fx_20200423_non_residential_meters', 'fx_20200423_non_residential_meters', 'Point'), ('fx_20200811_dn100_pipes', 'fx_20200811_dn100_pipes', 'LineString') ) AS configured(view_name, layer_key, geometry_type) LOOP IF to_regclass(format('gis.%I', layer.view_name)) IS NULL THEN EXECUTE format( $view$ CREATE MATERIALIZED VIEW gis.%I AS SELECT feature.source_fid::text AS id, feature.source_fid, feature.source_object_id, feature.source_diameter AS diameter, CASE WHEN GeometryType(feature.geom) IN ('LINESTRING', 'MULTILINESTRING') THEN ST_Length(feature.geom) ELSE NULL END AS length, dataset.dataset_key, dataset.title AS dataset_title, dataset.source_date, source_layer.layer_key AS source_layer_key, source_layer.display_name AS source_layer_name, source_layer.feature_kind, ST_Transform(feature.geom, 3857)::geometry(%s, 3857) AS geom FROM source_gis.features AS feature JOIN source_gis.layers AS source_layer ON source_layer.layer_key = feature.layer_key JOIN source_gis.datasets AS dataset ON dataset.dataset_key = source_layer.dataset_key WHERE feature.layer_key = %L AND feature.geom IS NOT NULL WITH DATA $view$, layer.view_name, layer.geometry_type, layer.layer_key ); END IF; EXECUTE format( 'CREATE UNIQUE INDEX IF NOT EXISTS %I ON gis.%I (id)', 'ux_' || layer.view_name || '_id', layer.view_name ); EXECUTE format( 'CREATE INDEX IF NOT EXISTS %I ON gis.%I USING GIST (geom)', 'ix_' || layer.view_name || '_geom', layer.view_name ); END LOOP; END $$; DROP VIEW IF EXISTS gis.water_quality_monitoring_points; CREATE VIEW gis.water_quality_monitoring_points AS WITH latest_result AS ( SELECT run.run_id, run.name AS source_analysis, run.created_at, result.payload FROM analysis.runs AS run JOIN LATERAL ( SELECT stored.payload FROM analysis.results AS stored WHERE stored.run_id = run.run_id AND stored.result_type = 'sensor_placement' ORDER BY stored.created_at DESC, stored.result_id DESC LIMIT 1 ) AS result ON true WHERE run.run_type = 'sensor_placement' AND run.status = 'completed' AND result.payload->>'sensor_type' = 'water_quality' AND jsonb_typeof(result.payload->'sensor_locations') = 'array' ORDER BY run.created_at DESC, run.run_id DESC LIMIT 1 ), ranked_locations AS ( SELECT latest.run_id, latest.source_analysis, latest.created_at, latest.payload, location.node_id, location.rank FROM latest_result AS latest CROSS JOIN LATERAL jsonb_array_elements_text( latest.payload->'sensor_locations' ) WITH ORDINALITY AS location(node_id, rank) ) SELECT ranked.node_id AS id, ranked.node_id, ranked.rank::integer AS monitoring_point_no, ranked.run_id, ranked.source_analysis, ranked.created_at, ranked.payload->>'method' AS selection_method, (ranked.payload->>'minimum_diameter')::integer AS minimum_diameter, junction.elevation, junction.geom FROM ranked_locations AS ranked JOIN gis.junctions AS junction ON junction.id = ranked.node_id; COMMENT ON VIEW gis.water_quality_monitoring_points IS 'Current water-quality monitoring points selected by the sensitivity service.';