phegman / vue-mapbox-gl

A Vue.js component for Mapbox GL JS
GNU General Public License v3.0
270 stars 33 forks source link

Adding markers stop the map from drawing #76

Closed tommed closed 4 years ago

tommed commented 4 years ago

Apologies if this turns out not to be your component's fault, but I'm having some difficulty adding markers to the map without the map's rendering being affected.

I essentially have a map element which after it has loaded I am attempting to add a marker. When the marker is added, it stops the map from drawing details. I have added console logging and am confident the map is loaded at the point the marker is added:

Broken map

mapbox-gl-js version: 1.9.1 mapbox-gl-draw version: 1.1.2

Code snippets

Hopefully this code will help prompt the problem (especially if I'm doing something wrong!),

EditPlan.vue

<!-- Map -->
        <div id="map-panel">
            <Map :default-zoom="zoom"
                :set-center="setCenter"
                @loaded="onMapLoaded"
                @zoomed="(z) => zoom = z"
                @moved="(c) => center = c">

                <!-- POI Markers -->
                <MapMarkers v-if="(plan||{}).pois" 
                    :sectors="plan.pois" 
                    @popup-opened="markerSelected" 
                    @popup-closed="selectedPOIIds = []"
                    @marker-moved="poiMarkerMoved"
                    />
                <!-- EO:POI Markers -->

            </Map>
        </div>
        <!-- EO:Map -->

Map.vue

<template>
    <MglMap access-token="REDACTED_MY_TOKEN" 
            map-style="mapbox://styles/mapbox/streets-v11"
            @load="onMapLoad">
        <MglNavigationControl v-if="!hideNavigation" position="top-right" />
        <MglFullscreenControl v-if="!hideFullscreen" position="top-right" />
        <MglScaleControl v-if="!hideScale" position="bottom-right" />
        <slot></slot>
    </MglMap>
</template>

MapMarkers.vue

<template>
    <div>
        <MapMarker
            v-for="s in sectors"
            :key="s.id"
            :sector="s"
            @popup-opened="e => $emit('popup-opened', e)" 
            @popup-closed="e => $emit('popup-closed', e)"
            />
    </div>
</template>

MapMarker.vue

<template>
    <div></div>
</template>

<script>
import * as utils from '../../plugins/map-utils'

export default {
    props: ['sector'],
    inject: ["mapbox", "map", "actions"],
    data() {
        return {
            marker: null,
            popup: null,
        };
    },
    watch: {
        sector(s) {
            this.recreateMarker(s);
        },
    },
    created() {
        this.recreateMarker(this.sector);
    },
    beforeDestroy() {
        if (this.marker) {
            this.marker.remove();
        }
    },
    methods: {

        recreateMarker(s) {

            // clean up before re-adding?
            if (this.marker) {
                this.marker.remove();
                this.marker = null;
            }

            // build our popup
            // this.popup = new this.mapbox.Popup({ offset: 25 }).setHTML(``);
            // this.popup.on('open', () => setTimeout(() => this.$emit('popup-opened', s), 100)); // avoid timing clashes with popup-closed :-/
            // this.popup.on('close', () => this.$emit('popup-closed', s));

            // and marker
            this.marker = utils
                .sectorMarker(s, this.mapbox)
                .setPopup(this.popup);
                .addTo(this.map);

            // when a marker was moved
            this.marker.on('dragend', () => {
                const feat = this.sector.toFeat();
                const mbc = this.marker.getLngLat();
                feat.geometry.coordinates = [mbc.lng, mbc.lat];
                this.$emit('marker-moved', feat);
            });
        }

    }
}
</script>

map-utils.js

const anchor = 'center';
const draggable = false;
const coords = sector.geometry.coordinates;
let offset = [0,0];
const marker = new mapbox.Marker({ 
        anchor, 
        offset, 
        draggable 
    }).setLngLat(coords);
return marker;
tommed commented 4 years ago

Here's a video of the issue

tommed commented 4 years ago

Is anyone monitoring these bugs please?

transfluxus commented 4 years ago

I had a bug of messing up my map from popups and maybe it might help here as well. even tho I have no clue why. Its more of an interplay between vue and mapbox... anyway

try instead of this

            this.marker = utils
                .sectorMarker(s, this.mapbox)
                .setPopup(this.popup);
                .addTo(this.map);

this:

            this.marker = utils
                .sectorMarker(s, this.mapbox)
                .setPopup(this.popup);

            this.marker.addTo(this.map);

weird, but fixed it for me

tommed commented 4 years ago

Looking at the code, I don't think there's a reason why this should fix anything - perhaps it just stopped breaking for you or something else was changed? I found my issue was with the mapbox vue component. You use this.$control = ... to set the control and it adds it to the map under-the-hood. I replaced this code with my own and it started working again :-/