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:00This 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/ArcGIShs_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 oldmakeKml.exeoutput, 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 hrEach 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 6Needs 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— onevelocity_NNNNNN.pngper 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.