diff --git a/raster/r.sim/r.sim.water/r.sim.water.html b/raster/r.sim/r.sim.water/r.sim.water.html index 7bf3d256d39..ba43e99c9b4 100644 --- a/raster/r.sim/r.sim.water/r.sim.water.html +++ b/raster/r.sim/r.sim.water/r.sim.water.html @@ -219,6 +219,52 @@

Run summary

-t -p format=json +In Python with grass.script: + +
+import grass.script as gs
+
+summary = gs.parse_command(
+    "r.sim.water",
+    elevation="elevation",
+    depth="depth",
+    discharge="discharge",
+    rain_value=50,
+    man_value=0.05,
+    nwalkers=100000,
+    duration=20,
+    output_step=10,
+    random_seed=3,
+    flags="tp",
+    format="json",
+)
+print(summary["walkers_remaining"], summary["outputs"][-1]["depth"])
+
+ +In Python with grass.tools: + +
+from grass.tools import Tools
+
+tools = Tools()
+summary = tools.r_sim_water(
+    elevation="elevation",
+    depth="depth",
+    discharge="discharge",
+    rain_value=50,
+    man_value=0.05,
+    nwalkers=100000,
+    duration=20,
+    output_step=10,
+    random_seed=3,
+    flags="tp",
+    format="json",
+)
+print(summary["walkers_remaining"], summary["outputs"][-1]["depth"])
+
+ +The printed summary: +
 {
     "walkers_requested": 100000,
@@ -258,63 +304,140 @@ 

Run summary

}
+

EXAMPLE

+ +This example uses the +SIMWE sample dataset +of the NC State University Sediment and Erosion Control Research and +Education Facility, a 52 ha area in Raleigh, North Carolina, USA, at 1 m +resolution. It contains a lidar-based elevation map, a land cover map +and orthophoto bands. +

-Reading the summary in Python: +Set the computational region to the elevation map and derive the +Manning's n raster map from the land cover classes with +r.recode. Buildings (class 1), paved +roads (2) and compacted roads and parking lots (3) get low roughness +values, while herbaceous cover such as fields and lawns (4) and forest (5) +get high values suitable for shallow overland flow. Water (6) gets a low +value. See the +r.manning +addon for an explanation of Manning's n and reference values for common +land cover classifications. + +

+g.region raster=elevation
+r.recode input=landcover output=mannings rules=- <<EOF
+1:1:0.012
+2:2:0.014
+3:3:0.025
+4:4:0.24
+5:5:0.35
+6:6:0.04
+EOF
+
+ +In Python with grass.script:
 import grass.script as gs
 
-summary = gs.parse_command(
-    "r.sim.water",
-    elevation="elevation",
-    depth="depth",
-    discharge="discharge",
-    flags="p",
-    format="json",
+gs.run_command("g.region", raster="elevation")
+manning = {
+    1: 0.012,  # buildings
+    2: 0.014,  # paved roads
+    3: 0.025,  # compacted roads and parking lots
+    4: 0.24,  # herbaceous cover
+    5: 0.35,  # forest
+    6: 0.04,  # water
+}
+rules = "\n".join(f"{k}:{k}:{v}" for k, v in manning.items())
+gs.write_command(
+    "r.recode", input="landcover", output="mannings", rules="-", stdin=rules
 )
-print(summary["walkers_remaining"], summary["outputs"][-1]["depth"])
 
-

EXAMPLE

+In Python with grass.tools: + +
+from io import StringIO
+
+from grass.tools import Tools
+
+tools = Tools()
+tools.g_region(raster="elevation")
+manning = {
+    1: 0.012,  # buildings
+    2: 0.014,  # paved roads
+    3: 0.025,  # compacted roads and parking lots
+    4: 0.24,  # herbaceous cover
+    5: 0.35,  # forest
+    6: 0.04,  # water
+}
+rules = "\n".join(f"{k}:{k}:{v}" for k, v in manning.items())
+tools.r_recode(input="landcover", output="mannings", rules=StringIO(rules))
+
+ +

+

+Manning's n derived from land cover
+ + Figure: Manning's n derived from land cover with low values for + buildings and roads and high values for fields and forest. + +
-Using the North Carolina full sample dataset: +

+Simulate 30 minutes of overland flow with a uniform rainfall excess of +20 mm/hr. The random seed makes the run reproducible.

-# set computational region
-g.region raster=elev_lid792_1m -p
+r.sim.water elevation=elevation man=mannings rain_value=20 depth=depth \
+    duration=30 random_seed=1
+
-# compute dx, dy -r.slope.aspect elevation=elev_lid792_1m dx=elev_lid792_dx dy=elev_lid792_dy +In Python with grass.script: -# simulate (this may take a minute or two) -r.sim.water elevation=elev_lid792_1m dx=elev_lid792_dx dy=elev_lid792_dy depth=water_depth disch=water_discharge nwalk=10000 rain_value=100 niter=5 +
+gs.run_command(
+    "r.sim.water",
+    elevation="elevation",
+    man="mannings",
+    rain_value=20,
+    depth="depth",
+    duration=30,
+    random_seed=1,
+)
 
-Now, let's visualize the result using rendering to a file -(note the further management of computational region and -usage of d.mon module -which are not needed when working in GUI): +In Python with grass.tools:
-# increase the computational region by 350 meters
-g.region e=e+350
-# initiate the rendering
-d.mon start=cairo output=r_sim_water_water_depth.png
-# render raster, legend, etc.
-d.rast map=water_depth_1m
-d.legend raster=water_depth_1m title="Water depth [m]" label_step=0.10 font=sans at=20,80,70,75
-d.barscale at=67,10 length=250 segment=5 font=sans
-d.northarrow at=90,25
-# finish the rendering
-d.mon stop=cairo
+tools.r_sim_water(
+    elevation="elevation",
+    man="mannings",
+    rain_value=20,
+    depth="depth",
+    duration=30,
+    random_seed=1,
+)
 

-r.sim.water generated depth map
- - Figure: Simulated water depth map in the rural area of - the North Carolina sample dataset. +Water depth over shaded relief
+ + Figure: Simulated water depth in meters after 30 minutes of rainfall + shown over shaded relief. + +
+ +

+

+Water depth over orthophoto
+ + Figure: Water depth of at least 0.1 m shown over the orthophoto, with + flow concentrated in ditches and channels and ponding in depressions.
diff --git a/raster/r.sim/r.sim.water/r.sim.water.ipynb b/raster/r.sim/r.sim.water/r.sim.water.ipynb index a445ea011bc..3311fb345cc 100644 --- a/raster/r.sim/r.sim.water/r.sim.water.ipynb +++ b/raster/r.sim/r.sim.water/r.sim.water.ipynb @@ -1,5 +1,167 @@ { "cells": [ + { + "cell_type": "markdown", + "id": "012bb203-d53a-4692-961d-b3c9d21db78a", + "metadata": {}, + "source": [ + "# SIMWE examples" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a3c1c671-e76b-4118-8a97-dbf1126c248c", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import subprocess\n", + "import sys\n", + "import shutil\n", + "\n", + "# Download zip\n", + "!curl https://zenodo.org/records/23017720/files/secref_northcarolina_usa_epsg6542.zip -o ~/data/secref_northcarolina_usa_epsg6542.zip\n", + "\n", + "# Unpack zip\n", + "shutil.unpack_archive(\n", + " os.path.expanduser(\"~/data/secref_northcarolina_usa_epsg6542.zip\"),\n", + " os.path.expanduser(\"~/data/\"),\n", + " \"zip\",\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "73a1a1d0-b43c-47f6-bb6f-e707e1bf728c", + "metadata": {}, + "outputs": [], + "source": [ + "import subprocess\n", + "import sys\n", + "\n", + "sys.path.append(\n", + " subprocess.check_output([\"grass\", \"--config\", \"python_path\"], text=True).strip()\n", + ")\n", + "# Import GRASS packages\n", + "import grass.script as gs\n", + "import grass.jupyter as gj\n", + "from grass.tools import Tools\n", + "\n", + "# Start GRASS Session\n", + "gj.init(\"~/data/secref_northcarolina_usa_epsg6542\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1c23db24-cc6d-4714-bfaf-6699b154c203", + "metadata": {}, + "outputs": [], + "source": [ + "tools = Tools()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5224e6ff-2c18-4b93-94eb-7e27cb1575fb", + "metadata": {}, + "outputs": [], + "source": [ + "tools.r_relief(input=\"elevation\", output=\"relief\", zscale=3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c52a0d6e-6f97-4e82-bf40-2618a593b549", + "metadata": {}, + "outputs": [], + "source": [ + "tools.g_region(raster=\"elevation\", s=\"s-110\", save=\"render\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2bca0b9a-f79a-45d8-8d0f-68350cfb9a52", + "metadata": {}, + "outputs": [], + "source": [ + "from io import StringIO\n", + "\n", + "manning = {\n", + " 1: 0.012, # building (roof)\n", + " 2: 0.014, # paved road\n", + " 3: 0.025, # compacted road, parking lot\n", + " 4: 0.24, # herbaceous (fields, grass, crops)\n", + " 5: 0.35, # forest\n", + " 6: 0.04, # water\n", + "}\n", + "tools.r_recode(\n", + " input=\"landcover\",\n", + " output=\"mannings\",\n", + " rules=StringIO(\"\\n\".join(f\"{k}:{k}:{v}\" for k, v in manning.items())),\n", + ")\n", + "tools.r_colors(map=\"mannings\", color=\"grass\", flags=\"n\")\n", + "manning_map = gj.Map(saved_region=\"render\", width=500)\n", + "manning_map.d_rast(map=\"mannings\")\n", + "manning_map.d_shade(shade=\"relief\", color=\"mannings\", brighten=70)\n", + "manning_map.d_legend(raster=\"mannings\", flags=\"t\", at=\"6,10,10,90\", fontsize=12)\n", + "manning_map.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "842698de-6b55-4d3f-8610-87f199e5a043", + "metadata": {}, + "outputs": [], + "source": [ + "tools.r_sim_water(\n", + " elevation=\"elevation\",\n", + " man=\"mannings\",\n", + " rain_value=20,\n", + " depth=\"depth\",\n", + " output_step=5,\n", + " duration=30,\n", + " random_seed=1,\n", + " nprocs=1,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "28a7a216-48fe-4e56-b2e8-f7e67c4304da", + "metadata": {}, + "outputs": [], + "source": [ + "depth_map = gj.Map(saved_region=\"render\", width=500)\n", + "depth_map.d_shade(shade=\"relief\", color=\"depth\", brighten=30)\n", + "depth_map.d_legend(raster=\"depth\", flags=\"t\", at=\"6,10,10,90\", fontsize=12)\n", + "depth_map.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2b63dd19-a142-47d7-b553-8a37ef1440ce", + "metadata": {}, + "outputs": [], + "source": [ + "tools.r_composite(red=\"naip.1\", green=\"naip.2\", blue=\"naip.3\", output=\"naip\")\n", + "depth_map = gj.Map(saved_region=\"render\", width=500)\n", + "depth_map.d_shade(shade=\"relief\", color=\"naip\", brighten=70)\n", + "depth_map.d_rast(map=\"depth\", values=\"0.1-100\")\n", + "depth_map.d_legend(\n", + " raster=\"depth\", flags=\"t\", at=\"6,10,10,90\", range=\"0.1,0.6\", labelnum=6, fontsize=12\n", + ")\n", + "depth_map.show()" + ] + }, { "cell_type": "markdown", "id": "05ec86f0-769a-407c-94b9-9e2bcaa35696", @@ -265,7 +427,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.5" + "version": "3.12.3" } }, "nbformat": 4, diff --git a/raster/r.sim/r.sim.water/r.sim.water.md b/raster/r.sim/r.sim.water/r.sim.water.md index 460e35e34c9..e128a492c90 100644 --- a/raster/r.sim/r.sim.water/r.sim.water.md +++ b/raster/r.sim/r.sim.water/r.sim.water.md @@ -199,11 +199,61 @@ the names of the `depth`, `discharge`, `error` and `walkers` maps, or Summary of a time series run with two output steps in JSON: -```sh -r.sim.water elevation=elevation depth=depth discharge=discharge rain_value=50 \ - man_value=0.05 nwalkers=100000 duration=20 output_step=10 random_seed=3 \ - -t -p format=json -``` + +=== "Command line" + + ```sh + r.sim.water elevation=elevation depth=depth discharge=discharge rain_value=50 \ + man_value=0.05 nwalkers=100000 duration=20 output_step=10 random_seed=3 \ + -t -p format=json + ``` + +=== "Python (grass.script)" + + ```python + import grass.script as gs + + summary = gs.parse_command( + "r.sim.water", + elevation="elevation", + depth="depth", + discharge="discharge", + rain_value=50, + man_value=0.05, + nwalkers=100000, + duration=20, + output_step=10, + random_seed=3, + flags="tp", + format="json", + ) + print(summary["walkers_remaining"], summary["outputs"][-1]["depth"]) + ``` + +=== "Python (grass.tools)" + + ```python + from grass.tools import Tools + + tools = Tools() + summary = tools.r_sim_water( + elevation="elevation", + depth="depth", + discharge="discharge", + rain_value=50, + man_value=0.05, + nwalkers=100000, + duration=20, + output_step=10, + random_seed=3, + flags="tp", + format="json", + ) + print(summary["walkers_remaining"], summary["outputs"][-1]["depth"]) + ``` + + +The printed summary: ```json { @@ -244,58 +294,133 @@ r.sim.water elevation=elevation depth=depth discharge=discharge rain_value=50 \ } ``` -Reading the summary in Python: - -```python -import grass.script as gs - -summary = gs.parse_command( - "r.sim.water", - elevation="elevation", - depth="depth", - discharge="discharge", - flags="p", - format="json", -) -print(summary["walkers_remaining"], summary["outputs"][-1]["depth"]) -``` - ## EXAMPLE -Using the North Carolina full sample dataset: - -```sh -# set computational region -g.region raster=elev_lid792_1m -p - -# compute dx, dy -r.slope.aspect elevation=elev_lid792_1m dx=elev_lid792_dx dy=elev_lid792_dy - -# simulate (this may take a minute or two) -r.sim.water elevation=elev_lid792_1m dx=elev_lid792_dx dy=elev_lid792_dy depth=water_depth disch=water_discharge nwalk=10000 rain_value=100 niter=5 -``` - -Now, let's visualize the result using rendering to a file (note the -further management of computational region and usage of -[d.mon](d.mon.md) module which are not needed when working in GUI): - -```sh -# increase the computational region by 350 meters -g.region e=e+350 -# initiate the rendering -d.mon start=cairo output=r_sim_water_water_depth.png -# render raster, legend, etc. -d.rast map=water_depth_1m -d.legend raster=water_depth_1m title="Water depth [m]" label_step=0.10 font=sans at=20,80,70,75 -d.barscale at=67,10 length=250 segment=5 font=sans -d.northarrow at=90,25 -# finish the rendering -d.mon stop=cairo -``` - -![r.sim.water generated depth map](r_sim_water_water_depth.png) -*Figure: Simulated water depth map in the rural area of the North -Carolina sample dataset.* +This example uses the +[SIMWE sample dataset](https://doi.org/10.5281/zenodo.23017720) of the +NC State University Sediment and Erosion Control Research and Education +Facility, a 52 ha area in Raleigh, North Carolina, USA, at 1 m +resolution. It contains a lidar-based elevation map, a land cover map +and orthophoto bands. + +Set the computational region to the elevation map and derive the +Manning's n raster map from the land cover classes with +*[r.recode](r.recode.md)*. Buildings (class 1), paved roads (2) and +compacted roads and parking lots (3) get low roughness values, while +herbaceous cover such as fields and lawns (4) and forest (5) get high +values suitable for shallow overland flow. Water (6) gets a low value. +See the +[r.manning](https://grass.osgeo.org/grass-stable/manuals/addons/r.manning.html) +addon for an explanation of Manning's n and reference values for +common land cover classifications. + + +=== "Command line" + + ```sh + g.region raster=elevation + r.recode input=landcover output=mannings rules=- < + +![Manning's n derived from land cover](r_sim_water_mannings.png) +*Figure: Manning's n derived from land cover with low values for +buildings and roads and high values for fields and forest.* + +Simulate 30 minutes of overland flow with a uniform rainfall excess of +20 mm/hr. The random seed makes the run reproducible. + + +=== "Command line" + + ```sh + r.sim.water elevation=elevation man=mannings rain_value=20 depth=depth \ + duration=30 random_seed=1 + ``` + +=== "Python (grass.script)" + + ```python + gs.run_command( + "r.sim.water", + elevation="elevation", + man="mannings", + rain_value=20, + depth="depth", + duration=30, + random_seed=1, + ) + ``` + +=== "Python (grass.tools)" + + ```python + tools.r_sim_water( + elevation="elevation", + man="mannings", + rain_value=20, + depth="depth", + duration=30, + random_seed=1, + ) + ``` + + +![Water depth over shaded relief](r_sim_water_depth.png) +*Figure: Simulated water depth in meters after 30 minutes of rainfall +shown over shaded relief.* + +![Water depth over orthophoto](r_sim_water_depth_orthophoto.png) +*Figure: Water depth of at least 0.1 m shown over the orthophoto, with +flow concentrated in ditches and channels and ponding in depressions.* ## REFERENCES diff --git a/raster/r.sim/r.sim.water/r_sim_water_depth.png b/raster/r.sim/r.sim.water/r_sim_water_depth.png new file mode 100644 index 00000000000..f0b4feb3371 Binary files /dev/null and b/raster/r.sim/r.sim.water/r_sim_water_depth.png differ diff --git a/raster/r.sim/r.sim.water/r_sim_water_depth_orthophoto.png b/raster/r.sim/r.sim.water/r_sim_water_depth_orthophoto.png new file mode 100644 index 00000000000..f5744bb12de Binary files /dev/null and b/raster/r.sim/r.sim.water/r_sim_water_depth_orthophoto.png differ diff --git a/raster/r.sim/r.sim.water/r_sim_water_mannings.png b/raster/r.sim/r.sim.water/r_sim_water_mannings.png new file mode 100644 index 00000000000..7dc7873541d Binary files /dev/null and b/raster/r.sim/r.sim.water/r_sim_water_mannings.png differ diff --git a/raster/r.sim/r.sim.water/r_sim_water_water_depth.png b/raster/r.sim/r.sim.water/r_sim_water_water_depth.png deleted file mode 100644 index e35f0cf86f7..00000000000 Binary files a/raster/r.sim/r.sim.water/r_sim_water_water_depth.png and /dev/null differ