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
x, rotate back and merge the intersecting parts of the Polygon with each cell according to your needs. – geozelot Sep 05 '23 at 08:21