VFlood
English version
Export

6. Exporting to GeoTIFF / PNG / Google Earth (vflood-export)

The original RRI pipeline turns .out grids into flood maps via a gnuplot script (hs_kml.plt) and makeKml.exe, both external to Python. vflood-export replaces that chain natively — no gnuplot, no separate .exe:

vflood-rri RRI_Input.txt                                        # 1. run the simulation first
vflood-export RRI_Input.txt --variable hs --formats geotiff,png,kml \
    --start 2023-12-22T17:00:00

This reads whichever hs_NNNNNN.out files already exist (run vflood-rri first — export is a separate post-processing step, same as makeKml.exe always was) and writes, per timestep, under <out folder>/export/hs/:

  • hs_NNNNNN.tif — a georeferenced GeoTIFF, opens directly in QGIS/ArcGIS
  • hs_NNNNNN.png — a colour-mapped depth frame (transparent where dry, so it overlays cleanly on a basemap)
  • hs.kml — one time-animated KML referencing all the PNGs; open it in Google Earth and scrub the timeline to watch the flood evolve, same as the old makeKml.exe output, just produced without leaving Python

A fourth format, gif, is a different kind of output — not one PNG/tif per timestep but a single self-contained animated GIF, viewable in any image viewer or browser (no Google Earth, no ffmpeg):

vflood-export RRI_Input.txt --variable hs --formats gif --river-variable hr

Each frame composites a DEM-derived hillshade basemap (so you see real terrain context, not water floating on a blank background) with a single combined water-depth layer — the river channel (--river-variable, default hr) inside the river network, the requested --variable (typically hs, overland depth) everywhere else — so one map shows both the river and the flood extent at once. Written to <outdir>/<variable>_animation.gif.

Options:

--variable hs|hr|qr|hg|gampt_ff   which grid to export (default: hs)
--formats geotiff,png,kml,gif     any comma-combination (kml implies png)
--vmax 5.0                        colour-scale max; omit to auto-scale from the data
--start <ISO datetime>            simulation start time, required only for --formats kml
--outdir <path>                   default: <out folder>/export/<variable>
--river-variable hr               river-channel depth combined with --variable for gif (default: hr)
--gif-duration-ms 200             milliseconds per GIF frame
--hillshade-azimuth 315           sun direction for the hillshade, degrees (default: 315 = NW)
--hillshade-altitude 45           sun elevation for the hillshade, degrees
--hillshade-vert-exag 30          vertical exaggeration — see note below

--start matches what Kml_input.txt used to hold for the original makeKml.exe — the real-world date/time your simulation's t=0 corresponds to.

On --hillshade-vert-exag: a coarse regional-scale DEM (e.g. a 15-arcsec/~464m grid) has gentle cell-to-cell slopes even across real mountains, so the physically "correct" exaggeration of 1.0 renders as a nearly flat gray — confirmed directly against the Rokan basin's own DEM (std of the shading value was 0.03 at vert_exag=1 vs. 0.20 at vert_exag=100, the value that actually shows visible relief for that 464m grid). The default of 30 is a reasonable middle ground; raise it further for coarse/regional DEMs, lower it for fine ones like DEMNAS.

Georeferencing assumes latlon coordinates (utm=0 in RRI_Input.txt), which is what every local project uses; a UTM-mode project would need a real projected CRS wired into viz.write_geotiff instead of its current EPSG:4326 default.

Velocity vector map (--formats vector,vectorgif)

The kind of flow-direction map iRIC/MIKE/HEC-RAS/ANSYS show — magnitude-colored arrows over terrain, not just a depth-colored raster:

vflood-export RRI_Input.txt --formats vectorgif --vector-stride 6

Needs hs/hr/qr/qu/qv .out files all present (run vflood-rri with outswitch_qu=1 and outswitch_qv=1 set — see §5). Combines slope velocity (derived from qu/qv/hs — velocity.slope_velocity) with river velocity (derived from qr/hr/channel width — velocity.river_velocity_magnitude, direction from the cell's own D8 flow-direction code), one vector field per timestep, over the same DEM+hillshade basemap --formats gif uses. --variable is ignored for these two formats — they always need all five inputs together.

  • vector — one velocity_NNNNNN.png per timestep.
  • vectorgif — velocity_animation.gif, the whole sequence animated (this is the "seems to move" output — real temporal evolution of the flow field, frame to frame, not a fake-motion trick like line-integral convolution or animated streaklines, which this doesn't attempt).

Arrows are direction-only, drawn at a fixed length — color (not arrow length) carries the magnitude. A shallow-water model always has a few "wetting front" cells sitting at just-above-minimum depth; dividing discharge by that near-zero depth produces enormous, physically meaningless velocity spikes, and letting those few spikes drive matplotlib's normal auto-scaled arrow length stretches a handful of arrows across the entire map while shrinking every real arrow to invisible — confirmed directly (an early version of this feature looked exactly like that against the Rokan basin, fixed by switching to fixed-length arrows). --vector-stride 6 (every 6th cell in both axes gets an arrow) and the velocity functions' own min_depth=0.05m guard (velocity.py) are the two knobs that most affect how readable a given basin's map turns out.

Velocity itself (m/s) is not a native RRI output — RRI only ever reports discharge (qr, qu, qv). velocity.py derives it: V = Q / (width · depth) for the river, V = Q / (cross-section length · depth) for slope — a genuinely new VFlood-RRI capability, not a Fortran port, so treat it with the same "new, checked directly rather than against reference output" caution as the rest of §10's new-capability rows.