It would be cool to have the ability to measure volumes directly from the map.
I think this could be approached in the following way:
Should also add the possibility to specify a "Cut" or "Fill" property for concave/convex cases.
Depending on the area, and given the density of points, it would be good to simplify the point cloud before creating a TIN, as ST_DelaunayTriangles (last I checked) could be pretty slow even with modest point clouds. If there is a way to pass the surface from ODM to PostGIS (which is pre-simplified), that might be a good alternative to constructing the TIN in PostGIS.
This blog post here hints that volume measurements can be done using "elevation data" https://blog.dronedeploy.com/new-release-volume-measurement-8d20b3754a2e#.kxkbugl18, so perhaps the volume calculation could be done using the DEM.
DEM --> TIN --> Volume Measurement over a base plane
@smathermather any suggestions on how you would generate a TIN from a DEM in PostGIS?
Sorry for the delay. Maybe we can look at this at the code sprint.
Grass GIS could do this also from DEM
Agreed @kikislater, although we are working to not bring all of grass in as a dependency.
Ok understand, thank you for the answer. It's 2 different computation. Sfcgal is very powerfull, nice to see here 馃憤
@Hi guys,
why so volume measurement feature has not been added? Is there any problem? If would be good if one could measure volume like area, distance, and height measurement which have already been included. Is there any specific reason that no one has been able to solve it so far?
We're working on getting better DEMs before we can tackle volume measurements. https://github.com/OpenDroneMap/node-OpenDroneMap/issues/15
Volume Measurements tool will be soon available on the WebODM. Basically, Volume estimation could be seen as a change in both surface & elevation. So, if we come up with the surface of our area of interest and the variation of elevation we can then estimate our Volume ... So here are some basics steps that could be implemented as well;
That's a great start. This would mostly work well for measurements made on flat areas. A further improvement could be to create a polygon surface defined by the contour and extrude the elevation values from the initial surface to create the final polygon to be measured. There's some good insights on how this is done at a high level here: https://support.dronedeploy.com/v1.0/docs/volume-measurement (see the "Best Fit" method).
The scipy library has some good utilities that could aid in the calculation. See https://stackoverflow.com/questions/42032540/python-library-to-calculate-surface-area-and-volume-of-an-arbirary-polyhedron and https://docs.scipy.org/doc/scipy/reference/spatial.html
Maybe, this is the right one to do, by then we could filter out Cut and Fill volumes using the normalised nDSM and estimate the global volume..this could be done without any problems..i have planned this to be the next step
@Abizem have you had any success with this?
Maybe, these scripts could help to do some volume measurments https://github.com/Abizem/VolumefromContour
Also a way to compute volume is to use this workflow in GRASS: https://gis.stackexchange.com/questions/168035/calculate-volume-over-sloped-ground-in-grass-gis
The fillnulls interpolation should allow estimation of sloped surfaces.
Note to self:
Script to compute volume:
#!/bin/bash
v.import input=/data/drone/sheffield_park/dems/building.geojson layer=building output=polygon_area --overwrite
v.import input=/data/drone/sheffield_park/dems/points.geojson layer=points output=polygon_points --overwrite
r.import input=/data/drone/sheffield_park/dems/dsm.tif output=dsm --overwrite
v.buffer -s --overwrite input=polygon_area type=area output=region distance=3 minordistance=3
g.region vector=region
v.what.rast map=polygon_points raster=dsm column=height
v.to.rast input=polygon_area output=r_polygon_area use=val value=255 --overwrite
#v.surf.rst --overwrite input=polygon_points zcolumn=height elevation=dsm_below_pile mask=r_polygon_area
v.surf.bspline --overwrite input=polygon_points column=height raster_output=dsm_below_pile lambda_i=100
r.mapcalc expression='pile_height_above_dsm=dsm-dsm_below_pile' --overwrite
r.volume -f input=pile_height_above_dsm clump=r_polygon_area
Takes as input a boundary polygon and points that form the polygon and a dsm.
It can then be executed via another script:
rm -fr test_location
grass72 -c /data/drone/sheffield_park/dems/dsm.tif -e test_location
grass72 test_location/PERMANENT/ --exec sh volume.sh
This is an improvement over the proposed implementation in Python because it can handle volumes over sloped terrain (current implementation in volume branch uses a median plane).
Hi @pierotofy ,
You never set resolution in your script. It's needed to set computation accuracy otherwise you will stay at 1 meter resolution and result would suffer from it.
Why not declare dsm resolution before setting region like this :
g.region rast=dsm
then change region to your buffer
g.region vect=region
Thanks @kikislater, I'm still learning GRASS, I will include your recommendations in the final script.
You could still improve computation with mask. Computation will be on mask, you save time.
r.mask vect=region
So I will replace your g.region with this :
g.region rast=dsm
g.region vect=region
r.mask -r # prevent : removing eventual existing mask
r.mask vect=region
This is pretty much done! https://github.com/OpenDroneMap/WebODM/pull/418
@kikislater could you double check calc_volume.grass for me? https://github.com/OpenDroneMap/WebODM/pull/418/files#diff-3b887f86b953d48470e37e5cbfd1f50c
Seems good for me. v.surf.bspline should be tested for some special cases. May be better to create a TIN then rasterize it but takes far away more long time to process ...
To understand well about your grass module. Is database created each time or once then reload it ?
It鈥檚 created each time (and then destroyed).
In that case r.mask -r is not needed
@kikislater thanks! Could you open a PR to remove the line?
Done here :
https://github.com/OpenDroneMap/WebODM/pull/425