Search code examples
pythonpostgresqlpostgisgeojsonshapely

How to merge multipolygon into one smoothly


I have multipolygon consisting two polygons. How can I merge them with a simple script so they would make polygon instead of multipolygon? I need to connect them even if it would cover the unneeded area. Also need this to work with n polygons in multipolygon.

For better understanding I need a single polygon instead of multipolygon, because multipolygon is

[[x,y],[x,y],[x,y], [x,y],[x,y],[x,y], [x,y],[x,y],[x,y]]

but I need

[[x,y],[x,y],[x,y]]

Check this image for reference

I have tried to use python shapely for doing this, but no luck.


Solution

  • ST_ConcaveHull is what you're looking for. This function calculates the concave geometry of a given geometry (its vertices) and returns a single geometry.

    Consider the following MultiPolygon

    MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)), ((20 35, 45 20, 30 5, 10 10, 10 30, 20 35), (30 20, 20 25, 20 15, 30 20)))
    

    enter image description here

    The function ST_ConcaveHull expects a second parameter, which sets the concaveness of the computed hull:

    The param_pctconvex controls the concaveness of the computed hull. A value of 1 produces the convex hull. A value of 0 produces a hull of maximum concaveness (but still a single polygon). Values between 1 and 0 produce hulls of increasing concaveness. Choosing a suitable value depends on the nature of the input data, but often values between 0.3 and 0.1 produce reasonable results.

    Check which value for param_pctconvex best fits your use case. Setting it to 0.1 gives you the following polygon:

    WITH j (geom) AS  (
      VALUES ('SRID=4326;MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)), 
                         ((20 35, 45 20, 30 5, 10 10, 10 30, 20 35), 
                         (30 20, 20 25, 20 15, 30 20)))'::geometry)
    )
    SELECT ST_ConcaveHull(geom,0.1) FROM j
    

    enter image description here

    Alternatively you can set a third (boolean) parameter to allow holes in the output:

    The polygon will not contain holes unless the optional param_allow_holes argument is specified as true