# Area calculation for non-planar surfaces

I am looking for a way to calculate the area for a big set of 3D-surfaces.

I know, that some of those surfaces are slightly non-planar, which means that the coordinates got somehow "rounded" at any point of the toolchain, which made them non-planar polygons. (One of the coordinates is slightly off the plane of the surface, so ST_isPlanar says false)

I do not have influence on those earlier points in the toolchain and must now deal with the non-planar surfaces.

I tried to disassemble the polygons into triangles with ST_DelaunayTriangles, but somehow the function only returns one polygon(triangle), which is then non-planar, but missing one of the original points. Most of the surfaces have 4 edges, so when one point is missing, the area calculation will return only the half compare to the real surface area.

My first example is the surface 1 which is planar as reference, and surface 2 which has one coordinate slightly off (+ 0.1 at one coordinate).

Surface 1:

``````POLYGON Z ((
9 6 17,
2 6 17,
2 6 4,
9 6 4,
9 6 17))
``````

Surface 2:

``````POLYGON 2 Z ((
9 6 17,
2 6 17,
2 6 4,
9 6.1 4,
9 6 17))
``````

ST_DelaunayTriangles() applied on Surface 2 returns only:

``````GEOMETRYCOLLECTION Z
(POLYGON Z ((
2 6 17,
9 6 17,
9 6.1 4,
2 6 17
)))

``````

ST_3dArea is only computing planar surfaces, so I somehow have to get rid of this non-planarity.

Does anyone have an idea how to calculate those surface areas of slightly non-planar surfaces?

My goal is to calculate the area of both by achieving more or less the same value of surface area.

• Have you tried st_snaptogrid? If you only need to fix the x and y coordinates, this could work for you. May 18, 2022 at 19:52
• I will check that, and tell if that solved the problem!
– e.g
May 19, 2022 at 15:37
• In your examples, your polygons contain vertices with identical Y coordinates, which in turn makes them invalid. They have zero area in 2D space (except for the one with a slight error). For that reason, ST_DelaunayTriangles() returns nothing for them. Simple solution would be to switch over your Y and Z coordinates and make simple 2d geoms from them. Something like this: select st_force2d(st_swapordinates(g.geom, 'yz')) from g Then you cen use st_area without issues... May 20, 2022 at 11:58
• Those surfaces are only an example, I have also some where the Y coordinates are not identical, so your solution would not work. For those which are vertical, I will try out your solution! postgis.net/docs/ST_DelaunayTriangles.html Here is described, that the function is also supporting 3D so I thought, that the surfaces with identical Y values would not be a problem..
– e.g
May 20, 2022 at 13:30
• Yes, but you need valid geometry at XY plane first, then you can add Z coordinates to the mix. And remember, GIS are almost always 2.5D systems. They don't work with real 3D objects (like Blender, FreeCAD etc.), but with planar objects with added Z coordinates. In 2.5D world, two coordinates with the same XY but different Z are considered errors (if they are part of the same geometry). If you need to calculate surfaces in arbitrary positions, you may need to look for a different piece of SW. May 27, 2022 at 11:53

The use of `ST_SnapToGrid()` is not very easy, as I don't want to manipulate the surfaces too much, so the area values are not changed too much. The parameter of the grid size was somehow hard to optimize, as bigger values led to more planarity, but also to more manipulation (sometimes the surface just dissapeared).
The key was, that I found out, that if I first apply `ST_SnapToGrid()` with a grid parameter of ~1, the surfaces did not get planar directly, but the `ST_DelaunayTriangles()` now brought back a clean triangle-representation of the surface, that ST_3dArea could calculate.
Finally the chain of tools: `ST_3dArea(ST_DelaunayTriangles(ST_SnapToGrid(geom, 1)))` solved the problem without manipulating the surfaces too much.