Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add temporal Flow and Basin results to QGIS. #2208

Merged
merged 5 commits into from
Apr 7, 2025
Merged

Conversation

evetion
Copy link
Member

@evetion evetion commented Apr 4, 2025

And adds "show topology" button on the layer context menu.

Fixes #2178
Fixes #2171

This creates a new Results group in QGIS for each loaded model, and adds a BasinNode and FlowLink layer to it. These are duplicates of the Node and Link layer for the result data (and thus only keeping node_type=Basin, and link_type=flow).

Result arrow files (basin, flow and concentration) are read with pandas and indexed on time (concentration is widened first) and saved on the widget. Fields on the BasinNode and FlowLink are created to store the result variables. A specific time slice, by default the last, or by a signal from the temporal manager is then used to update these fields. The temporal manager is initialized based on the start/endtime and timestep from .toml file.

In effect you now have Node and Link tables with all result variables for a given timestep, meaning you're free to add symbology/labels as you would for any (static) layer.

The layer context menu is expanded to show a "Show topology" checkmark, which sets a layer variable, which in turn is used by the layer symbology to either show @geometry or make_line(start_point(@geometry), end_point( @geometry)).


For @Huite and @JoerivanEngelen, updating the (memory) layers on the fly, and not using QGIS to read arrow files is essential for performance. Further performance was gained by not iterating over the layer features and updating them, but by setting them directly based on the fid (order). Note that the memory copy does not use the same fids as our geopackage layers, and you can't control them. The last factor of performance was disabling the automatic undo functionality (or rather creating 1 undo, instead of one for each feature) when updating the layer.

@visr
Copy link
Member

visr commented Apr 4, 2025

This is very very nice. I like how it dynamically fills in the tables and things I tried like adding a label with the flow rate just seem to work:
image

Here I used format_number("flow_rate", 2) to avoid getting the full Float64 printed. Perhaps we should add something like this in the default style?

If I remove a model and load it in in the same QGIS session it seems the show topology context is getting added another time:

image

Also it seemed to only work for me on the results but not the Link layer?

Further the BasinNode symbology uses relative_error by default(last column); can that be level (first column)?

These other things are perhaps better as follow ups:

@visr
Copy link
Member

visr commented Apr 4, 2025

If I do "remove group" on the HWS model and then open it again I consistently get:

Traceback (most recent call last):
  File "C:\Users/visser_mn/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\ribasim_qgis\widgets\dataset_widget.py", line 620, in _update_arrow_layers
    self._update_arrow_layer(
  File "C:\Users/visser_mn/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\ribasim_qgis\widgets\dataset_widget.py", line 593, in _update_arrow_layer
    layer.startEditing()
RuntimeError: wrapped C/C++ object of type QgsVectorLayer has been deleted

@evetion
Copy link
Member Author

evetion commented Apr 4, 2025

Traceback (most recent call last):
File "C:\Users/visser_mn/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\ribasim_qgis\widgets\dataset_widget.py", line 620, in _update_arrow_layers
self._update_arrow_layer(
File "C:\Users/visser_mn/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\ribasim_qgis\widgets\dataset_widget.py", line 593, in _update_arrow_layer
layer.startEditing()
RuntimeError: wrapped C/C++ object of type QgsVectorLayer has been deleted

I've seen this before and refactored a large part of the signals because of it, but I think it only triggers once you got another error first?

Here I used format_number("flow_rate", 2) to avoid getting the full Float64 printed. Perhaps we should add something like this in the default style?

Sure, will add it. What do you suggest for Basin labels?

Also it seemed to only work for me on the results but not the Link layer?

Yes, it only sets a variable on the layer, the style has to use that variable. Will update the default style to do so as well.

If I remove a model and load it in in the same QGIS session it seems the show topology context is getting added another time:

Ouch, nice find. It's hijacking of the contextmenu signal, and it does so for the DatasetWidget (repeated for each dataset), that should probably be the Ribasim widget, or check for an existing widget.

Further the BasinNode symbology uses relative_error by default(last column); can that be level (first column)?

Sure, but that's hard to style consistently, would have to make an update symbology after arrow load for it, based on min/max or so.

@Huite
Copy link
Contributor

Huite commented Apr 4, 2025

Traceback (most recent call last):
File "C:\Users/visser_mn/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\ribasim_qgis\widgets\dataset_widget.py", line 620, in _update_arrow_layers
self._update_arrow_layer(
File "C:\Users/visser_mn/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\ribasim_qgis\widgets\dataset_widget.py", line 593, in _update_arrow_layer
layer.startEditing()
RuntimeError: wrapped C/C++ object of type QgsVectorLayer has been deleted

I've seen this before and refactored a large part of the signals because of it, but I think it only triggers once you got another error first?

My guess here is that arrow layer in Python hasn't been updated after group deletion?
If you delete the group, the Qt memory manager will delete the group, but Python won't. So if you then to try access the Python object, it'll obviously try to look at something that's been deleted.
You could try connecting to the group deleted signal (or something). But this signal might not exist, or there might be a bunch of ways in which the group can get up deleted.

Alternatively, you just catch the exception and update the Python state then? Might be the most robust and simple.

@visr
Copy link
Member

visr commented Apr 4, 2025

What do you suggest for Basin labels?

Hmm by default nothing I guess so it doesn't get confused with flow rates? Otherwise level, would be nice if that is already prepared and folks just have to enable it.

would have to make an update symbology after arrow load for it, based on min/max or so

You wanted that for flow_rate as well right? Also fine with me as a follow up.

@visr
Copy link
Member

visr commented Apr 4, 2025

Another follow up, since I see you already add concentration data, would be to add allocation results, see also #2196.

@evetion
Copy link
Member Author

evetion commented Apr 4, 2025

Ok, this is good for review/merge.

Fixed:

  • Remove our Python reference (used in the update arrow layers) to our layers when layers are about to be removed. Should fix the C++ Wrapper errors.
  • Hide the Results group by default
  • Link layer now also supports topology view
  • FlowLink layer has labels by default
  • BasinNode layer now visualizes level (range will be useless for most cases though) and has labels by default.
  • Show topology button will only show up once now
  • Layers are now temporal enabled, enabling resetting of temporal ranges after manual changes:
Screenshot 2025-04-04 at 19 15 17

@evetion evetion merged commit 7be9b61 into main Apr 7, 2025
20 checks passed
@evetion evetion deleted the feat/temporal-qgis branch April 7, 2025 09:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Show topology in QGIS Visualize flows in QGIS
3 participants