123 lines
4.5 KiB
SQL
123 lines
4.5 KiB
SQL
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.';
|