README.md (5279B)
1 # Profile Interpreter 2 3 A QGIS 3.40+ plugin for placing 3D interpretation points by clicking directly 4 on the **Elevation Profile** view. 5 6 It is data-agnostic: use it to digitize geological boundaries, borehole picks, 7 geophysical layer tops, or any other interpretation on a profile/cross-section 8 view — for example the profiles produced by the 9 [TEM Loader](https://gitlab.com/qgeomodel/qgis-tem-loader) plugin. 10 11 ## How it works 12 13 When you click on the elevation profile, the plugin converts the click into a 14 real-world 3D coordinate: 15 16 ``` 17 click position (canvas pixels) 18 -> QgsElevationProfileCanvas.canvasPointToPlotPoint() 19 -> QgsProfilePoint(distance_along_section, elevation) 20 -> interpolate X/Y along the profile curve at `distance` 21 -> QgsPoint(x, y, z = elevation) -> PointZ feature 22 ``` 23 24 The clicked vertical position becomes the feature's elevation (Z), and the 25 horizontal position is mapped back to a true map X/Y along the cross-section 26 line. If the **active layer** is an editable PointZ vector layer, clicked points land 27 there (only the fields that already exist are written; the schema is never 28 altered). Otherwise points are stored in a memory layer named 29 **Profile interpretations** with `id`, `distance`, and `elevation` fields. 30 31 ## Requirements 32 33 - QGIS 3.40.0 or later (QGIS 4.x is also supported) 34 - Python 3 (bundled with QGIS) 35 36 ## Installation 37 38 1. Build the zip: `make package`. 39 2. In QGIS: **Plugins > Manage and Install Plugins > Install from ZIP**. 40 3. Select `profile_interpreter.zip` and click **Install Plugin**. 41 42 ## Usage 43 44 1. Load data that supports elevation profiles (e.g. TEM Loader layers). 45 2. Open the profile panel: **View > Elevation Profile**, then draw a profile 46 line across your data so the section renders. 47 3. Toggle **Interpret on Profile** on. The button sits on the Elevation Profile 48 panel's own toolbar; every open profile panel has its own button. 49 4. Click on the profile where you interpret a boundary. A PointZ feature is 50 added to the active layer (if it is a writable PointZ layer) or to the 51 fallback **Profile interpretations** memory layer. The point's X/Y/Z is 52 printed to the Python console and shown in the message bar. 53 5. To remove the point you just placed, click **Undo Point**. While the tool is 54 on, this button is added next to **Interpret on Profile** on the panel 55 toolbar, and stays disabled until you have placed at least one point in that 56 panel. Repeated clicks walk back through the points in reverse order. 57 6. To move a point, check **Edit Point**, click the point (it is selected), then 58 click its new position. Its `distance` and `elevation` fields are updated if 59 the layer has them. Right-click or uncheck **Edit Point** to cancel a 60 selection. 61 7. To remove a point, check **Delete Point** and click the point. 62 8. **Edit Point** and **Delete Point** sit next to **Undo Point** on the panel 63 toolbar. Only one of them can be checked at a time; 64 with neither checked, clicks add points. A point counts as clicked when it is 65 drawn within 10 pixels of the cursor. 66 9. Toggle the tool off to return to normal pan/zoom on the profile. 67 10. With several profile panels open, each one works on its own: it has its own 68 on/off state, Edit/Delete mode and **Undo Point** history, and several 69 panels can be on at once. Points from all panels go to the same target 70 layer. 71 72 # Limitations 73 74 - When no active PointZ layer is set, interpretation points are stored in an 75 in-memory fallback layer only; there is no GeoPackage persistence or 76 per-boundary classification. 77 - The plugin finds profile panels by walking the Qt widget tree 78 (`findChildren(QgsElevationProfileCanvas)`) whenever a window is added to the 79 QGIS main window; there is no official PyQGIS accessor or signal. 80 - **Undo Point** only walks back points placed in the current QGIS session, in 81 reverse order; it does not participate in QGIS's own undo stack (points are 82 written straight to the data provider, not through an edit buffer). 83 - Moving and deleting points cannot be undone. **Undo Point** skips deleted 84 points; undoing after moving a point deletes the moved point. 85 - **Edit Point** and **Delete Point** only search the layer new points go to 86 (the active PointZ layer, otherwise the fallback memory layer). Selecting a 87 point for editing replaces that layer's current selection, so two panels 88 editing the same layer share one selection highlight. 89 - The buttons are placed on a profile panel by locating the panel's toolbar in 90 the Qt widget tree. If a QGIS build lays the panel out differently, that 91 panel gets no buttons. 92 - Picking another tool on the panel toolbar (Pan, Identify, Measure) leaves 93 **Interpret on Profile** checked; toggle it off and on again to resume. 94 - Placing and moving points follow the profile's snap toggle (magnet icon): 95 with snapping on, the point lands on the snapped crosshair position. 96 Selecting a point for **Edit Point** or **Delete Point** uses the raw cursor. 97 98 ## Development 99 100 ```sh 101 make lint # run flake8 102 make test # run unit tests (no QGIS required) 103 make verify # lint + test (what CI runs) 104 make package # build profile_interpreter.zip for installation 105 make clean # remove the zip 106 ``` 107 108 ## License 109 110 ISC: see [LICENSE](LICENSE).