[PostGIS] #6135: ST_GeneratePoints can return a different number of points than requested for MultiPolygons
PostGIS
trac at osgeo.org
Fri Sep 25 11:18:54 PDT 2026
#6135: ST_GeneratePoints can return a different number of points than requested
for MultiPolygons
---------------------+---------------------------
Reporter: Henni | Owner: pramsey
Type: defect | Status: new
Priority: medium | Milestone: PostGIS 3.6.5
Component: postgis | Version: 3.6.x
Keywords: |
---------------------+---------------------------
Hi,
I noticed that `ST_GeneratePoints(multipolygon, n)` does not always return
`n` points, and for `n = 1` it can return NULL. I may be misreading the
intended behaviour, but the docs suggest exactly `n` points are expected.
**Version:**
PostGIS 3.5.3 and 3.6.1 (via imresamu/postgis linux/arm64 docker image)
**Reproduction** (three equal squares):
{{{
WITH g AS (
SELECT 'MULTIPOLYGON(((0 0,1 0,1 1,0 1,0 0)),
((2 0,3 0,3 1,2 1,2 0)),
((4 0,5 0,5 1,4 1,4 0)))'::geometry AS geom
)
SELECT n AS requested, ST_NumGeometries(ST_GeneratePoints(geom, n)) AS
returned
FROM g, generate_series(1, 6) AS n;
}}}
{{{
| requested | returned |
| --------- | -------- |
| 1 | NULL |
| 2 | 3 |
| 3 | 3 |
| 4 | 3 |
| 5 | 6 |
| 6 | 6 |
}}}
The seeded variant `ST_GeneratePoints(geom, n, 42)` behaves the same way.
A single polygon of the same area returns exactly `n`.
**Possible cause:**
This is Claude suggested. I don't have the depth of understanding myself
to explore this:
''`lwmpoly_to_points` in `liblwgeom/lwgeom_geos.c` rounds each part's
share
independently (`lround(npoints * sub_area / area)`), so the per-part
counts don't always add up to `npoints`. This looks unchanged on master.''
**Possible fix:**
allocate points to parts with largest-remainder rounding (floor each
share, then give the leftover
points to the parts with the largest remainders), so the total is always
`npoints`.
I'm happy to help test a patch.
We ran into this with real municipality boundaries that have exclaves (off
by ±1 for about 3% of the multi-part cases we tried), and are working
around it by splitting the MultiPolygon and calling ST_GeneratePoints per
part.
Thank you for your work and thanks for PostGIS!
--
Ticket URL: <https://trac.osgeo.org/postgis/ticket/6135>
PostGIS <http://trac.osgeo.org/postgis/>
The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project.
More information about the postgis-tickets
mailing list