Skip to content Skip to sidebar Skip to footer

Mapbox Style Changes/breaks On Zoom When A Layer Is Added

I have a mapbox map, initialized with the outdoors-v9 style (tried other styles, same behavior). When I add a layer to the map - a marker or a geojson source and zoom the map, the

Solution 1:

Vue data() properties are reactive, they have getters and setters, so, when loading map object or adding vector tiles layer (geojson), Vue tries to add getters & setters to the map & map.layers which causes vue & vue-dev-tools to crash and mess up the map.

If you enable any raster layer, it would work successfully because raster tiles are loaded via the mapbox.css whereas vector tiles being geojson, are added to the map object.

Easiest solution would be to define a non-reactive variable in vue and then re-use it everywhere.

// edit: A correct/recommended way to set non-reactive data: GitHub link

Solution 2:

Seems the issue was related with the fact that I'm pushing the marker instance to an observable (a vuejs data field). After pushing the marker instance to an array, the issue disappeared. This comment doesn't really answer why this happens, but hope it helps someone else that might face the same issue

Solution 3:

I just faced this issue and realized that I didn't follow the documentation exactly as it was described (jumped right on to coding without reading properly). And the documentation says:

Storing Map object

Take note that it's generally bad idea to add to Vuex or component's data anything but primitive types and plain objects. Vue adds getters and setters to every property, so if you add Map object to Vuex store or component data, it may lead to weird bugs. If you want to store map object, store it as non-reactive property like in example below.

The problem was that I had also registered "map" inside the "data" object of my Vue component. But in the example code it's not declared in data, only in the "create" function.

https://soal.github.io/vue-mapbox/guide/basemap.html#map-loading

Solution 4:

After hours spent on this problem, here is my working solution to access map instance from a store (thanks to https://github.com/vuejs/vue/issues/2637#issuecomment-331913620):

const state = reactive({
  map: Object.freeze({ wrapper: /* PUT THE MAP INSTANCE HERE */ });
});

Here is an example with Vue Composition Api:

index.js

import { reactive, computed } from"@vue/composition-api";

exportconst state = reactive({
  map: null
});

exportconstsetMap = (map) => {
  state.map = Object.freeze({ wrapper: map});
};

exportconst getMap = computed(() => state.map.wrapper);

exportconstinitMap = (event) => {
  setMap(event.map);

  // now you can access to map instance from the "getMap" getter!
  getMap.value.addSource("satellite-source", {
    type: "raster",
    url: "mapbox://mapbox.satellite",
  }); 
  getMap.value.addLayer({
    id: "satellite-layer",
    type: "raster",
    source: "satellite-source"
  });
};

App.vue

<template><MglMap:accessToken="...":mapStyle="..." @load="onMapLoaded" /></template><script>import { defineComponent } from"@vue/composition-api";
import { MglMap } from"vue-mapbox";
import { initMap } from"./index.js";

exportdefaultdefineComponent({
  components: {
    MglMap
  },
  setup() {
    constonMapLoaded = (event) => {
      initMap(event);
    }

    return { onMapLoaded };
  }
});
</script>

Solution 5:

I've got the same error. This happens if you either put the map or the marker on an reactive vue.js instance.

Post a Comment for "Mapbox Style Changes/breaks On Zoom When A Layer Is Added"