You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
GeoLibreAppAPI exposes getMap(): MapLibreMap | null and addMapControl(control: IControl). Of 141 modules under packages/plugins/src/plugins/, 62 touch the MapLibre map directly (getMap(), addMapControl, an IControl implementation, or a maplibre-gl import): 13 call getMap() and 23 register an IControl.
On the globe getMap() returns null and addMapControl returns false, so those plugins activate and then do nothing visible — the worst failure mode, because the toggle reports success.
Three tiers
Only one of them needs substantial work.
Tier 1 — already engine-neutral
Catalog and service browsers (STAC, Planetary Computer, NASA Earthdata, Source Coop, ArcGIS Hub, Open Data Catalogs, EnviroAtlas, FEMA WMS, …) only call app.addTileLayer / addWmtsLayer / addGeoJsonLayer, which are pure store writes in createAppAPI. These work on the globe today once #2261 covers the layer kind they produce.
Audit which plugins are genuinely store-only and un-gate them.
Tier 2 — DOM controls (23 modules)
Layer control, basemap control, components (legend / colorbar / HTML), time slider, swipe, … A MapLibre IControl is just onAdd(map) → HTMLElement. Two pieces make these portable:
Render the four .maplibregl-ctrl-{top,bottom}-{left,right} corner containers over the Cesium canvas, so control DOM lands in the right place and the scoped overrides in apps/geolibre-desktop/src/index.css keep working unchanged.
Pass onAdd a map facade implementing the subset these controls actually use — getContainer, getCanvas, on / off / once, project / unproject, getCenter / getZoom / getBearing / getPitch, getBounds, flyTo / easeTo / jumpTo. All have exact Cesium equivalents.
The facade must fail loudly on addSource / addLayer / setPaintProperty rather than no-op. That is the honest boundary between tier 2 and tier 3, and a silent no-op there reproduces the exact bug this issue is about.
Tier 3 — plugins that paint through MapLibre
Graticule, H3 / S2 / geohash / A5 / DGGS grids, annotations, geo-editor, effects, clouds, route animation. These need real Cesium implementations (GeoJsonDataSource, Entity, PolylineCollection) or they stay MapLibre-only.
Implement per plugin, as demand dictates. Not a blocker for the rest.
Declare engine support
Add engines?: MapRendererKind[] to the plugin manifest, defaulting to ["maplibre"].
Gate the Plugins menu on it, so a plugin that cannot run on the current engine is greyed out honestly instead of toggling into nothing.
Document it in docs/plugin-api.md — external plugin authors need a declaration point, and this is also the compatibility contract for third-party plugins once a second engine is real.
Depends on
The engines field and the tier 1 audit are independent and cheap — worth doing early. Tier 2's facade is easiest once #2260 has defined MapEngine, since the facade is a thin MapLibre-shaped adapter over the same CesiumEngine.
#2263 builds that facade against two real consumers (Search Places and the Basemaps plugin) and should land before the rest of tier 2 — with the seam in place, the remaining 21 IControl plugins become an audit rather than a design problem.
Part of #2259.
Problem
GeoLibreAppAPIexposesgetMap(): MapLibreMap | nullandaddMapControl(control: IControl). Of 141 modules underpackages/plugins/src/plugins/, 62 touch the MapLibre map directly (getMap(),addMapControl, anIControlimplementation, or amaplibre-glimport): 13 callgetMap()and 23 register anIControl.On the globe
getMap()returnsnullandaddMapControlreturnsfalse, so those plugins activate and then do nothing visible — the worst failure mode, because the toggle reports success.Three tiers
Only one of them needs substantial work.
Tier 1 — already engine-neutral
Catalog and service browsers (STAC, Planetary Computer, NASA Earthdata, Source Coop, ArcGIS Hub, Open Data Catalogs, EnviroAtlas, FEMA WMS, …) only call
app.addTileLayer/addWmtsLayer/addGeoJsonLayer, which are pure store writes increateAppAPI. These work on the globe today once #2261 covers the layer kind they produce.Tier 2 — DOM controls (23 modules)
Layer control, basemap control, components (legend / colorbar / HTML), time slider, swipe, … A MapLibre
IControlis justonAdd(map) → HTMLElement. Two pieces make these portable:.maplibregl-ctrl-{top,bottom}-{left,right}corner containers over the Cesium canvas, so control DOM lands in the right place and the scoped overrides inapps/geolibre-desktop/src/index.csskeep working unchanged.onAdda map facade implementing the subset these controls actually use —getContainer,getCanvas,on/off/once,project/unproject,getCenter/getZoom/getBearing/getPitch,getBounds,flyTo/easeTo/jumpTo. All have exact Cesium equivalents.addSource/addLayer/setPaintPropertyrather than no-op. That is the honest boundary between tier 2 and tier 3, and a silent no-op there reproduces the exact bug this issue is about.Tier 3 — plugins that paint through MapLibre
Graticule, H3 / S2 / geohash / A5 / DGGS grids, annotations, geo-editor, effects, clouds, route animation. These need real Cesium implementations (
GeoJsonDataSource,Entity,PolylineCollection) or they stay MapLibre-only.Declare engine support
engines?: MapRendererKind[]to the plugin manifest, defaulting to["maplibre"].docs/plugin-api.md— external plugin authors need a declaration point, and this is also the compatibility contract for third-party plugins once a second engine is real.Depends on
The
enginesfield and the tier 1 audit are independent and cheap — worth doing early. Tier 2's facade is easiest once #2260 has definedMapEngine, since the facade is a thin MapLibre-shaped adapter over the sameCesiumEngine.#2263 builds that facade against two real consumers (Search Places and the Basemaps plugin) and should land before the rest of tier 2 — with the seam in place, the remaining 21
IControlplugins become an audit rather than a design problem.