I want to create a buffer along a line where the buffer width correspond 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 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
Infortunately the node are not always at the right position, so I guess that my angle is sometime wrong.
Do you have an idea how to solve this problem.