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.

  • It seems like a complicated question. Maybe you can try to create segments with the bisector of your junctions in both directions (like if your were creating an arrow top for the green line), and get the first point that cut the polygon to create the 2 point that delemit the end of the small river ? I think getting those 2 points is the most difficult, once you have them you can use the line between the 2 as the separator between the 2 rivers, and the rest should be easy. Commented Feb 9, 2022 at 11:00
  • Thank you @robinloche for the arrow idea. I could get the direction of last point of the green line and then create two line from this point (like arrow has). Then it would be possible to intersect these arrow lines with polygon and get intersection points. I will try this approach and give feedback on this.
    – Andrius
    Commented Feb 9, 2022 at 13:51

1 Answer 1


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
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
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


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.