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
