Split seamless polygon representing river banks into separate polygons using center lines

linepolygonpostgisriverssplitting

I have a polygon that represents river banks. This polygon is seamless for all rivers. And I also have lines of each river. Here is the example of one situation:

enter image description here

Is there a way to split the seamless polygon into separate polygons representing banks of each river? Expected result:

enter image description here

I tried to play with the river buffers but I can't define the exact buffer size because the connection of the rivers can be various widths.

I am using the newest version of PostGIS.

Best Answer

You can create a hexagonal grid covering the river polygons:

create table public.hexgrid as 
with cte as (
select (st_hexagongrid(2.0, geom)).geom as geom --adjust the 2.0, the smaller the smoother split, but longer execution time
from public.riverpoly
)
select row_number() over() as id, geom from cte
;
create index hexgrid_idx on public.hexgrid using GIST(geom)
;

Intersect (clip) this with the river polygons:

create table public.hexclip as
select hex.id, st_intersection(poly.geom, hex.geom) as geom
from public.riverpoly poly
join
public.hexgrid hex
on st_intersects(poly.geom, hex.geom);
create index hexclip_idx on public.hexclip using GIST(geom);

Join the closest river line id to each hexagon and union by river id:

create table public.splitriver as
with cte as (
select distinct on (hex.id) line.id as lineid, st_distance(hex.geom, line.geom), hex.geom
from public.hexclip hex
join
public.riverline line
on st_dwithin(hex.geom, line.geom, 50) --You might need to pick a higher search distance if you have wide rivers
order by hex.id, st_distance(hex.geom, line.geom)
)
select lineid, st_union(geom) as geom from cte
group by lineid

enter image description here