Mapbox GL JS实现移动端H5实时多边形(涂鸦)绘制

关于使用MapBox GL进行图形绘制,很多人都在使用mapbox-gl-draw。但是它只是封装了一些简单的点、线、面的绘制功能。最近的一个项目提出了要求在手机上用手指拖动实现多边形涂鸦绘制,要求实时记录点。开始一直使用mapbox-gl-draw来做,但是始终无法实现手指拖动绘制的功能。最后,通过监听touch事件,实时改变source实现了这个效果。效果如下图:

代码如下:

注意,这里使用的监听事件,仅适合移动端使用,或者将Chrome调成移动端模式

<template>
  <div style="width: 100%; height: 100%; overflow:hidden">
    <div
      id="map"
      style="width: 100%; height: 100vh;position: absolute;top: 0;left: 0; z-index: 1;"
    ></div>
  </div>
</template>

<script>

import mapboxgl from "mapbox-gl";

export default {
  name: "HelloWorld",
  data() {
    return {
      map: null,
      coordinates:[]
    };
  },

  async mounted() {
      this.initMap();
  },
  methods: {
    //取消涂鸦
    cancleClick() {
      this.removeDrawLayer();
      this.map.dragPan.enable();
      this.map.off('touchstart', this.touchstart);
      this.map.off('touchmove', this.touchmove);
      this.map.off('touchend', this.touchend);
      this.coordinates=[];
    },

    touchstart(e){
      this.coordinates=[];
      console.log("拖动结束")
      console.log(e)
      this.addDrawLayer();
    },
    touchmove(e){
      this.coordinates.push([e.lngLat.lng,e.lngLat.lat])
      this.updateDrawLayer();
    },
    touchend(e){
      this.coordinates.push(this.coordinates[0])
      this.updateDrawLayer();
    },


    initMap() {
      mapboxgl.accessToken =
        'pk.eyJ1IjoiaGFtYnVnZXJkZXZlbG9wIiwiYSI6ImNqNXJtZjF4ZzB3em4yd21pZmVqbHlleDAifQ.I9eqVjtotz7jaU7XcJm9pQ';
      let map = new mapboxgl.Map({
        container: "map",
        style: "mapbox://styles/mapbox/streets-v11",
        maxZoom: 17.99,
        zoom: 14,
        center: [111.929173, 32.67442],
        dragRotate: false,
        pitchWithRotate: false,
        touchZoomRotate: true,
        refreshExpiredTiles: true,
      });
      this.map = map;
      //解决canvas渲染不正确
      map.on("styledata", function() {
        map.resize();
      });
      map.on("load", e => {
        // //禁止拖拽地图
        this.map.dragPan.disable();
        // //禁止通过捏合屏幕进行缩放
        this.map.touchZoomRotate.disable();
        // //禁止双击缩放
        this.map.doubleClickZoom.disable();
        this.coordinates=[];
        this.map.on('touchstart', this.touchstart);
        this.map.on('touchmove', this.touchmove);
        this.map.on('touchend', this.touchend);

      });
    },



    /**
     * 移除绘制图层
     */
    removeDrawLayer(){
      if(this.map.getLayer("draw")){
        this.map.removeLayer("draw")
        this.map.removeLayer("draw_line")
      }
      if(this.map.getSource("draw")){
        this.map.removeSource("draw")
      }

    },
    updateDrawLayer(){
      this.map.getSource('draw').setData({
        "type": "FeatureCollection",
        "features": [{
          "type": "Feature",
          "properties": { },
          "geometry": {
            "type": "Polygon",
            "coordinates": [this.coordinates]
          }
        }]
      });
    },

    /**
     * 添加绘制图层
     */
    addDrawLayer(){
      if(this.map.getLayer("draw")){
        return ;
      }
      let geoJosn={
        "type": "FeatureCollection",
        "features": [
          {
            "type": "Feature",
            "properties": {},
            "geometry": {
              "type": "Polygon",
              "coordinates": [
                [
                  [
                    92.98828125,
                    58.90464570302001
                  ],
                  [
                    122.16796875,
                    56.46249048388979
                  ],
                  [
                    133.06640625,
                    66.58321725728175
                  ],
                  [
                    117.42187500000001,
                    69.96043926902489
                  ]
                ]
              ]
            }
          }
        ]
      }
      this.map.addSource("draw", {
        type: "geojson",
        data: geoJosn});
      this.map.addLayer({
        id: "draw",
        type: "fill",
        source: "draw",
        layout: {},
        paint: {
          "fill-color": "#F00",
          "fill-opacity":0.3
        }
      });
      this.map.addLayer({
        id: "draw_line",
        type: "line",
        source: "draw",
        layout: {},
        paint: {
          "line-color": "#F00",
          "line-width": 5
        }
      });
    }
  }
};
</script>

代码可能缺失vue中引入mapbox的东西,自己想办法实现吧

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GIS开发者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值