首先准备一个点的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-ignoreimport 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>附上点位移动前后的图片: