Lazy load Maplibre GL JS and add hillshading layer

This commit is contained in:
Norbert Renner 2022-06-13 12:17:24 +02:00
parent f92d2e2227
commit 13efb4864c
11 changed files with 314 additions and 15 deletions

View file

@ -240,6 +240,21 @@ BR.LayersConfig = L.Class.extend({
return new leafletOsmNotes();
},
createMvtLayer: function (props) {
const options = {};
if (props.url in BR.layerIndex) {
// url is key to style in local layers bundle (file name without '.json'),
// suggested file naming convention: `<layer id>-style.json`
options.style = BR.layerIndex[props.url];
} else {
// external URL to style.json
options.style = props.url;
}
return BR.maplibreGlLazyLoader(options);
},
createLayer: function (layerData) {
var props = layerData.properties;
var url = props.url;
@ -326,6 +341,8 @@ BR.LayersConfig = L.Class.extend({
layer = this.createOverpassLayer(props.query, props.icon);
} else if (props.dataSource === 'OpenStreetMapNotesAPI') {
layer = this.createOpenStreetMapNotesLayer();
} else if (props.type === 'mvt') {
layer = this.createMvtLayer(props);
} else {
// JOSM
var josmUrl = url;

View file

@ -46,13 +46,14 @@ BR.LayersTab = BR.ControlLayers.extend({
title: i18next.t('layers.opacity-slider'),
callback: function (opacity) {
for (var i = 0; i < self._layers.length; i++) {
if (!self._layers[i].overlay || !map.hasLayer(self._layers[i].layer)) {
const layer = self._layers[i].layer;
if (!self._layers[i].overlay || !map.hasLayer(layer)) {
continue;
}
if (self._layers[i].layer.setOpacity) {
self._layers[i].layer.setOpacity(opacity);
} else {
self._layers[i].layer.setStyle({ opacity: opacity });
if (layer.setOpacity) {
layer.setOpacity(opacity);
} else if (layer.setStyle) {
layer.setStyle({ opacity: opacity });
}
}
},

View file

@ -0,0 +1,64 @@
/**
* Only load Maplibre bundles when layer is actually added, using dynamic imports
*/
BR.MaplibreGlLazyLoader = L.Layer.extend({
initialize: function (options) {
this.options = options;
},
onAdd: function (map) {
if (!('maplibreGL' in L)) {
this._load();
} else {
this._addGlLayer();
}
return this;
},
onRemove: function (map) {
this._map.removeLayer(this.glLayer);
this.glLayer = null;
return this;
},
// needed when overlay, also requires `position: absolute` (see css)
setZIndex: function (zIndex) {
this.options.zIndex = zIndex;
return this;
},
setOpacity: function (opacity) {
if (this.glLayer) {
const glMap = this.glLayer.getMaplibreMap();
if (glMap.getLayer('hillshading')) {
glMap.setPaintProperty('hillshading', 'hillshade-exaggeration', opacity);
} else {
glMap.getCanvas().style.opacity = opacity;
}
}
},
_load: async function () {
await import('./maplibre-gl.js');
await import('./leaflet-maplibre-gl.js');
this._addGlLayer();
},
_addGlLayer: function () {
this.glLayer = L.maplibreGL(this.options);
this._map.addLayer(this.glLayer);
this._updateZIndex();
},
_updateZIndex: function () {
if (this.glLayer && this.glLayer.getContainer() && this.options.zIndex != null) {
this.glLayer.getContainer().style.zIndex = this.options.zIndex;
}
},
});
BR.maplibreGlLazyLoader = function (options) {
return new BR.MaplibreGlLazyLoader(options);
};