Bootstrap

leaflet使用draw插件测量距离和面积

1.安装插件

npm install --save leaflet-draw

2.采用import形式,引入这个插件

import "leaflet-draw";
import "leaflet-draw/dist/leaflet.draw.css";

3.初始化使用插件

//添加画图的提示信息
   L.drawLocal.draw.handlers.polyline = {
      tooltip: {
        start: "点击地图开始画线",
        cont: "继续选择",
        end: "双击完成绘制"
      }
    };
    L.drawLocal.draw.handlers.polygon = {
      tooltip: {
        start: "点击地图开始绘制多边形",
        cont: "继续选择",
        end: "点击第一个顶点完成绘制"
      }
    };

4.执行方法

		/**
         * 绘制多边形
         */
        drawPolygon() {
            let map = this.map;
            this.polygon = new L.Draw.Polygon(map, {
                shapeOptions: {
                weight: 1,
                color: "#ff0000",
                opacity: 0.8,
                fillColor: "#ff0000"
                }
            });
            this.polygon.enable();
        },
        /**
         * 绘制线段
         */
        drawPolyline() {
            let map = this.map;
            this.polyline = new L.Draw.Polyline(map, {
                shapeOptions: {
                weight: 1,
                color: "#ff0000",
                opacity: 0.8
                }
            });
            this.polyline.enable();
        },
        measureDistance() {
            // 距离
            this.isDrawLine = true;
            this.drawPolyline();
        },
        measureArea() {
            // 面
            this.isDrawPolygon = true;
            this.drawPolygon();
        },

5.监听函数

 getData(){
        this.drawGroupPolyline = L.featureGroup().addTo(this.map);
        this.drawGroupPolygon = L.featureGroup().addTo(this.map);
        //画图创建事件
      this.map.on(L.Draw.Event.CREATED, event => {
            const { layer, layerType } = event;
            if (layerType === "polygon") {
              //layer.getLatLngs()得到的多边形的经纬度集合,多边形得到的是一个二维数组,这里要取里面的数组,一定要注意
                let latlng = layer.getLatLngs()[0];
                //一个自定义的计算面积的函数
                let area = this.formatArea(latlng)+'';
                this.addMeasureMarker(area, [latlng[latlng.length - 1].lat, latlng[latlng.length - 1].lng], this.map); //把画图之后计算的结果添加到地图上
                this.drawGroupPolygon.addLayer(layer);

            } else if (layerType === "polyline") {
            //polyline得到的是一个一维数组,直接使用
              let latlng = layer.getLatLngs();
              //一个自定义的计算长度的函数
              let distance = this.formatLength(latlng) + '';
              this.addMeasureMarker(distance, [latlng[0].lat, latlng[0].lng],this.map);
              this.drawGroupPolyline.addLayer(layer);
            }
            // drawGroup,groupLayer,把画图的图层添加到图层组方便管理
            // this.drawGroup.addLayer(layer);
            
          });
          // 结束绘制监听
          this.map.on(L.Draw.Event.DRAWSTOP, function() {
            console.log('结束绘制')

          });
           //添加画图的提示信息
           L.drawLocal.draw.handlers.polyline = {
                tooltip: {
                    start: "点击地图开始画线",
                    cont: "继续选择",
                    end: "双击完成绘制"
                }
            };
            L.drawLocal.draw.handlers.polygon = {
                tooltip: {
                    start: "点击地图开始绘制多边形",
                    cont: "继续选择",
                    end: "点击第一个顶点完成绘制"
                }
            };
      },
      addMeasureMarker(text, latlng, groupLayer) {
            var myIcon = L.divIcon({
                html: text,
                className: 'my-div-icon',
                iconSize: [80, 26]
            });
            L.marker(latlng, {
                icon: myIcon
            }).addTo(groupLayer);
        },

6.计算面积和长度 L.GeometryUtil.geodesicArea,L.latLng().distanceTo()

// 获取面积
        formatArea(polygon) {
            //L.GeometryUtil.geodesicArea(),返回number类型的数据,单位是平方米,这里做了一下转化
            var seeArea = L.GeometryUtil.geodesicArea(polygon);
            let area = (seeArea.toFixed(0)) + "㎡";
            if (seeArea > 10e5) {
                area = ((seeArea / 10e5).toFixed(2)) + "k㎡";
            }
            console.log(area)
            return area;
        },

        // 获取长度
        formatLength(line) {
            let dis = 0;
            for (let i = 0; i < line.length - 1; i++) {
                let start = line[i];
                let end = line[i + 1];
                dis += L.latLng([start.lat, start.lng]).distanceTo([end.lat, end.lng]); //计算两个点之间的距离,并累加
            }
            //结果得到的也是number类型,单位是 米
            if (dis < 1000) {
                return dis.toFixed(2) + "m";
            }
            return (dis / 10e2).toFixed(2) + "km";
        },

7.清除线段和面积

  clearMeasureDistance() {
            // 距离
            this.isDrawLine = false;
            if(this.polyline){
                this.polyline.disable();
            }
            let obj = document.getElementsByClassName('my-div-icon');
            for(let i=0;i<obj.length;i++){
                obj[i].innerHTML = ''
            }
            if(this.drawGroupPolyline){
                this.drawGroupPolyline.clearLayers()
            }
        },
        clearMeasureArea() {
            // 面
            this.isDrawPolygon = false;
            if(this.polygon){
                this.polygon.disable();
            }
            let obj = document.getElementsByClassName('my-div-icon');
            for(let i=0;i<obj.length;i++){
                obj[i].innerHTML = ''
            }
            if(this.drawGroupPolygon){
                this.drawGroupPolygon.clearLayers()
            }
        },

8.转中文
新建leaflet.draw-cn.js 覆盖英文提示,并引入路径

  import "../../../../public/js/leaflet.draw-cn.js"

js内容如下:

L.drawLocal = {
	draw: {
		toolbar: {
			// #TODO: this should be reorganized where actions are nested in actions
			// ex: actions.undo  or actions.cancel
			actions: {
				title: '取消绘图',//'Cancel drawing',
				text: '',//'Cancel'
			},
			finish: {
				title: '完成绘图',//'Finish drawing',
				text: 'Finish'
			},
			undo: {
				title: '删除最后绘制的点',//'Delete last point drawn',
				text: '',//'Delete last point'
			},
			buttons: {
				polyline: '绘制一个多段线',//'Draw a polyline',
				polygon: '绘制一个多边形',//'Draw a polygon',
				rectangle: '绘制一个矩形',//'Draw a rectangle',
				circle: '绘制一个圆',//'Draw a circle',
				marker: '绘制一个标记',//'Draw a marker',
				circlemarker: '绘制一个圆形标记',//'Draw a circlemarker'
			}
		},
		handlers: {
			circle: {
				tooltip: {
					start: '单击并拖动以绘制圆',//'Click and drag to draw circle.'
				},
				radius: 'Radius'
			},
			circlemarker: {
				tooltip: {
					start: '单击“地图”以放置圆标记',//'Click map to place circle marker.'
				}
			},
			marker: {
				tooltip: {
					start: '单击“地图”以放置标记',//'Click map to place marker.'
				}
			},
			polygon: {
				tooltip: {
					start: '单击开始绘制形状',//'Click to start drawing shape.',
					cont: '单击继续绘制形状',//'Click to continue drawing shape.',
					end: '单击第一个点关闭此形状',//'Click first point to close this shape.'
				}
			},
			polyline: {
				error: '<strong>错误:</strong>形状边缘不能交叉!',//'<strong>Error:</strong> shape edges cannot cross!',
				tooltip: {
					start: '单击开始绘制线',//'Click to start drawing line.',
					cont: '单击以继续绘制线',//'Click to continue drawing line.',
					end: '单击“最后一点”以结束线',//'Click last point to finish line.'
				}
			},
			rectangle: {
				tooltip: {
					start: '单击并拖动以绘制矩形',//'Click and drag to draw rectangle.'
				}
			},
			simpleshape: {
				tooltip: {
					end: '释放鼠标完成绘图',//'Release mouse to finish drawing.'
				}
			}
		}
	},
	edit: {
		toolbar: {
			actions: {
				save: {
					title: '保存更改',//'Save changes',
					text: '保存',//'Save'
				},
				cancel: {
					title: '取消编辑,放弃所有更改',//'Cancel editing, discards all changes',
					text: '取消',//'Cancel'
				},
				clearAll: {
					title: '清除所有图层',//'Clear all layers',
					text: '清除所有',//'Clear All'
				}
			},
			buttons: {
				edit: '编辑图层',//'Edit layers',
				editDisabled: '无可编辑的图层',//'No layers to edit',
				remove: '删除图层',//'Delete layers',
				removeDisabled: '无可删除的图层',//'No layers to delete'
			}
		},
		handlers: {
			edit: {
				tooltip: {
					text: '拖动控制柄或标记以编辑要素',//'Drag handles or markers to edit features.',
					subtext: '单击“取消”撤消更改',//'Click cancel to undo changes.'
				}
			},
			remove: {
				tooltip: {
					text: '单击要删除的要素',//'Click on a feature to remove.'
				}
			}
		}
	}
};

全部代码如下:

<template>
	<div id="map">
        <div class="leftbg" style="z-index: 9999;">
            <div v-if="isDrawLine" class="lengthbg_select" @click="clearMeasureDistance"></div>
            <div v-else  class="lengthbg" @click="measureDistance"></div>
            <div v-if="isDrawPolygon" class="areabg_select"  @click="clearMeasureArea"></div>
            <div v-else class="areabg"  @click="measureArea"></div>
         </div>
    </div>
</template>

<script>
    import redMarker from "../../../assets/image/red-marker.png";
    import "leaflet-draw";
    import "leaflet-draw/dist/leaflet.draw.css";
    import "../../../../public/js/leaflet.draw-cn.js"
	export default {
		name: 'workSpace',
        components: {},
		data() {
			return {
                map:null,
                marker:'',
                lat:'',
                lng:'',
                polyline:null,
                polygon:null,
                drawGroupPolyline:null,
                drawGroupPolygon:null,
                isDrawLine:false,
                isDrawPolygon:false,
			};
		},
          //初始化方法
		watch: {
    	'$route' () {
            //  
    		}
		},
		created() { 
            this.$nextTick(()=>{
                if(!this.map){
                    this.getMap();
                }
            })
		},
		methods: {
            getMap(){
            this.map = L.map("map", {
                center: [30.551116,119.975995],
                // zoom: 16,
                zoomControl: false, //禁用 + - 按钮
                // doubleClickZoom: false, // 禁用双击放大
                attributionControl: false, // 移除右下角leaflet标识
                crs: L.CRS.EPSG4326,
            }).setView([30.551116,119.975995], 14);
            //添加电子地图影像
            var vector_map = L.tileLayer(
                "http://t1.tianditu.com/img_c/wmts?layer=img&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&tk=d4782516c98542ebc0bdc11ec86b68ca",
                {
                    maxZoom: 17,
                    tileSize: 256,
                    zoomOffset: 1,
                    minZoom: 3,
                }
            ).addTo(this.map);
            //添加注记
            var vector_note = L.tileLayer(
                "http://t1.tianditu.com/cva_c/wmts?layer=cva&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&tk=d4782516c98542ebc0bdc11ec86b68ca",
                {
                maxZoom: 17,
                tileSize: 256,
                zoomOffset: 1,
                zIndex: 5,
                minZoom: 14,
                }
            ).addTo(this.map);
            var matrixIds = [];
            for (var i = 0; i < 22; ++i) {
                matrixIds[i] = {
                    identifier: "" + i,
                    topLeftCorner: new L.LatLng(90, -180)
                };
            }
            this.map.pm.setLang('zh');  //设置语言  en, de, it, ru, ro, es, fr, pt_br, zh , nl
            var that = this
            var redIcon = L.icon({
                    iconUrl:redMarker,//markerIcon  redMarker
                    iconSize: [35, 35],
                    iconAnchor: [17.5, 17.5]
                })
            if(that.lng&&that.lat){
                console.log("打印点的经纬度")
                 that.marker = L.marker([that.lat, that.lng],{
                    icon:redIcon,
                    riseOnHover:true
                    }).addTo(that.map) 
            }
            
                // // 点击地图进行打点
                // that.map.on('click', function(e) {
                //     // var content = '你点击了这个点:<br>';
                //     // content += e.latlng.toString();
                //     // console.log(content);
                //     // mypop.setLatLng(e.latlng).setContent(content).openOn(that.map);
                //     /** 点 */ 
                //     /**在这里进行处理数据,将在地图上打点的经纬度坐标通过接口上传服务器 */
                //     that.lat = e.latlng.lat;
                //     that.lng = e.latlng.lng;
                //     if(that.marker){
                //         //移除上次的marker点
                //         that.map.removeLayer(that.marker)
                //     }
                //     that.marker = L.marker([e.latlng.lat, e.latlng.lng],{
                //         icon:redIcon,
                //         riseOnHover:true
                //         }).addTo(that.map) 
                // });
                this.getData();
            
            },
    getData(){
        this.drawGroupPolyline = L.featureGroup().addTo(this.map);
        this.drawGroupPolygon = L.featureGroup().addTo(this.map);
        //画图创建事件
      this.map.on(L.Draw.Event.CREATED, event => {
            const { layer, layerType } = event;
            if (layerType === "polygon") {
              //layer.getLatLngs()得到的多边形的经纬度集合,多边形得到的是一个二维数组,这里要取里面的数组,一定要注意
                let latlng = layer.getLatLngs()[0];
                //一个自定义的计算面积的函数
                let area = this.formatArea(latlng)+'';
                this.addMeasureMarker(area, [latlng[latlng.length - 1].lat, latlng[latlng.length - 1].lng], this.map); //把画图之后计算的结果添加到地图上
                this.drawGroupPolygon.addLayer(layer);

            } else if (layerType === "polyline") {
            //polyline得到的是一个一维数组,直接使用
              let latlng = layer.getLatLngs();
              //一个自定义的计算长度的函数
              let distance = this.formatLength(latlng) + '';
              this.addMeasureMarker(distance, [latlng[0].lat, latlng[0].lng],this.map);
              this.drawGroupPolyline.addLayer(layer);
            }
            // drawGroup,groupLayer,把画图的图层添加到图层组方便管理
            // this.drawGroup.addLayer(layer);
            
          });
          // 结束绘制监听
          this.map.on(L.Draw.Event.DRAWSTOP, function() {
            console.log('结束绘制')

          });
           //添加画图的提示信息
           L.drawLocal.draw.handlers.polyline = {
                tooltip: {
                    start: "点击地图开始画线",
                    cont: "继续选择",
                    end: "双击完成绘制"
                }
            };
            L.drawLocal.draw.handlers.polygon = {
                tooltip: {
                    start: "点击地图开始绘制多边形",
                    cont: "继续选择",
                    end: "点击第一个顶点完成绘制"
                }
            };
      },
      addMeasureMarker(text, latlng, groupLayer) {
            var myIcon = L.divIcon({
                html: text,
                className: 'my-div-icon',
                iconSize: [80, 26]
            });
            L.marker(latlng, {
                icon: myIcon
            }).addTo(groupLayer);
        },
      // 获取面积
        formatArea(polygon) {
            //L.GeometryUtil.geodesicArea(),返回number类型的数据,单位是平方米,这里做了一下转化
            var seeArea = L.GeometryUtil.geodesicArea(polygon);
            let area = (seeArea.toFixed(0)) + "㎡";
            if (seeArea > 10e5) {
                area = ((seeArea / 10e5).toFixed(2)) + "k㎡";
            }
            console.log(area)
            return area;
        },

        // 获取长度
        formatLength(line) {
            let dis = 0;
            for (let i = 0; i < line.length - 1; i++) {
                let start = line[i];
                let end = line[i + 1];
                dis += L.latLng([start.lat, start.lng]).distanceTo([end.lat, end.lng]); //计算两个点之间的距离,并累加
            }
            //结果得到的也是number类型,单位是 米
            if (dis < 1000) {
                return dis.toFixed(2) + "m";
            }
            return (dis / 10e2).toFixed(2) + "km";
        },
      /**
         * 绘制多边形
         */
        drawPolygon() {
            let map = this.map;
            this.polygon = new L.Draw.Polygon(map, {
                shapeOptions: {
                weight: 1,
                color: "#ff0000",
                opacity: 0.8,
                fillColor: "#ff0000"
                }
            });
            this.polygon.enable();
        },
        /**
         * 绘制线段
         */
        drawPolyline() {
            let map = this.map;
            this.polyline = new L.Draw.Polyline(map, {
                shapeOptions: {
                weight: 1,
                color: "#ff0000",
                opacity: 0.8
                }
            });
            this.polyline.enable();
        },
        measureDistance() {
            // 距离
            this.isDrawLine = true;
            this.drawPolyline();
        },
        measureArea() {
            // 面
            this.isDrawPolygon = true;
            this.drawPolygon();
        },
        clearMeasureDistance() {
            // 距离
            this.isDrawLine = false;
            if(this.polyline){
                this.polyline.disable();
            }
            let obj = document.getElementsByClassName('my-div-icon');
            for(let i=0;i<obj.length;i++){
                obj[i].innerHTML = ''
            }
            if(this.drawGroupPolyline){
                this.drawGroupPolyline.clearLayers()
            }
        },
        clearMeasureArea() {
            // 面
            this.isDrawPolygon = false;
            if(this.polygon){
                this.polygon.disable();
            }
            let obj = document.getElementsByClassName('my-div-icon');
            for(let i=0;i<obj.length;i++){
                obj[i].innerHTML = ''
            }
            if(this.drawGroupPolygon){
                this.drawGroupPolygon.clearLayers()
            }
        },
		}
	};
</script>
<style>
    .my-div-icon {
        font-size:16px;
        color:#fff;
    }
</style>
<style scoped>
	.home{
        width: 100%;
        height: 100%;
        position: absolute;
      
    }
    #map {
        top: 0px;
        width: 100%;
        bottom: 0px;
        position: absolute;
    }
	

    .leftbg {
      width: 1rem;
      height: 2rem;
      bottom: 0rem;
      right: 4.6rem;
      position: absolute;
    }

    .lengthbg{
        width: 0.67rem;
        height: 0.67rem;
        background: url(../../../assets/image/measure_length.png) no-repeat;
        background-size: 100% 100%;
        margin-bottom: 0.19rem;
    }
    .areabg{
        width: 0.67rem;
        height: 0.67rem;
        background: url(../../../assets/image/measure_area.png) no-repeat;
        background-size: 100% 100%;
    }
    .lengthbg_select{
        width: 0.67rem;
        height: 0.67rem;
        background: url(../../../assets/image/measure_length_select.png) no-repeat;
        background-size: 100% 100%;
        margin-bottom: 0.19rem;
    }
    .areabg_select{
        width: 0.67rem;
        height: 0.67rem;
        background: url(../../../assets/image/measure_area_select.png) no-repeat;
        background-size: 100% 100%;
    }
</style>

;