vue+mapbox学习(3)--添加一个可移动的点

1,190 阅读2分钟
首先准备一个点的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>

附上点位移动前后的图片: