vue-mapbox
vue-mapbox copied to clipboard
Update MglGeojsonLayer after set mapStyle
HI! I have a MglGeojsonLayer component with polygon
<MglGeojsonLayer sourceId="sourceId" :source="source" layerId="layerId" :layer="layer" :clearSource="false" />
And some method like this: this.mapStyle = 'mapbox://styles/mapbox/light-v9';
After map style is changed, the polygon disappears. What is the right way to update source and layer in MglGeojsonLayer component to show polygon again?
How I do it is I use computed value for the source and use .sync. When this.features change the layer is updated automatically with new content.
<template lang="pug">
.......
mgl-geojson-layer(
:layerId="getLayerId"
:sourceId="getSourceId",
:source.sync="getSource"
:layer="getLayer"
)
.......
computed: {
.......
getSource() {
return {
data: {
type: 'FeatureCollection',
features: this.features,
},
};
},
.......
}
......
I tried calling $_deferredMount() (see https://github.com/soal/vue-mapbox/blob/master/src/components/layer/GeojsonLayer.js#L104) after the map event style.load (which seems like it is emitted after a new style is fully loaded). That seemed to work initially (the layer was visible again), but the watchers on the source data were broken, so changes to the source no longer affected the layer.
I tried a variety of things that didn't work and ended up hitting it with a hammer. I put a key property on each geoJsonLayer, and I update it after style.load, forcing all of the geoJsonLayers to be recreated. Doing this on the map works, too, but that'll mean another map load (which is how usage is billed).
So something like this:
<MglMap
:mapStyle="mapStyle"
@load="onMapLoaded"
>
<MglGeojsonLayer
:sourceId="tripsGeoJson.data.id"
:source.sync="tripsGeoJson"
:replace-source="true"
:layerId="tripsGeoJson.data.id"
:layer="tripLineLayer"
:key="'trips' + mapKey"
/>
</MglMap>
async onMapLoaded(event) {
event.map.on('style.load', async () => {
this.mapKey = Date.now();
});
}
There's probably a cleaner way to do this. If you find it, please share.
I agree this feels like too much of a hack, but it works! The click handler remains intact which is important in my case.
I tried the suggested method of calling this.map.addLayer() from #146 referencing the geoJsonSource object, but that didn't work. No errors, but the layer wasn't rendered after the style change. I dug a little deeper and found this solution which at least works even if it feels less elegant.