4

The problem I am trying to solve is to divide a given polygon into smaller polygons based on a given input number (proportion of the polygon).

 Example polygon

In this example, the desired output would be a MultiPolygon composed of the coordinates (geometry) of the orange polygon and the green polygon or something similar.

Also, in this case, the input was 3x. The input is always a given side of the polygon (in this case, the height, x) multiplied or divided by a number (in this case, 3). The remaining area will vary depending on the polygon (here it is 2x).

I have thought about calculating the area of the polygon and then getting the area of the smaller polygons but I do not know how to get the geometry (polygon coordinates) of those smaller polygons. (Also, I do not know if it is possible to do this with PostGIS)

Is there any function or script capable of achieving this?

6
  • 1
    The polygons can be any shape? Does it have to be a straight split line?
    – Bera
    Commented Sep 5, 2023 at 5:49
  • Hi, thank you for your comment! Yes, actually the polygon will represent an agricultural field (so usually they are usually irregular polygons) and the line will be one side of the given polygon multiplied or divided by a number!
    – Belén F.
    Commented Sep 5, 2023 at 6:22
  • 1
    What is the allowable area error of the parts? Commented Sep 5, 2023 at 7:54
  • 2
    Does this answer your question? Splitting polygon into equal area polygons using QGIS You could split it into 5 parts and then merge 3х and 2х together. Commented Sep 5, 2023 at 7:56
  • 3
    For irregular polygonal areas (and with computational completeness in mind) the only way is a heuristic approach, i.e. Voronoi or Delaunay dissection. For near-regular areas a grid based space partitioning might be used, i.e. create the oriented envelope, rotate to axis colinearity, create a grid with cell edge length of x, rotate back and merge the intersecting parts of the Polygon with each cell according to your needs.
    – geozelot
    Commented Sep 5, 2023 at 8:21

1 Answer 1

1

Here's a query that might help you - it is based on the assumption that the Polygons in question are near-rectangular, using their ST_OrientedEnvelope to create a blade at the desired ratio to split them:

SELECT
    id,
    CASE WHEN ST_Area(poly_split.geom) / ST_Area(pd.geom) < 0.5
        THEN 'smaller'
        ELSE 'larger'
    END AS part,
    poly_split.geom
FROM
    <polygon_layer> AS pd,
    LATERAL ST_Boundary(ST_OrientedEnvelope(ST_Buffer(geom, 0.00000000001))) AS obb_bd,
    LATERAL ST_Distance(ST_PointN(obb_bd, 1), ST_PointN(obb_bd, 2)) AS len_min,
    LATERAL ST_Distance(ST_PointN(obb_bd, 2), ST_PointN(obb_bd, 3)) AS len_maj,
    LATERAL ST_MakeLine(ST_PointN(obb_bd, 2), ST_PointN(obb_bd, 3)) AS maj_1,
    LATERAL ST_MakeLine(ST_PointN(obb_bd, 5), ST_PointN(obb_bd, 4)) AS maj_2,
    LATERAL LEAST((len_min * <RATIO>) / len_maj, 1.0) AS rat_frac,
    LATERAL ST_LineInterpolatePoint(maj_1, rat_frac) AS blade_sp,
    LATERAL ST_LineInterpolatePoint(maj_2, rat_frac) AS blade_ep,
    LATERAL ST_MakeLine(blade_sp, blade_ep) AS blade_ln,
    LATERAL ST_Dump(ST_Split(geom, blade_ln)) AS poly_split
;

I kept it verbose, using LATERAL expressions to run a sequence of geometric computations needed to create the blade, where

  • we introduce a tiny ST_Buffer around the original Polygons to avoid precision issues during the split operation
  • we extract the ST_Boundary to access its vertices - note the reversed vertex order for the second ST_MakeLine in the next step
  • we create the major axii maj_1 & maj_2 - this is where you can decide along what sides of the Polygons the ratio is calculated; create the minor axii if that is what you want
  • we calculate the ratio_frac at which we ST_LineInterpolatePoint the blade start and end points of the blade - this is where you need to come up with a <RATIO>; note that we always fall back to 1.0 for cases where the ratio exceeds the axis lengths!
  • we ST_Split the Polygons with the created blade_ln and ST_Dump its results into individual Polygon parts

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