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

QGIS: Show data for selected nodes #1648

Closed
visr opened this issue Jul 22, 2024 · 9 comments · Fixed by #1756
Closed

QGIS: Show data for selected nodes #1648

visr opened this issue Jul 22, 2024 · 9 comments · Fixed by #1756
Assignees
Labels
enhancement New feature or request QGIS Ribasim QGIS plugin v1.0 Release!

Comments

@visr
Copy link
Member

visr commented Jul 22, 2024

In QGIS you can select one or more nodes:

image

This can be used to show the Node table for those nodes:

image

However, if you want to see the data associated with this node, you need several extra steps. For instance, open the "Basin / profile" table, apply a field filter on node_id, and enter the node ID you selected manually.

image

Ideally a user can directly see and edit all data for a selected node. Perhaps we can for a node of type X, automatically apply a field filter on all tables X / * to show this. Or perhaps some other way that integrates nicely with existing QGIS functionality exists? Like perhaps automatically doing some kind of joins between these tables.

It looks like this would also be needed for #790.

@visr visr added enhancement New feature or request QGIS Ribasim QGIS plugin labels Jul 22, 2024
@SnippenE SnippenE added the v1.0 Release! label Jul 25, 2024
@deltamarnix
Copy link
Contributor

We are looking for QGIS joining and relations: https://docs.qgis.org/3.34/en/docs/user_manual/working_with_vector/joins_relations.html#setting-relations-between-multiple-layers

I did some small tests. joining is nice when there is a 1-to-1 relation between features in different layers. For example: Basin / state or Basin / area.

I made a model and added Basin / area and Basin / state. Then I set a Joins property on the Basin / area layer. When I then create a layer, and fill in the node_id, it automatically matches the node_id and gives me the information about the node. And I also tried it the other way around. On Node I set a relation to Basin / state, and when you add a new node, it will automatically add a row in the Basin / state if it's not there.

image
image
image

The other option is useful for 1-to-N relations, like Basin / time. Then it's better to use relations and it looks more like this:

image

Both joins and relations are stored in QGIS project files, which means that we have to initialize all those relations every time we will open a toml file. The other option is that we start working with QGIS project files and let users open their projects that way, instead of the Open button in the Ribasim plugin.

@Huite
Copy link
Contributor

Huite commented Aug 2, 2024

Oh, the relations thing looks very good! Does it provide a good table view as well?

That is, what if you click this button:

image

@deltamarnix
Copy link
Contributor

Clicking that button will just bring you to the table I guess.

Another option would be to add relationship tables with SQL queries inside of the geopackage. In that way it is not stored in a qgis project, but in the geopackage itself.

@Huite
Copy link
Contributor

Huite commented Aug 2, 2024

A possible risk with storing it inside of the geopackage is that QGIS / OGR will not be smart enough to see through it when it matters.

For example, if you have transient data associated with vector features, one way to make it known to QGIS is by simply duplicating the geometries for each timestamp and using the Temporal Controller to manage what to show. This has the unfortunate downside of making QGIS quite slow to draw the vector features. The reason is that it's filtering over all features whenever you pan the map view to decide which ones to show.

My guess is: if you store inside of the geopackage, it won't realize the geometries are duplicates. My second guess is: it will know the geometries are duplicated if you set it up via this relationship thing.

You could test it by mocking up e.g. 5 basins with a hundred thousand timestamps or something.

@Huite
Copy link
Contributor

Huite commented Aug 2, 2024

Looks like the second link disproves my guess! That would be excellent news and we would able to keep everything contained in a geopackage.

@visr visr self-assigned this Aug 8, 2024
Jingru923 pushed a commit that referenced this issue Aug 13, 2024
Fixes #1690 as a 🎁 for @deltamarnix when he is back from holiday.

Triggered by #1648, which seems very hard to do in QGIS as it doesn't
support compound indexes and we dislike a separate global unique id. In
a discussion with @visr he mentioned most people don't use the
non-global unique id feature (yet).

Reverts #1513. Partially reverts #1690 as the `NodeID` changes are not
reverted, as it is quite useful to know the node_type in several parts
of the code (instead of only a node_id). Therefore, I've added a new
`NodeID` constructor and joined the Edge table with the Node table.

I had to change the node_ids of several new test models created by
@SouthEndMusic, bit of a pain, but the tests seem to pass still.

Furthermore, I changed the `node.add` functionality to *return* the
`NodeData`, which should make the `edge.add` more straightforward (and
pave the way for automatic id numbering in the future). So this:

```julia
model.terminal.add(Node(terminal_id, Point(500, 200)))
model.tabulated_rating_curve.add(
    Node(6, Point(450, 200)),
    [tabulated_rating_curve.Static(level=[0.0, 1.0], flow_rate=[0.0, 10 / 86400])],
)

model.edge.add(
    model.basin[6],
    model.tabulated_rating_curve[6],
)
model.edge.add(
    model.tabulated_rating_curve[6],
    model.terminal[terminal_id],
)
```
becomes this:

```julia
term = model.terminal.add(Node(terminal_id, Point(500, 200)))
trc0 = model.tabulated_rating_curve.add(
    Node(0, Point(450, 200)),
    [tabulated_rating_curve.Static(level=[0.0, 1.0], flow_rate=[0.0, 10 / 86400])],
)

model.edge.add(
    basin6,
    trc0,
)
model.edge.add(trc0, term)
```

I've made this change in a single Python test model, and in the first
model of the examples notebook. We could gradually change this further
over time.

---------

Co-authored-by: Martijn Visser <mgvisser@gmail.com>
@evetion
Copy link
Member

evetion commented Aug 22, 2024

@Jingru923 Jingru923 assigned evetion and unassigned visr Aug 22, 2024
@evetion
Copy link
Member

evetion commented Aug 24, 2024

So there are roughly three paths for getting the relationship info in QGIS:

  • Implement foreign keys in SQLite and use discover relationships in QGIS
  • Use the GPKG relation extension and populate all the required N-N tables.
  • Make the relationship in QGIS (only)

I like the first option, but SQLite tables can't be altered after creation, so I need to generate the SQL statements myself. I've got it working for pure pandas (so all non-spatial tables), but spatial tables is another beast (ogr generates the schema, not pandas). Besides, it would require duplicating the functionality in PyQGIS (even harder) for all models created there. Still, we might even keep the non-spatial tables foreign key creation in Python, it makes the GPKG "better" imho.

However, I now implemented the third option, which works pretty well. I haven't yet found a way to quickly filter the attribute table, but this is already useful and should be merged:

Identification results

Image

Form with table view (as asked by @Huite above

Image

@evetion
Copy link
Member

evetion commented Aug 25, 2024

With a few events (changedselection) attribute tables are selected in sync with Node selection.
riba_select

Note it needs a fix for the Edge, as only the (last) relationship to_node_id is used, not selecting all related edges.

visr added a commit that referenced this issue Aug 27, 2024
Fixes #1648
Fixes #1755 (by updating the edge style)
Fixes #1688 (node_id has to be unique)

Also sets the node_id and edge_id to be unique, so they are
autogenerated in the edit forms.

The current changes also will make the snapping + edge creation based on
coordinates obsolete, as the form now looks like this:

<img width="701" alt="Screenshot 2024-08-25 at 13 45 11"
src="https://github.com/user-attachments/assets/a4ea6f15-a24f-40a4-ba40-f160f02e93b6">

There are buttons to open a form with the Node, a highlighter to blink
the node on the map, and a map selection panel, where one can click the
desired node.

---------

Co-authored-by: Martijn Visser <mgvisser@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request QGIS Ribasim QGIS plugin v1.0 Release!
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

5 participants