Я пытаюсь использовать Mapbox с Vue / Vuex / Typescript, чтобы выбрать местоположение пользователя и центрировать карту на нем, а также заставить карту следовать за пользователем в случае их перемещения.
Проблемы:
- Карта иногда фокусируется {long: 0, lat; 0}, в другое время в местоположение по умолчанию mapStyle.
- Карта не обновляется после получения userLocation из navigator.geolocation.
Вот моя карта. vue:
<template>
<MglMap
class="map"
:center="userLocation"
:zoom="zoom"
:accessToken="accessToken"
:mapStyle="mapStyle"
>
</MglMap>
</template>
<script lang="ts">
import Vue from "vue";
import {
MglMap,
} from "vue-mapbox";
import { mapState } from "vuex";
export default Vue.extend({
data() {
return {
accessToken:"ACCESS_TOKEN",
mapStyle: "MAP_STYLE"
};
},
components: {
MglMap,
},
computed: mapState({
userLocation: (state: any) => state.mapModule.userLocation,
zoom: (state: any) => state.mapModule.zoom
}),
beforeCreate() {
this.$store.dispatch("mapModule/fetchGeolocation");
}
});
</script>
<style lang="scss">
@import url("./_Map.scss");
</style>
Вот картаModule.ts:
import mapboxgl from "mapbox-gl";
const mapModule = {
namespaced: true,
state: {
zoom: 14,
gettingLocation: false,
userLocation: [0, 0],
errorString: ""
} as State,
getters: {},
mutations: {
SET_GETTING_LOCATION(state: State, payload: boolean) {
state.gettingLocation = payload;
},
SET_USER_LOCATION(state: State, payload: mapboxgl.LngLatLike) {
console.log(payload);
state.userLocation = payload;
},
SET_ERROR_STRING(state: State, payload: string) {
state.errorString = payload;
}
},
actions: {
fetchGeolocation({ commit }: any) {
if (!("geolocation" in navigator)) {
commit("SET_ERROR_STRING", "Geolocation is not available.");
return;
}
commit("SET_GETTING_LOCATION", true);
// get position
navigator.geolocation.getCurrentPosition(
pos => {
commit(
"SET_USER_LOCATION",
new mapboxgl.LngLat(pos.coords.longitude, pos.coords.latitude)
);
commit("SET_GETTING_LOCATION", false);
},
err => {
commit("SET_GETTING_LOCATION", false);
commit("SET_ERROR_STRING", err.message);
}
);
navigator.geolocation.watchPosition(
pos => {
commit(
"SET_USER_LOCATION",
new mapboxgl.LngLat(pos.coords.longitude, pos.coords.latitude)
);
commit("SET_GETTING_LOCATION", false);
},
err => {
commit("SET_GETTING_LOCATION", false);
commit("SET_ERROR_STRING", err.message);
}
);
}
}
};
interface State {
zoom: number;
gettingLocation: boolean;
userLocation: mapboxgl.LngLatLike;
errorString: string;
}
export default mapModule;