【Leaflet】地图绘制/编辑多边形

4 篇文章 0 订阅
3 篇文章 0 订阅
 <div id="grid_map" style="width: 100%; height: 100%;"></div>

初始化地图:

initLeaflet (level) {
      if (this.map) {
        this.map.remove()
      }
      this.map = this.initLeafletMap('grid_map')
      //添加左侧绘制控件
      this.map.pm.addControls({
        position: 'topleft',
        drawMarker: false, // 绘制标记
        drawCircle: false, // 绘制圆形
        drawPolyline: false, // 绘制折线
        drawRectangle: false, // 绘制矩形
        drawPolygon: true, // only五级网格绘制
        drawCircleMarker: false, // 绘制圆形标记
        removalMode: false, // 清除图层
        cutPolygon: false, // 删除图层里的部分内容
        editMode: false, // 编辑多边形
        dragMode: false // 拖动多边形
      });

      let that = this

      //绘制开始事件
      this.map.on('pm:drawstart', e => {
        if (e.shape === 'Marker') {
          document.getElementById("grid_map").style.cursor = "none";
        } else {
          document.getElementById("grid_map").style.cursor = "grab";
        }
      });

      //绘制模式关闭
      this.map.on('pm:drawend', () => {
        document.getElementById("grid_map").style.cursor = "grab";
      });

      //绘制完成事件
      this.map.on('pm:create', e => {
        let shape = e.shape;
        //多边形
        if ('Polygon' === shape || 'Rectangle' === shape) {
          // 处理绘制完成的逻辑
        }
      });

      //移除事件
      this.map.on('pm:remove', () => {
        let layers = that.map.pm.getGeomanLayers()
        if (layers) {
          for (let i = 0; i < layers.length; i++) {
            //多边形
            if (layers[i].pm._shape === 'Polygon' || layers[i].pm._shape === 'Rectangle') {
              // 经纬度
             // layers[i]._latlngs[0]
            }
          }
        }
      })
      //地图缩放事件
      this.map.on('zoomend', () => {
        
      })

      // 双击事件
      this.map.addEventListener("dblclick", function () {
        
      })
      // 拖拽事件
      this.map.addEventListener("dragend", function(){
        
      })
      // 缩放事件
      this.map.addEventListener("zoomend", function(){
        
      })

      // 先清除all多边形
      this.clearAllPolygon(this.map)
    },
// 初始化map
initLeafletMap(id, zoom = 16) {
    let normalMap = window.L.tileLayer.chinaProvider('Baidu.Normal.Map', {
        maxZoom: 18,
        minZoom: 10
    });
    let normal = window.L.layerGroup([normalMap])
    let map = window.L.map(id, {
        crs: window.L.CRS.Baidu,
        center: [36.717672, 119.160414],
        zoom: zoom,
        layers: [normal],
        zoomControl: true,
        trackResize: true
    });
    //初始化绘制插件
    window.L.PM.initialize();
    //中文
    map.pm.setLang('zh')

    // 比例尺
    window.L.control.scale({maxWidth:200,metric:true,imperial:false}).addTo(map)
    return map
},

// 清除所有多边形
clearAllPolygon (map) {
    let layers = map.pm.getGeomanLayers()
    if (layers) {
        layers.forEach(res => {
            map.removeLayer(res)
        })
    }
},

绘制多边形

polygonToMap (list) {
      // 已选中图标
      let PickedIcon = window.L.Icon.extend({
        options: {
          iconUrl: require('@/assets/map/ic_map_selected.png'),
          iconSize: [24, 24]
        }
      })
      // 可编辑图标
      let EditIcon = window.L.Icon.extend({
        options: {
          iconUrl: require('@/assets/map/ic_map_edit.png'),
          iconSize: [24, 24]
        }
      })
      // 清除all marker
      for (let i = 0; i < this.selectMarkers.length; i++) {
        this.map.removeLayer(this.selectMarkers[i].marker)
      }
      this.selectMarkers = []
      list.forEach(res => {
        let latlngs = []
        let rangePoints = res.rangePoints
        let options = {
          color: '#5b8ff9', // res.color
          fillColor: '#5b8ff9', // res.color
          fillOpacity: 0.1,
          data: res
        }
        rangePoints.forEach(item => {
          latlngs.push([item.lat, item.lng])
        })
        // 绘制多边形
        let polygonLayer = window.L.polygon(latlngs, options).addTo(this.map)
        // 点击事件
        this.polygonInit(polygonLayer)
        // 绘制覆盖点
        let isPicked = res.isPicked
        let isEdit = res.isEdit
        if (isPicked === 1 || isEdit === 1) { // 已选中/可编辑
          new window.L.marker([res.latitude, res.longitude], {
            icon: res.isEdit ? new EditIcon() : new PickedIcon(),
            data: res
          }).addTo(this.map).on('click', () => {
            if (isEdit === 1) {
              // 编辑
              this.currentGridData = res
              // 禁用全局编辑按钮
              this.map.pm.disableGlobalEditMode()
                this.editMapLayer(polygonLayer)
            }
          })
        }
        // map 改变后,重新设置map选中的marker
        if (this.gridData.gridIdList.indexOf(res.id) > -1) {
          let marker = new window.L.marker([res.latitude, res.longitude], {
            icon: new PickedIcon()
          }).addTo(this.map).on('click', () => {
            if (this.gridData.gridLevel < 5) { // 五级以下可选
              let index = this.gridData.gridIdList.indexOf(res.id)
              if (index > -1) {
                this.gridData.gridIdList.splice(index, 1)
                this.gridDataList.splice(index, 1)
                this.selectMarkers.splice(index, 1)
              }
              this.map.removeLayer(marker)
            }
          })
          this.selectMarkers.push({
              marker: marker,
              id: res.id
            })
        }
        // 绘制文字
        let iconLabel = window.L.divIcon({
          html: res.gridName,
          className: 'my-grid-configure-icon',
          iconSize: 30,
          data: res
        })
        new window.L.marker([res.latitude, res.longitude], {
          icon: iconLabel
        }).addTo(this.map).on('click', () => {
          if (res.isEdit === 1) {
            // 可编辑
            this.currentGridData = res
            // 禁用全局编辑按钮
            this.map.pm.disableGlobalEditMode()
            this.editMapLayer(polygonLayer)
          }
        })
      })
    },

// 多边形需要执行的操作
polygonInit(polygonLayer) {
      //点击事件
      polygonLayer.on('click', e => {
        if (e.sourceTarget.options.data && e.sourceTarget.options.data.isEdit === 1) {
          // 可编辑
          this.currentGridData = e.sourceTarget.options.data
          // 禁用全局编辑按钮
          this.map.pm.disableGlobalEditMode()
          this.editMapLayer(polygonLayer)
          return
        }
       
        if (e.sourceTarget.options.data) {
          this.polygonSelectHandler(e.sourceTarget.options.data)
        }
      });
    },

编辑多边形

editMapLayer (layer) {
      layer.pm.enable({
        allowSelfIntersection: true,
        preventMarkerRemoval: false,  // 禁止右键删除点
      })
      let that = this
      // 监听编辑事件
      layer.on('pm:edit', e => {
        // 拖动后的坐标
        that.currentGridData.rangePoints = e.target._latlngs[0]
      })
      layer.on('pm:vertexadded', e =>{
        // 添加顶点
        console.log(e, '添加顶点')
      })
    },

 

Leaflet是一个非常流行的JavaScript库,它可以用来创建交互式的Web地图。要绘制多边形,需要使用Leaflet的绘图插件——Leaflet.draw。 下面是一个简单的示例: 1. 引入LeafletLeaflet.draw库 ```html <!-- Leaflet --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet@1.7.1/dist/leaflet.css" /> <script src="https://cdn.jsdelivr.net/npm/leaflet@1.7.1/dist/leaflet.js"></script> <!-- Leaflet.draw --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js"></script> ``` 2. 创建地图容器 ```html <div id="map" style="width: 100%; height: 400px;"></div> ``` ```javascript // 初始化地图 var map = L.map('map').setView([51.505, -0.09], 13); // 添加OSM地图图层 L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: 'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors', maxZoom: 18 }).addTo(map); ``` 3. 添加绘图工具 ```javascript // 添加绘图工具 var drawControl = new L.Control.Draw({ draw: { polygon: true, // 允许绘制多边形 polyline: false, rectangle: false, circle: false, marker: false, circlemarker: false }, edit: { featureGroup: drawnItems // 将绘制的图形添加到drawnItems图层 } }).addTo(map); ``` 4. 处理绘制完成事件 ```javascript // 处理绘制完成事件 map.on('draw:created', function(e) { var layer = e.layer; drawnItems.addLayer(layer); }); ``` 完整代码如下: ```html <!DOCTYPE html> <html> <head> <title>Leaflet Draw Demo</title> <!-- Leaflet --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet@1.7.1/dist/leaflet.css" /> <script src="https://cdn.jsdelivr.net/npm/leaflet@1.7.1/dist/leaflet.js"></script> <!-- Leaflet.draw --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js"></script> </head> <body> <div id="map" style="width: 100%; height: 400px;"></div> <script> // 初始化地图 var map = L.map('map').setView([51.505, -0.09], 13); // 添加OSM地图图层 L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: 'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors', maxZoom: 18 }).addTo(map); // 添加绘图工具 var drawnItems = new L.FeatureGroup(); map.addLayer(drawnItems); var drawControl = new L.Control.Draw({ draw: { polygon: true, // 允许绘制多边形 polyline: false, rectangle: false, circle: false, marker: false, circlemarker: false }, edit: { featureGroup: drawnItems // 将绘制的图形添加到drawnItems图层 } }).addTo(map); // 处理绘制完成事件 map.on('draw:created', function(e) { var layer = e.layer; drawnItems.addLayer(layer); }); </script> </body> </html> ``` 运行代码,你可以在地图上用鼠标绘制多边形绘制完成后,多边形将会被添加到地图上。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值