源代码地址:Leaflet: https://gitee.com/SunBear/Leaflet
效果如图:
vue中安装引入leaflet组件及相关插件:
npm i leaflet
npm i leaflet-draw
// vue中引入
import * as L from "leaflet";
import "leaflet/dist/leaflet.css";import "leaflet-draw";
import "leaflet-draw/dist/leaflet.draw.css";
完整html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="assets/css/map.css" rel="stylesheet">
<link href="assets/css/leaflet.css" rel="stylesheet">
<link href="assets/css/leaflet.draw.css" rel="stylesheet">
<title>leaflet插件</title>
<style>
.map-marker-draws2{
display: none;
}
.map-marker-draws {
width: 14px !important;
height: 14px !important;
margin-left: -7px !important;
margin-top: -7px !important;
background: #3592f1;
border: 2px solid #ffffff;
border-radius: 100%;
}
.map-measure-show-area {
color: #000;
background: #fff;
padding: 5px;
font-size: 12px;
opacity: 0.9;
width: max-content;
}
.map-measure-show-length {
color: #000;
background: #fff;
padding: 5px;
font-size: 12px;
opacity: 0.9;
width: max-content;
}
</style>
</head>
<body>
<div id="map"></div>
<div class="btns" style="text-align: center;margin-top: 20px;">
<button onclick="enableDraw('marker')">测点</button>
<button onclick="enableDraw('polygon')">测面</button>
<button onclick="enableDraw('polyline')">测距</button>
<button onclick="disableDraw()">取消绘制</button>
<button onclick="clearDraw()">清除</button>
</div>
<script src="assets/js/leaflet.js"></script>
<script src="assets/js/leaflet.draw.js"></script>
<script>
let map = L.map("map", {
zoom: 12,
maxZoom: 18,
center: [34.269701076858354, 108.94729614257814],
});
L.tileLayer(
"http://{s}.tile.osm.org/{z}/{x}/{y}.png"
).addTo(map);
let drawLayer = null
const layerGroup = new L.FeatureGroup().addTo(map);
// 监听绘制完成事件
map.on(L.Draw.Event.CREATED, (e) => {
const {
layer,
layerType
} = e;
disableDraw(); //取消绘制、绘制初始化
let markerLayer = null;
layerGroup.addLayer(layer);
if (layerType === "polygon") {
const latlng = layer.getLatLngs()[0];
const area = formatArea(latlng)
markerLayer = addDivIconMarker(
[latlng[0].lat, latlng[0].lng],
`<div class="map-measure-show-area">面积:${area}</div>`
);
} else if (layerType === "polyline") {
const latlng = layer.getLatLngs();
const distance = formatLength(latlng);
markerLayer = addDivIconMarker(
[latlng[0].lat, latlng[0].lng],
`<div class="map-measure-show-length">长度:${distance}</div>`
);
} else {
const latlng = layer._latlng
const icon = L.icon({
iconUrl: 'assets/img/marker_icon.png',
iconSize: [15,28],
});
markerLayer = L.marker([latlng.lat, latlng.lng], {
icon: icon
});
}
layerGroup.addLayer(markerLayer);
});
// 启动绘制
function enableDraw(type) {
if (drawLayer) return; //防止重复绘制
let config = {
drawLocal: {
marker: {
tooltip: {
start: "单击放置标记,按esc退出",
},
},
polyline: {
tooltip: {
start: "点击地图开始画线",
cont: "继续选择",
end: "双击完成绘制",
},
},
polygon: {
error: "<strong>错误:</strong>无法形成面 请重新绘制",
tooltip: {
start: "点击地图开始绘制多边形",
cont: "继续选择",
end: "双击或者点击第一个顶点完成绘制",
},
},
},
drawConfig: {
marker: {
icon: L.divIcon({
className: "map-marker-draws2",
}),
shapeOptions: {
color: "#3592f1",
},
},
polyline: {
icon: L.divIcon({
className: "map-marker-draws",
}),
shapeOptions: {
color: "#3592f1",
},
},
polygon: {
icon: L.divIcon({
className: "map-marker-draws",
}),
shapeOptions: {
color: "#3592f1",
},
},
},
};
if (type === "marker") {
L.drawLocal.draw.handlers.marker =
config.drawLocal.marker;
drawLayer = new L.Draw.Marker(
map,
config.drawConfig.marker
);
} else if (type === "polyline") {
L.drawLocal.draw.handlers.polyline =
config.drawLocal.polyline;
drawLayer = new L.Draw.Polyline(
map,
config.drawConfig.polyline
);
} else {
L.drawLocal.draw.handlers.polygon =
config.drawLocal.polygon;
drawLayer = new L.Draw.Polygon(
map,
config.drawConfig.polygon
);
}
drawLayer.enable(); // 启动绘制
}
// 取消绘制
function disableDraw() {
if (drawLayer) {
drawLayer.disable();
drawLayer = null;
}
}
// 清除绘制
function clearDraw() {
layerGroup.clearLayers();
}
/**
* 添加自定义div标注
* @param {*} coordinate 坐标
* @param {*} divHtml htm字符串
* @param {*} option 配置项
* @returns
*/
function addDivIconMarker(
coordinate = [],
divHtml,
option = {}
) {
const divIcon = L.divIcon({
className: "hidden-icon",
html: divHtml,
...option,
});
const marker = L.marker(coordinate, {
icon: divIcon,
});
return marker;
}
// 测面
function formatArea(coordinate = []) {
const seeArea = L.GeometryUtil.geodesicArea(coordinate); //单位默认平方米
return seeArea.toFixed(2) + 'm²';
}
// 测距
function formatLength(coordinate = []) {
let dis = 0;
for (let i = 0; i < coordinate.length - 1; i++) {
let start = coordinate[i];
let end = coordinate[i + 1];
dis += L.latLng([start.lat, start.lng]).distanceTo([end.lat, end.lng]);
}
if (dis > 1000) {
return (dis / 10e2).toFixed(2) + 'km'
} else {
return dis.toFixed(2) + 'm';
}
}
</script>
</body>
</html>
相关api参考:
GitHub - Leaflet/Leaflet.draw: Vector drawing and editing plugin for Leaflet