I want to create a buffer along a line where the buffer width corresponds to a fraction of the length of the line, something like that:
To do that my idea is to compute for each node of the line (except for the first and last node) the bisector angle between the previous and the next segment, example for the node, bisector angle in red #3:
At the moment I'm just trying to create one side (a line) of the buffer:
Here's my attempt:
WITH POINT_LINE AS
(
WITH SUB AS
(
-- Extract all the segments and calculate for each segment the cumulative length
WITH segments AS (
SELECT gid, (pt).path[1]-1 as path, ST_MakeLine(lag((pt).geom, 1, NULL) OVER (PARTITION BY gid ORDER BY gid, (pt).path), (pt).geom) AS geom
FROM (SELECT gid, ST_DumpPoints(geom) AS pt FROM MYLINE) as dumps
)
SELECT
gid,
sum(st_length(geom)) over (order by path asc rows between unbounded preceding and current row)-st_length(geom) as l_start,
sum(st_length(geom)) over (order by path asc rows between unbounded preceding and current row) as l_end,
ST_StartPoint(geom) as g_start,
ST_EndPoint(geom) as g_end,
path,
geom
FROM segments WHERE geom IS NOT NULL
)
SELECT
a.gid,
a.path,
a.l_end,
b.g_start,
-- HERE I try to calculate the bisector angle:
atan((ST_Y(a.g_start)-ST_Y(a.g_end))/(ST_X(a.g_start)-ST_X(a.g_end))) + asin((ST_X(a.g_end)-ST_X(a.g_start))/SQRT((ST_X(a.g_end)-ST_X(a.g_start))^2+(ST_Y(a.g_end)-ST_Y(a.g_start))^2)) as phi,
a.geom
FROM SUB a, SUB b
WHERE a.path = b.path-1
AND a.gid = b.gid
)
-- Intermediate node
SELECT gid, path+1 as path, ST_SetSRID(ST_MakePoint(ST_X(g_start)+cos(phi)*l_end,ST_Y(g_start)+sin(phi)*l_end),2056) as geom
FROM POINT_LINE
UNION
-- First node of the line
SELECT gid, path as path, ST_StartPoint(geom) as geom
FROM POINT_LINE
WHERE path = 1
Unfortunately, the node are not always in the right position, so I guess that my angle is sometimes wrong.
Do you have an idea on how to solve this problem?