WEBODM volume calculation

Referring to this before I began: Volumetric Measurements · Issue #53 · OpenDroneMap/WebODM (github.com)

I am using the grass volume calculation code from WEBODM to calculate a polygon drawn over the DSM.

I am providing the input to the grass python script, namely area_file, points_file, and DSM.

area_file.geojson (is the area file somehow supposed to contain some height information?)

{"type": "Feature", "properties": {}, "geometry": {"type": "Polygon", "coordinates": [[[73.31359828017844, 26.222181594890415], [73.31345181478787, 26.222065660491182], [73.31356935634167, 26.221948621838607], [73.31371520633195, 26.22205185876942], [73.31359828017844, 26.222181594890415]]]}}

points_file.geojson

{"type": "FeatureCollection", "features": [{"type": "Feature", "properties": {}, "geometry": {"type": "Point", "coordinates": [73.31359828017844, 26.222181594890415]}}, {"type": "Feature", "properties": {}, "geometry": {"type": "Point", "coordinates": [73.31345181478787, 26.222065660491182]}}, {"type": "Feature", "properties": {}, "geometry": {"type": "Point", "coordinates": [73.31356935634167, 26.221948621838607]}}, {"type": "Feature", "properties": {}, "geometry": {"type": "Point", "coordinates": [73.31371520633195, 26.22205185876942]}}, {"type": "Feature", "properties": {}, "geometry": {"type": "Point", "coordinates": [73.31359828017844, 26.222181594890415]}}]}

dsm_file : https://drive.google.com/file/d/1t3BqUht08ubrZs6klZJXKi8eNxhRTj24/view?usp=sharing

While running the grass script, until this step, everything runs fine.

Module("r.mask", vector="region")

It goes into an infinite loop during this step, where it keeps reading areas and writing the raster map.

Output is something like below.

Reading areas...
100%
Writing raster map...
100%
Reading areas...
100%
Writing raster map...
100%
Reading areas...
100%
Writing raster map...

It never stops, and I had to hit CTRL+C to stop it.

This next step output is only achieved if I skip the previous step ie. Module(“r.mask”, vector=“region”)

And the main doubt that I have is in the next step.

# Transfer dsm raster data to vector
Module("v.what.rast", map="polygon_points", raster="dsm", column="height")

Where did this column “height” came into picture, since it was not there in the polygon_points map, generated in the second step (Module(“v.import”, input=opts[“points_file”], output=“polygon_points”, overwrite=True))

this gives a warning about column height being missing and then later says,

Column <height> not found in the table <polygon_points>. Creating...
Reading features from vector map...
Update vector attributes...
100%
v.what.rast complete. 5 records updated.

After this step, it gets stuck, and nothing further happens in the script.

So the lines

Module(
"v.surf.rst",
input="polygon_points",
zcolumn="height",
elevation="dsm_below_pile",
overwrite=True,
)
# Compute difference between dsm and new dsm
Module(
"r.mapcalc",
expression="pile_height_above_dsm=dsm-dsm_below_pile",
overwrite=True,
)
# Set region to polygon area to calculate volume
Module("g.region", vector="polygon_area")
# Volume output from difference
Module("r.volume", input="pile_height_above_dsm", f=True)

remain unexecuted.

Please help me out with this and also let me know if you need more information.

1 Like

Update:
I ran the complete script in Windows GRASS GIS.


green color represents buffer region (region @PERMANENT)
grey polygon shows polygon_area ([email protected])
4 black cross shows the polygon_points([email protected])
white area inside the red square is the DSM color ([email protected])

So I figured out that it was going into an infinite loop because the command that was creating the region

Module("v.buffer", input="polygon_area", s=True, type="area", output="region", distance=1, minordistance=1, overwrite=True)

Contained distance value as 1 indicated it was 1 degree(nearly equals 111.1 km) and not 1 m, thus creating a huge area (because I was using longlat projection EPSG:4326, which is standard for geojson, and not any UTM projection). I tried creating the buffer region with a smaller distance value (i.e., 0.001) to fix this. Thus the buffer region was accurate, leading to the mask command (i.e. Module("r.mask," vector="region")) run within a reasonable time (i.e., 1-2 seconds).

I also figured out that the height column in polygon_points was supposed to be created/updated by the following command:

Module("v.what.rast", map="polygon_points", raster="dsm", column="height")

So, everything runs fine until this command:

Module("v.surf.rst", input="polygon_points", zcolumn="height", elevation="dsm_below_pile", overwrite=True)

Here I get the warning:

v.surf.rst input=polygon_points zcolumn=height elevation=dsm_below_pile --overwrite
Reading features from vector map ...
WARNING: Strip exists with insufficient data
Ignoring 1 points (too dense)
WARNING: 4 points given for interpolation (after thinning) is less than given NPMIN=300
WARNING: There are less than 600 points for interpolation. No segmentation is necessary, to run the program faster set segmax=600 (see manual)
Processing all selected output files will require
29.39 MB of disk space for temp files.
Bitmap mask created
Processing segments...
v.surf.rst complete.

I am not sure what that means. So, what can be done to make it work in EPSG:4326 CRS?

Also below is the complete log of the output of the script. And finally, it gives me 0.0 volume.

(Mon Jul 26 22:21:05 2021)                                                      
v.import input=C:\\Users\\Administrator\\Downloads\\area_file.geojson output=polygon_area --overwrite
Check if OGR layer <area_file> contains polygons...
Creating attribute table for layer <area_file>...
Importing 1 features (OGR layer <area_file>)...
-----------------------------------------------------
Registering primitives...
-----------------------------------------------------
Cleaning polygons
-----------------------------------------------------
Breaking polygons...
Breaking polygons (pass 1: select break points)...
Breaking polygons (pass 2: break at selected points)...
-----------------------------------------------------
Removing duplicates...
-----------------------------------------------------
Breaking boundaries...
-----------------------------------------------------
Removing duplicates...
-----------------------------------------------------
Cleaning boundaries at nodes...
-----------------------------------------------------
Merging boundaries...
-----------------------------------------------------
Removing dangles...
-----------------------------------------------------
Building areas...
-----------------------------------------------------
Removing bridges...
-----------------------------------------------------
Registering primitives...
Building areas...
Attaching islands...
-----------------------------------------------------
Finding centroids for OGR layer <area_file>...
-----------------------------------------------------
Writing centroids...
-----------------------------------------------------
1 input polygons
Total area: 341.906 (1 areas)
-----------------------------------------------------
Copying features...
Building topology for vector map <[email protected]>...
Registering primitives...
Building areas...
Attaching islands...
Attaching centroids...
Input <C:\\Users\\Administrator\\Downloads\\area_file.geojson> successfully imported without reprojection
(Mon Jul 26 22:21:06 2021) Command finished (1 sec)                             
(Mon Jul 26 22:21:13 2021)                                                      
v.import input=C:\\Users\\Administrator\\Downloads\\points_file.geojson output=polygon_points --overwrite
Check if OGR layer <points_file> contains polygons...
Creating attribute table for layer <points_file>...
Importing 5 features (OGR layer <points_file>)...
-----------------------------------------------------
Building topology for vector map <[email protected]>...
Registering primitives...
Input <C:\\Users\\Administrator\\Downloads\\points_file.geojson> successfully imported without reprojection
(Mon Jul 26 22:21:14 2021) Command finished (0 sec)                             
(Mon Jul 26 22:21:34 2021)                                                      
v.buffer input=polygon_area -s type=area output=region distance=0.001 minordistance=1 --overwrite
Note: In latitude-longitude coordinate system specify distances in degree unit
WARNING: Option 'minordistance' is not available with GEOS buffering
Buffering areas...
Cleaning buffers...
Building parts of topology...
Building topology for vector map <[email protected]>...
Registering primitives...
Snapping boundaries...
Reading features...
Snap vertices Pass 1: select points
Snap vertices Pass 2: assign anchor vertices
Snap vertices Pass 3: snap to assigned points
Breaking polygons...
Breaking polygons (pass 1: select break points)...
Breaking polygons (pass 2: break at selected points)...
Removing duplicates...
Breaking boundaries...
Removing duplicates...
Cleaning boundaries at nodes
Building topology for vector map <[email protected]>...
Building areas...
Removing dangles...
Removing bridges...
Attaching islands...
Building topology for vector map <[email protected]>...
Attaching islands...
Calculating centroids for all areas...
Generating list of boundaries to be deleted...
Deleting boundaries...
Calculating centroids for areas...
Building topology for vector map <[email protected]>...
Registering primitives...
Building areas...
Attaching islands...
Attaching centroids...
(Mon Jul 26 22:21:34 2021) Command finished (0 sec)                             
(Mon Jul 26 22:21:49 2021)                                                      
r.external input=C:\\Users\\Administrator\\Downloads\\dsm2.tif output=dsm --overwrite
Reading band 1 of 1...
Link to raster map <dsm> created.
(Mon Jul 26 22:21:50 2021) Command finished (1 sec)                             
(Mon Jul 26 22:21:56 2021)                                                      
g.region raster=dsm                                                             
(Mon Jul 26 22:21:56 2021) Command finished (0 sec)                             
(Mon Jul 26 22:22:00 2021)                                                      
g.region vector=region                                                          
(Mon Jul 26 22:22:00 2021) Command finished (0 sec)                             
(Mon Jul 26 22:22:07 2021)                                                      
r.mask vector=region                                                            
Reading areas...
Writing raster map...
All subsequent raster operations will be limited to the MASK area. Removing or renaming raster map named 'MASK' will restore raster operations to normal.
(Mon Jul 26 22:22:08 2021) Command finished (1 sec)                             
(Mon Jul 26 22:22:14 2021)                                                      
v.what.rast map=polygon_points raster=dsm column=height                         
Column <height> not found in the table <polygon_points>. Creating...
Reading features from vector map...
Update vector attributes...
v.what.rast complete. 5 records updated.
(Mon Jul 26 22:22:14 2021) Command finished (0 sec)                                                     
(Mon Jul 26 22:32:57 2021)                                                      
v.surf.rst input=polygon_points zcolumn=height elevation=dsm_below_pile --overwrite
Reading features from vector map ...
WARNING: Strip exists with insufficient data
Ignoring 1 points (too dense)
WARNING: 4 points given for interpolation (after thinning) is less than given NPMIN=300
WARNING: There are less than 600 points for interpolation. No segmentation is necessary, to run the program faster set segmax=600 (see manual)
Processing all selected output files will require
29.39 MB of disk space for temp files.
Bitmap mask created
Processing segments...
v.surf.rst complete.
(Mon Jul 26 22:33:00 2021) Command finished (2 sec)                             
(Mon Jul 26 22:33:06 2021)                                                      
r.mapcalc expression=pile_height_above_dsm=dsm-dsm_below_pile --overwrite       
(Mon Jul 26 22:33:07 2021) Command finished (1 sec)                             
(Mon Jul 26 22:33:14 2021)                                                      
g.region vector=polygon_area                                                    
(Mon Jul 26 22:33:15 2021) Command finished (0 sec)                             
(Mon Jul 26 22:33:19 2021)                                                      
r.volume input=pile_height_above_dsm -f                                         
No clump map given, using MASK
1:0.73:68050:93627:73.31:26.22:0.00 
(Mon Jul 26 22:33:19 2021) Command finished (0 sec)                             

The last-second line in the above output shows 0.00 volume saying it did not find any clump. What is going wrong? Any hints or suggestions will be helpful.

1 Like

Do you need to work in EPSG:4326? Angular CRSs are painful for calculations for the reason you’ve outlined above.

Can’t you work in a local CRS and then convert to EPSG:4326 at the end?

2 Likes

With reference to this, openlayers - Proper projection for Utm for geojson - Geographic Information Systems Stack Exchange

You need to re-project your data to WGS-84 (4326) as that is the GeoJSON standard. All software using GeoJSON expects the data in that projection. Since the GeoJSON is in Lat/ Long decimal degrees, your UTM Meters coordinates won’t show up where you expect them.

So geojson has to be in EPSG:4326 CRS.
The coordinates in the Geojson file are longlat coordinates.
Should I be using the corresponding local UTM Zone 43N coordinates?
How can I use UTM values with a Geojson file?

I’m wondering if you can work in a local CRS in another format (we support geopackage), and then dump to geojson at the last step.

I followed your first response of working in local CRS, without converting it to EPSG:4326 at the end (I am not sure how to do that and would affect the volume value). I was able to get the volume at the end, and compared it with ArcGIS (ESRI volume tool). The results are not consistent (as in the ratio of the values of the GRASS GIS and ESRI tool).
Anything else that could be done to get the volume consistent?

Also, does the decimal digits more than 6 can be a reason for the inconsistent results (since longlat value up to 6 digits means accuracy up to centimeters)? Thoughts?

I would be very careful about which calculation you believe to be accurate.

Is ESRI doing planimetric or geodetic measurements?

EPSG 4326 has pretty severe accuracy issues, especially in Z/vertical. I wouldn’t rely upon it for truth measurements if it can be avoided.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.