Legend panel: new Map() was building an OpenLayers map, not a JS Map

MapView.js imported OpenLayers' map class as a bare `Map`, which shadowed the
global Map for the whole module. `this._legendEntries = new Map()` therefore
constructed a second, target-less OpenLayers map, and the legend registry was
never a Map at all.

Two things kept this hidden. Storing an entry did not throw, because ol/Map
extends ol/Object, which has its own set(key, value) — the wrappers were filed
silently into an OpenLayers property bag and discarded. The for...of in
_updateLegendPanel did throw, since an OpenLayers map is not iterable, but it is
inside a try/catch and only ever surfaced as "legend panel update failed:
TypeError: {} is not iterable". Safari prints the object as {} and its
constructor is also named Map, which is why the warning read as if a plain
object had appeared from nowhere.

So the legend panel has never shown a legend for any layer, which would have
been visible during the layer walkthrough in the board demonstration.

Fixed by removing the shadowing rather than working around it: the import is now
OLMap, the map is constructed with it, and new Map() is the real global Map
again. Verified in a browser against the dev server — the registry is now a Map
with Symbol.iterator, it holds the Digital Earth Africa slope entry, and
_updateLegendPanel runs without throwing. Only this file imported ol/Map.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
ekke 2026-10-21 09:33:47 +02:00
parent ea3ad5726b
commit 577d94ef5b
9 changed files with 50 additions and 46 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
dist/assets/index-BZOjrkLV.js.map vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
import{d as f,z as d}from"./index-ybgDODsx.js";import"./vite-helpers-BlTxHScW.js";import"./bootstrap-D1-uvFxm.js";import"./openlayers-D5-VSKzq.js";import"./ol-ext-DV70ljNY.js";function p(e){return String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;").replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g,"")}function h(e){let l="",o=e;for(;o>=0;)l=String.fromCharCode(o%26+65)+l,o=Math.floor(o/26)-1;return l}function x(e){return e&&!Array.isArray(e)&&Array.isArray(e.cells)?{cells:e.cells,bold:!!e.bold}:{cells:Array.isArray(e)?e:[e],bold:!1}}function u(e){const l=[];return e.forEach((o,n)=>{const{cells:t,bold:a}=x(o),r=a?' s="1"':"",i=t.map((s,c)=>{const m=`${h(c)}${n+1}`;return s==null||s===""?`<c r="${m}"${r}/>`:typeof s=="number"&&Number.isFinite(s)?`<c r="${m}"${r}><v>${s}</v></c>`:`<c r="${m}"${r} t="inlineStr"><is><t xml:space="preserve">${p(s)}</t></is></c>`}).join("");l.push(`<row r="${n+1}">${i}</row>`)}),`<?xml version="1.0" encoding="UTF-8" standalone="yes"?> import{d as f,z as d}from"./index-BZOjrkLV.js";import"./vite-helpers-BlTxHScW.js";import"./bootstrap-D1-uvFxm.js";import"./openlayers-D5-VSKzq.js";import"./ol-ext-DV70ljNY.js";function p(e){return String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;").replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g,"")}function h(e){let l="",o=e;for(;o>=0;)l=String.fromCharCode(o%26+65)+l,o=Math.floor(o/26)-1;return l}function x(e){return e&&!Array.isArray(e)&&Array.isArray(e.cells)?{cells:e.cells,bold:!!e.bold}:{cells:Array.isArray(e)?e:[e],bold:!1}}function u(e){const l=[];return e.forEach((o,n)=>{const{cells:t,bold:a}=x(o),r=a?' s="1"':"",i=t.map((s,c)=>{const m=`${h(c)}${n+1}`;return s==null||s===""?`<c r="${m}"${r}/>`:typeof s=="number"&&Number.isFinite(s)?`<c r="${m}"${r}><v>${s}</v></c>`:`<c r="${m}"${r} t="inlineStr"><is><t xml:space="preserve">${p(s)}</t></is></c>`}).join("");l.push(`<row r="${n+1}">${i}</row>`)}),`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><sheetData>${l.join("")}</sheetData></worksheet>`}const y=`<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><sheetData>${l.join("")}</sheetData></worksheet>`}const y=`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"> <styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<fonts count="2"><font><sz val="11"/><name val="Calibri"/></font><font><b/><sz val="11"/><name val="Calibri"/></font></fonts> <fonts count="2"><font><sz val="11"/><name val="Calibri"/></font><font><b/><sz val="11"/><name val="Calibri"/></font></fonts>
@ -27,4 +27,4 @@ ${n.map(t=>`<Relationship Id="rId${t.id}" Type="http://schemas.openxmlformats.or
`)} `)}
<Relationship Id="rIdStyles" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/> <Relationship Id="rIdStyles" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
</Relationships>`,o["xl/styles.xml"]=y,d(o,"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")}function S(e,l){f(g(e),l)}export{g as buildXlsxBlob,S as exportXlsx}; </Relationships>`,o["xl/styles.xml"]=y,d(o,"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")}function S(e,l){f(g(e),l)}export{g as buildXlsxBlob,S as exportXlsx};
//# sourceMappingURL=xlsx-x-C7b9wf.js.map //# sourceMappingURL=xlsx-q0F9FUtJ.js.map

File diff suppressed because one or more lines are too long

2
dist/index.html vendored
View File

@ -2004,7 +2004,7 @@
} }
</style> </style>
<script type="module" crossorigin src="/assets/index-ybgDODsx.js"></script> <script type="module" crossorigin src="/assets/index-BZOjrkLV.js"></script>
<link rel="modulepreload" crossorigin href="/assets/vite-helpers-BlTxHScW.js"> <link rel="modulepreload" crossorigin href="/assets/vite-helpers-BlTxHScW.js">
<link rel="modulepreload" crossorigin href="/assets/bootstrap-D1-uvFxm.js"> <link rel="modulepreload" crossorigin href="/assets/bootstrap-D1-uvFxm.js">
<link rel="modulepreload" crossorigin href="/assets/openlayers-D5-VSKzq.js"> <link rel="modulepreload" crossorigin href="/assets/openlayers-D5-VSKzq.js">

View File

@ -16,7 +16,11 @@
* map.addMarker(lon, lat, { name: 'Point A' }); * map.addMarker(lon, lat, { name: 'Point A' });
*/ */
import Map from 'ol/Map'; // Imported as OLMap, not Map: a bare `Map` here shadows the global Map for the
// whole module, and `new Map()` then silently builds an OpenLayers map. That
// is what broke the legend panel — ol/Object provides .set(), so storing an
// entry appeared to work, and only the for...of in _updateLegendPanel failed.
import OLMap from 'ol/Map';
import View from 'ol/View'; import View from 'ol/View';
import Overlay from 'ol/Overlay'; import Overlay from 'ol/Overlay';
import TileLayer from 'ol/layer/Tile'; import TileLayer from 'ol/layer/Tile';
@ -257,7 +261,7 @@ export class MapView {
// initEditBar() will insert its Drawings group above those. // initEditBar() will insert its Drawings group above those.
// Final LayerSwitcher order (top → bottom): // Final LayerSwitcher order (top → bottom):
// Overlays, Drawings, Measurements, Markers, Base Maps // Overlays, Drawings, Measurements, Markers, Base Maps
this.map = new Map({ this.map = new OLMap({
target: targetId, target: targetId,
layers: [ layers: [
baseLayers, baseLayers,