Mercurial > gemma
diff schema/isrs_functions.sql @ 2563:dc4fae4bdb8f
Expose axis snapping tolerance to users
author | Tom Gottfried <tom@intevation.de> |
---|---|
date | Fri, 08 Mar 2019 19:15:47 +0100 |
parents | 73c8762cee60 |
children | 974122125a76 |
line wrap: on
line diff
--- a/schema/isrs_functions.sql Fri Mar 08 18:57:58 2019 +0100 +++ b/schema/isrs_functions.sql Fri Mar 08 19:15:47 2019 +0100 @@ -47,6 +47,7 @@ -- Uses the table waterway.distance_marks_virtual to map ISRS location codes -- to their geo-location. -- Distance marks are assumed to be near the axis. +-- Returns the axis geometry transformed to the best matching UTM zone. CREATE OR REPLACE FUNCTION ISRSrange_axis( stretch isrsrange, tolerance float @@ -135,32 +136,28 @@ LANGUAGE plpgsql STABLE PARALLEL SAFE; --- Clip an area to a stretch given by a pair of ISRS location codes. --- Uses ISRSrange_axis() to retrieve the respective clipped axis used to find --- perpendicular direction at geo-locations of ISRS codes. +-- Clip an area to a stretch given by a geometry representing an axis (e.g. +-- the output of ISRSrange_axis()). +-- Clipping is done by cutting the area in perpendicular direction at +-- the ends of the given axis. -- The area passed as argument is assumed to intersect with the axis -- (use e.g. waterway area or fairway dimensions). -- If a multipolygon is passed, the union of the polygons intersecting with the --- relevant part of the axis is used for clipping. +-- axis is used for clipping. CREATE OR REPLACE FUNCTION ISRSrange_area( - stretch isrsrange, + axis geometry, area geometry ) RETURNS geometry AS $$ WITH - axis_substring AS ( - SELECT ISRSrange_axis(stretch, 5) AS line), - utm_zone AS ( - SELECT best_utm(stretch) AS z), area_subset AS ( -- In case area is a multipolygon, process the union of those -- polygons, which intersect with the axis. The union is to avoid -- problems with invalid/self-intersecting multipolygons SELECT ST_Union(a_dmp.geom) AS area - FROM axis_substring, utm_zone, LATERAL ( - SELECT ST_MakeValid(ST_Transform(geom, z)) AS geom - FROM ST_Dump(area)) AS a_dmp - WHERE ST_Intersects(a_dmp.geom, axis_substring.line) + FROM (SELECT ST_MakeValid(ST_Transform(geom, ST_SRID(axis))) + FROM ST_Dump(area)) AS a_dmp (geom) + WHERE ST_Intersects(a_dmp.geom, axis) ), rotated_ends AS ( SELECT ST_Collect(ST_Scale( @@ -168,11 +165,11 @@ (ST_X(p1) - ST_X(p2)) / 2, (ST_Y(p1) - ST_Y(p2)) / 2), ST_Point(d, d), p1)) AS blade - FROM axis_substring, area_subset, - LATERAL (SELECT i, ST_PointN(line, i) AS p1 + FROM (SELECT i, ST_PointN(axis, i) AS p1 FROM (VALUES (1), (-1)) AS idx (i)) AS ep, - ST_Rotate(ST_PointN(line, i*2), pi()/2, p1) AS ep2 (p2), + ST_Rotate(ST_PointN(axis, i*2), pi()/2, p1) AS ep2 (p2), ST_Makeline(p1, p2) AS e (e), + area_subset, LATERAL (SELECT (ST_MaxDistance(p1, area) / ST_Length(e)) * 2) AS d (d)), range_area AS ( @@ -183,8 +180,7 @@ -- From the polygons returned by the last CTE, select only those -- around the clipped axis SELECT ST_Multi(ST_Transform(ST_Union(range_area.geom), ST_SRID(area))) - FROM axis_substring, range_area - WHERE ST_Intersects(ST_Buffer(range_area.geom, -0.0001), - axis_substring.line) + FROM range_area + WHERE ST_Intersects(ST_Buffer(range_area.geom, -0.0001), axis) $$ LANGUAGE sql;