Skip to content

feat: push the model to GeoViewer (optional button) - #146

Open
lachlangrose wants to merge 1 commit into
feat/viewer-object-registryfrom
feat/push-to-geoviewer
Open

lachlangrose wants to merge 1 commit into
feat/viewer-object-registryfrom
feat/push-to-geoviewer

Conversation

@lachlangrose

Copy link
Copy Markdown
Member

What

An optional Push model to GeoViewer button, in a new GeoViewer tab of the export panel (step 5). It sends the stratigraphic and fault surfaces of the solved model to a running GeoViewer, the advanced 3D viewer. The model and the plugin's own 3D view do not change.

Stacked PR. The base is feat/viewer-object-registry (#145), the top of the usability stack. Merge the stack first.

How it works

  • main/geoviewer/protocol.py: the frame codec of protocol 1.8 (hello, scene.upsert for Group and Surface, scene.remove). Standard library and numpy only. Coordinates are written relative to the origin of the scene (f32, or f64 when a model is more than 4 km from the origin).
  • main/geoviewer/websocket_client.py: a small stdlib WebSocket client with the Authorization: Bearer <token> header. It needs no new dependency.
  • main/geoviewer/link.py: a short session. It connects, says hello, takes the origin that the viewer uses, sends the objects, removes old objects, collects errors, and closes. Nothing stays open, so there is no state to repair when the viewer stops.
  • main/geoviewer/scene.py: turns the model surfaces into objects. Ids start with loopstructural/, so a new push replaces the objects of the last push (objects that are not sent again are removed). Other objects of the scene stay. Faults get a red colour.
  • Export panel: port and token fields (saved in the plugin settings), the choice of surfaces, and the button. It runs on the existing background task.

No change in GeoViewer was necessary: protocol 1.8 already has everything this needs.

Tests

  • 27 new unit tests: the codec, the WebSocket client and the session against a fake viewer (wrong token, nothing listening, origin of the viewer, removal of old objects only with the prefix, refused objects, a large message), and the scene builder.
  • pytest tests/unit: 333 passed.
  • Manual end-to-end check with a real GeoViewer build (geoviewer --port, GEOVIEWER_TOKEN): two pushes in a row gave 6 objects each time, no errors, and the inventory showed no duplicates.
  • Not tested here: the new panel tab in QGIS itself (the panel needs QGIS; it compiles and ruff passes). Please click through it once.

Notes

  • The token is stored in the QGIS settings of the plugin, as plain text. The link accepts connections from 127.0.0.1 only.
  • Colours of the stratigraphic units, the bounding box, DEM and the data layers are not sent. They fit in a follow-up.

🤖 Generated with Claude Code

Add an optional "Push model to GeoViewer" button in a new GeoViewer tab of
the export panel. It sends the stratigraphic and fault surfaces to a running
GeoViewer over its local link (protocol 1.8): a small stdlib WebSocket
client, the frame codec, and a short session that says hello, sends the
objects, and removes the objects of the last push that are not sent again.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@lachlangrose
lachlangrose added this pull request to stack #139 October 23, 2026 00:16

This branch has not been deployed

No deployments
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.

1 participant