qgis-profile-interpreter

qgis plugin for placing 3D points along elevation profiles
git clone git://src.adamsgaard.dk/qgis-profile-interpreter # fast
git clone https://src.adamsgaard.dk/qgis-profile-interpreter.git # slow
Log | Files | Refs | README | LICENSE Back to index

commit f6d7559e83c8b55795bdf38416418c054ac5d18c
parent 2e04edc4bd5cd1a7db9fad42c0aadb47eeef89c3
Author: Anders Damsgaard <anders@adamsgaard.dk>
Date:   Fri,  5 Jun 2026 21:43:18 +0300

refactor: drop note field from fallback layer; remove dead stubs (B3+T6+B7)

Diffstat:
MREADME.md | 6++----
Mprofile_interpreter/profile_interpreter.py | 1-
Mtest/fakeqgis.py | 3---
Mtest/test_profile_interpreter.py | 20+++++++++++++++++---
4 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/README.md b/README.md @@ -26,8 +26,7 @@ horizontal position is mapped back to a true map X/Y along the cross-section line. If the **active layer** is an editable PointZ vector layer, clicked points land there (only the fields that already exist are written; the schema is never altered). Otherwise points are stored in a memory layer named -**Profile interpretations** with `id`, `distance`, `elevation`, and `note` -fields. +**Profile interpretations** with `id`, `distance`, and `elevation` fields. ## Requirements @@ -57,8 +56,7 @@ fields. - When no active PointZ layer is set, interpretation points are stored in an in-memory fallback layer only; there is no GeoPackage persistence or - per-boundary classification for that layer yet. The `note` field exists in - the fallback layer schema but has no input UI. + per-boundary classification. - The plugin grabs the profile canvas by walking the Qt widget tree (`findChildren(QgsElevationProfileCanvas)`); there is no official PyQGIS accessor. With multiple profile docks open it picks the first visible one. diff --git a/profile_interpreter/profile_interpreter.py b/profile_interpreter/profile_interpreter.py @@ -255,7 +255,6 @@ class ProfileInterpreterPlugin: QgsField('id', QMetaType.Type.Int), QgsField('distance', QMetaType.Type.Double), QgsField('elevation', QMetaType.Type.Double), - QgsField('note', QMetaType.Type.QString), ]) layer.updateFields() project.addMapLayer(layer) diff --git a/test/fakeqgis.py b/test/fakeqgis.py @@ -330,9 +330,6 @@ class QgsElevationProfileCanvas: def isVisible(self): return self._visible - def setSnappingEnabled(self, v): - pass - def setTool(self, tool): self._tool = tool diff --git a/test/test_profile_interpreter.py b/test/test_profile_interpreter.py @@ -53,9 +53,6 @@ class _FakeCanvas: def crs(self): return self._crs_val if self._crs_val is not None else fq._FakeCrs() - def setSnappingEnabled(self, v): - pass - def setTool(self, tool): self._tool = tool @@ -408,6 +405,23 @@ class TestFindProfileCanvas(unittest.TestCase): self.assertIsNone(plugin._find_profile_canvas()) +# ── _interpretation_layer field names ──────────────────────────────────── + +class TestInterpretationLayerFields(unittest.TestCase): + def setUp(self): + fq.QgsProject._instance = None + fq.QgsGeometry._next_interpolate_empty = False + + def test_fallback_layer_has_exactly_id_distance_elevation(self): + plugin, _ = _make_plugin(active_layer=None) + plugin._on_pick(_FakeEvent()) + layer = plugin._layer + self.assertIsNotNone(layer) + field_names = {f.name() for f in layer.fields()} + self.assertEqual(field_names, {'id', 'distance', 'elevation'}) + self.assertNotIn('note', field_names) + + # ── addFeatures failure ─────────────────────────────────────────────────── class TestOnPickAddFeaturesFailure(unittest.TestCase):