Hi, I’m trying to calculate the volumes of buildings. I have done this in the past by generating point clouds from 3D BAG and AHN data. Now, I want to use the 3D geometries provided by the 3D BAG PostgreSQL database dump. Building geometries are provided as MultiPolygonZ
, and currently the highest LoD is 2.2 (source: General Concepts - 3D BAG).
I’m having trouble with calling ST_Volume()
on the geometries (source: ST_Volume). I have the postgis_sfcgal
extension installed. Here’s what I tried:
SELECT
-- ST_Volume(geometrie),
-- ST_Volume(ST_MakeValid(geometrie)),
ST_Volume(ST_MakeSolid(geometrie)),
-- ST_Volume(ST_Tesselate(geometrie)),
-- ST_Volume(ST_Buffer(ST_Buffer(geometrie, -0.001), 0.001)),
gid
FROM bag3d.lod22_3d LIMIT 1;
Doing ST_Volume(geometrie)
, ST_Volume(ST_MakeSolid(geometrie))
, or ST_Volume(ST_Tesselate(geometrie))
results in:
[XX000] ERROR: MultiPolygon is invalid : intersection between Polygon 0 and 10
Doing ST_Volume(ST_MakeValid(geometrie))
results in:
[XX000] ERROR: GeometryCollection is invalid : MultiPolygon 0 is invalid: Polygon 1 is invalid: points don't lie in the same plane
Doing ST_Volume(ST_Buffer(ST_Buffer(geometrie, -0.001), 0.001))
does sometimes result in the error below, and otherwise always yields a volume of zero.
[XX000] ERROR: Intersection does not support polygon with connected rings
When I split the MultiPolygonZ
s into Polygon
s, I get similar results:
SELECT
n,
ST_Volume(ST_GeometryN(geometrie, n)),
ST_Volume(ST_MakeValid(ST_GeometryN(geometrie, n))),
ST_Volume(ST_MakeSolid(ST_GeometryN(geometrie, n))),
ST_Volume(ST_Tesselate(ST_GeometryN(geometrie, n))),
ST_Volume(ST_Buffer(ST_Buffer(geometrie, -0.001), 0.001)),
gid
FROM (SELECT * FROM bag3d.lod22_3d LIMIT 1) a
CROSS JOIN generate_series(1, 100) n
WHERE n <= ST_NumGeometries(geometrie);
None of these combinations result in an error, but instead, they always yield a volume of zero.
In all cases, other postgis_sfcgal
functions such as ST_3DArea()
do return some useful output. Does this mean that I have to convert the MultiPolygonZ
s into POLYHEDRALSURFACE
or POLYHEDRALSURFACEZ
first, before I can call ST_MakeSolid()
on them? Or am I missing something else?
Any help with this is greatly appreciated!