From 3b4e228f81556882c852bf058352ab08ed3ccfb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Siffert?= Date: Mon, 29 Jun 2026 22:27:03 +0200 Subject: [PATCH] [FIX] geoengine_tools: don't select measurement features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clicking a drawn ruler / area / proximity geometry crashed with "undefined is not an object (evaluating 'attributes.id')": measurement features live on a dedicated layer but carry no record, so the base select interaction selected them and updateInfoBox/mountGeoengineRecord dereferenced their missing `attributes`. - registerInteraction(): exclude the measurement layer from both select interactions via a `layers` filter. - updateInfoBox(): safety net — ignore features without `attributes`. Co-Authored-By: Claude Opus 4.8 --- .../src/js/geoengine_measure_tools.esm.js | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/geoengine_tools/static/src/js/geoengine_measure_tools.esm.js b/geoengine_tools/static/src/js/geoengine_measure_tools.esm.js index 83a47b1eb..3cfa8a132 100644 --- a/geoengine_tools/static/src/js/geoengine_measure_tools.esm.js +++ b/geoengine_tools/static/src/js/geoengine_measure_tools.esm.js @@ -49,6 +49,44 @@ patch(GeoengineRenderer.prototype, { this._deactivateMeasureTools(); }, + /** + * Reimplemented (vs base) only to exclude the measurement layer from the + * select interactions. Measure geometries carry no record, so selecting + * one would reach mountGeoengineRecord with undefined attributes and crash + * (evaluating 'attributes.id'). + */ + registerInteraction() { + const notMeasureLayer = (layer) => layer !== this._measureLayer; + this.selectPointerMove = new ol.interaction.Select({ + condition: ol.events.condition.pointerMove, + style: this.selectStyle, + layers: notMeasureLayer, + }); + this.selectClick = new ol.interaction.Select({ + condition: ol.events.condition.click, + style: this.selectStyle, + layers: notMeasureLayer, + }); + this.selectClick.on("select", (e) => { + this.updateInfoBox(e.target.getFeatures()); + }); + this.map.addInteraction(this.selectClick); + this.map.addInteraction(this.selectPointerMove); + }, + + /** + * Safety net: ignore features without "attributes" (e.g. measurement + * geometries) so they never reach mountGeoengineRecord. + */ + updateInfoBox(features) { + const feature = features.item(0); + if (feature !== undefined && feature.get("attributes") === undefined) { + this.hidePopup(); + return; + } + return super.updateInfoBox(...arguments); + }, + // ---- Setup ---------------------------------------------------------- _setupMeasureControls() {