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>