POSTGRES POSTGIS sfcgal - st_3darea not working

Viewed 94

I have a problem with sfcgal extension methods like st_3darea, st_3dintersection,using multipolygons.

When the polygons are touching I got an error saying that the polygons are intersecting. These two triangles are clearly not intersecting only touching:

SELECT st_3darea(ST_GeomFromText(
    'MULTIPOLYGON Z (((1 0 0, 1 1 0, 0 1 1, 1 0 0)), 
                    ((1 0 0, 0 1 1, 0 0 1, 1 0 0)))'));
                

but I got an error:

ERROR:  MultiPolygon is invalid : intersection between Polygon 0 and 1 : MULTIPOLYGON(((1/1 0/1 0/1,1/1 1/1 0/1,0/1 1/1 1/1,1/1 0/1 0/1)),((1/1 0/1 0/1,0/1 1/1 1/1,0/1 0/1 1/1,1/1 0/1 0/1)))
SQL state: XX000

please help.

Any suggestions are wellcome

2 Answers

Your MULTIPOLYGON is invalid, as the polygons intersect. Use ST_MakeValid to overcome this issue:

SELECT 
  ST_3DArea(
   ST_MakeValid('MULTIPOLYGON Z (((1 0 0, 1 1 0, 0 1 1, 1 0 0)),
                                ((1 0 0, 0 1 1, 0 0 1, 1 0 0)))'::geometry));

    st_3darea     
------------------
 1.41421356237309
(1 row)

As pointed out by @JGH (see comments):

ST_Overlaps, ST_Touches, ST_Within all imply spatial intersection. If any of the aforementioned returns true, then the geometries also spatially intersect. Disjoint implies false for spatial intersection.

Generally, the geometry "MULTIPOLYGON" does not imply any limitation to the polygons. It depends on the application. In Postgres, MULTIPOLYGON polygons are not allowed to touch or intersect. In Esri applications, the term "MULTIPOLYGON" refers to a set of polygons that are not allowed to intersect each other but can touch so that MULTIPOLYGON can be used to represent a mesh surface where polygons are adjacent to each other. WKT format specification defines MULTIPOLYGON as a set of polygons without any limitation.

To represent a mesh surface in Postgres, we should use POLYHEDRALSURFACE. This geometry is also a collection of polygons, but they have to be adjacent to each other.

Therefore, this will work:

SELECT st_3darea(ST_GeomFromText(
    'POLYHEDRALSURFACE Z (((1 0 0, 1 1 0, 0 1 1, 1 0 0)), 
                    ((1 0 0, 0 1 1, 0 0 1, 1 0 0)))'));
Related