QGIS rasters and temporal controller
The Wflow temporal rasters, which are NetCDFs with x, y and time dimensions, have always had poor support in QGIS, despite GDAL having support for time dimensions QGIS having the Temporal Controller. QGIS thinks that the time dimensions are bands and tries to assign the RGB fields to the first three layers. So it is not easy to visualize the rasters over time using the slider in the Temporal Controller.
There was a QGIS issue open about this: https://github.com/qgis/QGIS/issues/36251 But I just checked out the changelog of QGIS 3.44 and saw this: https://changelog.qgis.org/en/version/3.44/#rastertemporal-add-fixed-datetime-raster-temporal-
It turns out that it is now possible to get fast rasters over time in QGIS. It doesn't work well out of the box but I'll record the steps needed here. It might be nice to document these steps, or use this as a basis to further simplify this visualization and/or fund QGIS developments to improve this.
If you load the NetCDFs as a Mesh layer the Temporal Controller does work well out of the box, but it tends to load only some pixels, which is useless.
The result looks like this:
https://github.com/user-attachments/assets/5d25713d-82b1-4667-a7b5-c51718aecdc7
Here are the steps to visualize a NetCDF raster over time
- Load a NetCDF as a raster layer.
- Switch the symbology to a singleband visualization.
- In the temporal properties, enable Dynamic Temporal Control, and set to Fixed Time Range Per Band. The begin and end columns are not pre-filled, and need to computed. Click Calculate Beginning and then Calculate End. For beginning, the pre-filled expression is
make_datetime(2025,1,1,0,0,0) + make_interval(days:=@band), which is incorrect. Since I know the model starttime is July 20210, we do get a correct time withmake_datetime(2010,7,1,0,0,0) + make_interval(days:=@band). This is a bit hacky and it would be nice if this table could be automatically filled in correctly.
- Enable the Temporal Controller by clicking the clock, click "Set to Full Range", and see the raster updating smoothly as you slide the time slider.
Note that once these styles are set, you can save them as a QML and place them next to the NetCDF, such that QGIS loads it automatically when loading the NetCDF.
In the QML XML it then looks like:
<qgis version="3.44.0-Solothurn" styleCategories="Symbology|Temporal">
<temporal mode="3" enabled="1" bandNumber="1" fetchMode="0">
<ranges>
<range begin="2010-07-02T00:00:00" end="2010-07-02T23:59:59" includeEnd="1" band="1" includeBeginning="1"/>
<range begin="2010-07-03T00:00:00" end="2010-07-03T23:59:59" includeEnd="1" band="2" includeBeginning="1"/>
An intermediate workaround may be to generate these QMLs automatically.
Nice @visr and indeed good to document this! We ran into this issue in past wflow trainings too, where users with limited python knowledge wanted to visualize the nc outputs in QGIS and simply slide the time bar. I also remember they asked why this worked for other layers (if I recall correctly, the forcing ones) but not for the wflow outputs.
Ah yes I only tried it on the output, but we should check if e.g. the presence of additional dimensions confuses QGIS.
Yeah indeed, really nice, thanks for taking the time to explore and writing it in this issue @visr!
Nice @visr and indeed good to document this! We ran into this issue in past wflow trainings too, where users with limited python knowledge wanted to visualize the nc outputs in QGIS and simply slide the time bar. I also remember they asked why this worked for other layers (if I recall correctly, the forcing ones) but not for the wflow outputs.
Indeed, I think it was related due to people opening the output.nc as a mesh, as it has the temporal controller support. However, the mesh some strange interpolation (related to assuming data is on the edges vs nodes or something), which becomes problematic for a layer as river discharge due to the many missing cells. For full catchment covering data, this was less of an issue as this interpolation works better. Still much better to show that actual rasters, as shown in this example.