Opened 35 hours ago
Last modified 8 hours ago
#5868 new defect
Add Function to Detect Valid Polygons with Point Touching Rings
Reported by: | gravitystorm | Owned by: | pramsey |
---|---|---|---|
Priority: | medium | Milestone: | PostGIS 3.5.3 |
Component: | postgis | Version: | 3.4.x |
Keywords: | Cc: | gravitystorm |
Description (last modified by ) ¶
Certain functions are not implemented for valid polygons with point touching rings (see https://trac.osgeo.org/postgis/ticket/5867).
For some use-cases, it would be handy if there was a function that could be used to detect such polygons ahead of time, in order to handle them separately. I haven't been able to find any existing postgis function that does this, but if I've missed one please let me know.
With such a function, you could choose to ignore these polygons, e.g.
select CG_StraightSkeleton(geom) from table where !ST_ValidPolygonHasPointTouchingInnerRing(geom)
Alternatively, you could buffer only the geometries that have point touching rings, without buffering the vast majority that don't, e.g.
select CG_StraightSkeleton( case when ST_ValidPolygonHasPointTouchingInnerRing(geom) then st_buffer(geom, 0.0001) else geom end) from table
Change History (6)
comment:1 by , 34 hours ago
Cc: | added |
---|
comment:2 by , 33 hours ago
comment:3 by , 33 hours ago
Have you considered using ST_MakeValid
to fix this problem? It causes less change than buffering.
comment:4 by , 11 hours ago
Thanks for looking into this mdavis, and I'm sorry I wasn't clear enough about the situation.
This issue is about valid polygons only, so st_isvalid and st_makevalid don't help. Specifically, this is not about polygons with self-touching rings, it's about polygons with an inner ring(s) that touch(es) the outer ring at one vertex (valid polygon example (i) in https://postgis.net/docs/manual-dev/using_postgis_dbmanagement.html#OGC_Validity ).
Despite being valid, these valid polygons throw an error with certain functions, see #5867
So we have two sub-groups of valid polygons:
- Group A - valid polygons that work with GC_StraightSkeleton (and similar functions)
- Group B - valid polygons that error with GC_StraightSkeleton (and similar functions)
An example of group A is POLYGON((0 0, 3 0, 3 3, 0 3, 0 0))
(a square)
An example of group B is POLYGON((0 0, 3 0, 3 3, 0 3, 0 0),(0 0, 1 2, 2 1, 0 0))
(a square with an inner ring that touches at one vertex, which despite being valid, still causes the error in those functions).
gis=# select st_straightskeleton(st_geomfromtext('POLYGON((0 0, 3 0, 3 3, 0 3, 0 0),(0 0, 1 2, 2 1, 0 0))')); NOTICE: During straight_skeleton(A) : NOTICE: with A: POLYGON((0/1 0/1,3/1 0/1,3/1 3/1,0/1 3/1,0/1 0/1),(0/1 0/1,1/1 2/1,2/1 1/1,0/1 0/1)) ERROR: straight skeleton of Polygon with point touching rings is not implemented.
So I'm looking for a function that can detect Group B valid polygons, so that the function can be used to avoid triggering errors in GC_StraightSkeleton.
comment:5 by , 11 hours ago
Description: | modified (diff) |
---|
comment:6 by , 8 hours ago
Thanks for the clarification.
One option is to make a SQL function to check whether the shell ring of a valid polygon and the inner hole rings intersect.
In fact, there is code in GEOS to transform polygons with touching holes into equivalent self-touching rings (AKA inverted/exverted rings). This currently isn't exposed, but it could be - either as a PostGIS function, or simply as a preprocessing step inside the affected CG functions.
Can you just use
ST_IsValid
? It will reportfalse
for self-touching rings.There is also a flag on
ST_IsValid
which allows polygons with self-touching rings to be considered valid. You could combine this with the defaultST_Valid
to test whether a geometry is valid but with a self-touch (i.e. to identify geometries to be ignored or fixed):