vue+mapbox学习(三)–添加一个可移动的点
首先准备一个点的geojson数据,存为Point.json(这里我将坐标放在了苏科大石湖校区):
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
120.57034514036286,
31.251418083207284
]
}
}
]
}
然后,通过axios读取(不是必须这么做,简单的json完全可以在函数体里写出来)。和上篇一样,利用addSource()方法,给点数据一个id,例如“ point ”,“告诉”mapbox可以根据这个id去查找使用;再利用addLayer()方法添加到地图上,这次的type是“circle”并通过paint设置样式。到这为止,又是一次简单的地理数据添加。
this.map.addSource("point", {
type: "geojson",
data: this.geojson
});
this.map.addLayer({
id: "point",
type: "circle",
source: "point",
paint: {
"circle-radius": 10,
"circle-color": "#3887be"
}
});
下面需要利用mapbox所提供的方法,对这个点进行移动。“mouseenter”事件是mapbox提供的当鼠标移动到指定图层的响应事件,这里是在addLayer()中注册的“point”即设置好的点图层;setPaintProperty()方法设置的是鼠标移动到该图层后,所显示的样式:
let _this = this;
this.map.on("mouseenter", "point", () => {
_this.map.setPaintProperty("point", "circle-color", "#3bb2d0");
_this.canvas.style.cursor = "move";
});
同样的还有“mouseleave”、“mousedown”事件:
this.map.on("mousedown", "point", (e: any) => {
e.preventDefault();
_this.canvas.style.cursor = "grab";
_this.map.on("mousemove", _this.onMove);
_this.map.once("mouseup", _this.onUp);
});
this.map.on("touchstart", "point", (e: any) => {
if (e.points.length !== 1) return;
e.preventDefault();
_this.map.on("touchmove", _this.onMove);
_this.map.once("touchend", _this.onUp);
});
注:“_this”是通过“劫持”全局this从而可以指向需要的函数。贴上这次的完整代码:
<template>
<div id="first-map">
<pre id="coordinates" class="coordinates"></pre>
</div>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import axios from "axios";
// @ts-ignore
import mapboxgl from "mapbox-gl";
@Component({})
export default class Map extends Vue {
private map: any;
private coordinates: any;
private canvas: any;
private geojson: any;
private initMap() {
mapboxgl.accessToken =
"pk.eyJ1IjoiaGFqY2tlciIsImEiOiJjazJ5ZWhleTgwMW9pM2RxaTRjOXFkZW9zIn0.Z1RgDBBWGm4BjuvbPtqw0w";
this.map = new mapboxgl.Map({
container: "first-map",
style: "mapbox://styles/hajcker/ck382fdsu0nia1cocmp6tf3vm",
center: [120.57034514036286, 31.251418083207284],
zoom: 15
});
axios.get("../data/Taihu.json").then(res => {
this.map.on("load", () => {
this.map.addLayer({
id: "taihu",
type: "fill",
source: {
type: "geojson",
data: res.data
},
layout: {},
paint: {
"fill-color": "#088",
"fill-opacity": 0.8
}
});
});
});
this.canvas = this.map.getCanvasContainer();
this.coordinates = document.getElementById("coordinates");
axios.get("../data/Point.json").then(res => {
this.geojson = res.data;
this.map.on("load", () => {
this.map.addSource("point", {
type: "geojson",
data: this.geojson
});
this.map.addLayer({
id: "point",
type: "circle",
source: "point",
paint: {
"circle-radius": 10,
"circle-color": "#3887be"
}
});
let _this = this;
this.map.on("mouseenter", "point", () => {
_this.map.setPaintProperty("point", "circle-color", "#3bb2d0");
_this.canvas.style.cursor = "move";
});
this.map.on("mouseleave", "point", () => {
_this.map.setPaintProperty("point", "circle-color", "#3887be");
_this.canvas.style.cursor = "";
});
this.map.on("mousedown", "point", (e: any) => {
e.preventDefault();
_this.canvas.style.cursor = "grab";
_this.map.on("mousemove", _this.onMove);
_this.map.once("mouseup", _this.onUp);
});
this.map.on("touchstart", "point", (e: any) => {
if (e.points.length !== 1) return;
e.preventDefault();
_this.map.on("touchmove", _this.onMove);
_this.map.once("touchend", _this.onUp);
});
});
});
}
private onMove(e: any) {
const coords = e.lngLat;
this.canvas.style.cursor = "grabbing";
this.geojson.features[0].geometry.coordinates = [coords.lng, coords.lat];
this.map.getSource("point").setData(this.geojson);
}
private onUp(e: any) {
const coords = e.lngLat;
this.coordinates.style.display = "block";
this.coordinates.innerHTML =
"Longitude: " + coords.lng + "<br />Latitude: " + coords.lat;
this.canvas.style.cursor = "";
this.map.off("mousemove", this.onMove);
this.map.off("touchmove", this.onMove);
}
private mounted() {
this.initMap();
}
}
</script>
<style scoped lang="scss">
#first-map {
height: 800px;
width: 800px;
margin: auto;
position: relative;
.coordinates {
background: rgba(0, 0, 0, 0.5);
color: #fff;
position: absolute;
bottom: 40px;
left: 10px;
padding: 5px 10px;
margin: 0;
font-size: 11px;
line-height: 18px;
border-radius: 3px;
display: none;
z-index: 1;
}
}
</style>
附上点位移动前后的图片: