diff --git a/extras/profile/README.md b/extras/profile/README.md new file mode 100644 index 0000000..17b83ae --- /dev/null +++ b/extras/profile/README.md @@ -0,0 +1,20 @@ +# Stream profile + +Extracting a stream profile and/or gradient from FWA geometries is a straightforward, but often repeated task. +Run the required query once and materialize the result in table `whse_basemapping.fwa_stream_profiles` for re-use. + +## Process + + ./process.sh + +## Output + + Table "whse_basemapping.fwa_stream_profiles" + Column | Type | Collation | Nullable | Default + --------------------------+------------------+-----------+----------+--------- + blue_line_key | integer | | | + downstream_route_measure | double precision | | | + upstream_route_measure | double precision | | | + downstream_elevation | double precision | | | + upstream_elevation | double precision | | | + diff --git a/extras/profile/process.sh b/extras/profile/process.sh new file mode 100755 index 0000000..6f043eb --- /dev/null +++ b/extras/profile/process.sh @@ -0,0 +1,16 @@ +set -euxo pipefail + +PSQL="psql $DATABASE_URL -v ON_ERROR_STOP=1" +WSGS=$($PSQL -AXt -c "SELECT watershed_group_code FROM whse_basemapping.fwa_watershed_groups_poly") + +$PSQL -c "drop table if exists whse_basemapping.fwa_stream_profiles" +$PSQL -c "create table whse_basemapping.fwa_stream_profiles ( + blue_line_key integer, + downstream_route_measure double precision, + upstream_route_measure double precision, + downstream_elevation double precision, + upstream_elevation double precision + ); + " + +parallel $PSQL -f sql/fwa_stream_profiles.sql -v wsg={1} ::: $WSGS \ No newline at end of file diff --git a/extras/profile/sql/fwa_stream_profiles.sql b/extras/profile/sql/fwa_stream_profiles.sql new file mode 100644 index 0000000..2bb87c3 --- /dev/null +++ b/extras/profile/sql/fwa_stream_profiles.sql @@ -0,0 +1,60 @@ +-- extract coordinates from streams +insert into whse_basemapping.fwa_stream_profiles ( + blue_line_key, + downstream_route_measure, + upstream_route_measure, + downstream_elevation, + upstream_elevation +) + +with coordinates as ( + select + blue_line_key, + downstream_route_measure, + linear_feature_id, + edge_type, + (st_dumppoints(geom)).path[1] as node_id, + (st_dumppoints(geom)).geom as geom + from whse_basemapping.fwa_stream_networks_sp + where watershed_group_code = :'wsg' +), + +-- extract elevation of each point and determine distances between each point +lengths as ( + select + blue_line_key, + downstream_route_measure, + linear_feature_id, + edge_type, + node_id, + st_z(geom) as elevation_from, + st_z(lead(geom) OVER(ORDER BY blue_line_key, downstream_route_measure, node_id)) as elevation_to, + st_distance(geom, lead(geom) OVER(ORDER BY blue_line_key, downstream_route_measure, node_id)) as length + from coordinates + order by blue_line_key, downstream_route_measure, node_id +), + +-- derive measure of at upstream point +-- drop duplicates at geometry endpoints (where length is 0) +-- drop the final vertex (where length is null) +tidy as ( + select + row_number() over() as id, + blue_line_key, + linear_feature_id, + edge_type, + round((downstream_route_measure + sum(length) over (order by blue_line_key, downstream_route_measure, node_id))::numeric, 2) as upstream_route_measure, + round(elevation_from::numeric, 2) as elevation_from, + round(elevation_to::numeric, 2) as elevation_to + from lengths + where length !=0 and length is not null + order by blue_line_key, downstream_route_measure, node_id +) + +select + blue_line_key, + lag(upstream_route_measure, 1, 0) over (order by id) as downstream_route_measure, + upstream_route_measure, + elevation_from as downstream_elevation, + elevation_to as upstream_elevation +from tidy;