目录
初始化
<div ref="map" id="map"></div>
#map {
height: 90%;
width: 100%;
}
import { ref, onMounted, nextTick } from "vue";
import { Config } from "@/config";//项目配置
//引入leaflet
import L from "leaflet";
import "leaflet/dist/leaflet.css";
//初始化
let map = ref(); //地图容器
let myMap; //地图实例
const initDate = () => {
myMap = L.map(map.value).setView([31, 117], 13);
L.tileLayer(Config.baseMap).addTo(myMap);;//项目配置地图接口,没有可以使用下面的在线地图
//在线的瓦片地图源,"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",需要翻墙
};
onMounted(() => {
nextTick(() => {
initDate();
});
});
动态绘圆
思路:动态绘圆主要涉及到三个事件:
mousedown,mousemove,mouseup
mousedown
确定圆的圆心,mouseup
确定圆的半径,mousemove
绘制鼠标移动过程中圆的变化鼠标按下确定圆心,松开鼠标确定半径绘制完成
import { ref, onMounted, nextTick } from "vue";
import { Config } from "@/config";
import L from "leaflet";
import "leaflet/dist/leaflet.css";
let map = ref(); //地图容器
let myMap; //地图实例
//绘制圆
//读取点击位置坐标并返回其经纬度
//r用来存储半径,i用来存储圆心经纬度
//tempCircle是用来存放圆的图层
let r;
let i;
let tempCircle;
//移除圆图层
function removeCircle() {
myMap.removeLayer(tempCircle);
}
function drawCircle() {
//在绘制圆之前需要先判断是否已经绘制过了,如果有,则清空再绘制
//如果需要绘制多个圆,则不必此句
if (tempCircle) {
removeCircle();
}
r = 0;
i = null;
tempCircle = new L.circle();
myMap.dragging.disable(); //将mousemove事件拖拽地图禁用
//监听鼠标落下事件
myMap.on("mousedown", onmouseDown);
function onmouseDown(e) {
//确定圆心
i = e.latlng;
//监听鼠标移动事件
myMap.on("mousemove", onMove);
//监听鼠标弹起事件
myMap.on("mouseup", onmouseUp);
}
function onMove(e) {
r = L.latLng(e.latlng).distanceTo(i); //计算半径
if (i) {
//绘制圆心位置与半径
tempCircle.setLatLng(i);
tempCircle.setRadius(r);
tempCircle.setStyle({ color: "#ff0000", fillOpacity: 0.5});
myMap.addLayer(tempCircle);
}
}
function onmouseUp(e) {
r = L.latLng(e.latlng).distanceTo(i);
L.circle(i, { radius: r, color: "#ff0000", fillOpacity:0.5 });
myMap.addLayer(tempCircle);
myMap.dragging.enable();
//动画滑动居中圆
myMap.flyToBounds(tempCircle.getBounds());
i = null;
r = 0;
//取消监听事件
myMap.off("mousedown");
myMap.off("mouseup");
myMap.off("mousemove");
}
}
const initDate = () => {
myMap = L.map(map.value).setView([31, 117], 13);
L.tileLayer(Config.baseMap).addTo(myMap);
drawCircle();//开始绘制圆时调用,可以反复调用,自动清空
};
onMounted(() => {
nextTick(() => {
initDate();
});
});
动态绘线
思路:动态绘线主要涉及到三个事件:
click,dbclick,mousemove
click
确定线的折点,dbclick
确定线的终点,mousemove
绘制鼠标移动过程线的变化
<el-button-group style="margin-top: 5px">
<el-button :icon="Edit" @click="drawLines">开始编辑</el-button>
<el-button :icon="Close" @click="offDraw">关闭编辑</el-button>
<el-button :icon="Delete" @click="deleteDraw">清除</el-button>
</el-button-group>
import { ref, onMounted, nextTick } from "vue";
import { Config } from "@/config";
import L from "leaflet";
import "leaflet/dist/leaflet.css";
let map = ref(); //地图容器
let myMap; //地图实例
let points = [];//折点
let lines; //折线
let timer;
//按钮和双击都能结束绘制
//点击按钮结束绘制
const offDraw = () => {
lines.setLatLngs(points);
//触发双击事件,结束绘制
myMap.fire("dblclick");
myMap.off("dblclick");
};
//清除多边形
const deleteDraw = () => {
myMap.removeLayer(lines);
};
//开始绘制
function drawLines() {
if (lines) {
deleteDraw();
}
points = [];
lines = new L.polyline(points).addTo(myMap);
myMap.off("dblclick"); //首次绘制时取消默认双击放大地图事件
myMap.on("click", onClick);
function onClick(e) {
clearTimeout(timer); // 先清定时器
timer = setTimeout(() => {
// 再延迟执行
points.push([e.latlng.lat, e.latlng.lng]);
lines.setLatLngs(points);
myMap.on("mousemove", onMove);
myMap.on("dblclick", onDoubleClick);
}, 50);
}
function onMove(e) {
points.push([e.latlng.lat, e.latlng.lng]);
lines.setLatLngs(points);
points.pop();
}
function onDoubleClick(e) {
clearTimeout(timer);
myMap.off("click");
myMap.off("mousemove");
}
}
const initDate = () => {
myMap = L.map(map.value).setView([31, 117], 13);
L.tileLayer(Config.baseMap).addTo(myMap);
drawLines();
};
onMounted(() => {
nextTick(() => {
initDate();
});
});
动态绘多边形(单个)
思路:动态绘多边形主要涉及到三个事件:
click,dbclick,mousemove
click
确定多边形的角,dbclick
确定多边形结束的角,mousemove
绘制鼠标移动过程中多边形的变化注意:单击事件和双击事件冲突,双击时执行两次单击事件;使用定时器解决,在单击事件函数里通过定时器控制延迟执行。单击事件函数和双击事件函数里都先清定时器。
效果:双击第一次点击执行单击函数,第二次点击执行双击函数,达到最后双击结束点也算多边形一角的效果。
<el-button-group style="margin-top: 5px">
//开始编辑单个多边形drawPolygon,多个多边形drawPolygons
<el-button :icon="Edit" @click="drawPolygon">开始编辑</el-button>
<el-button :icon="Close" @click="offDraw">关闭编辑</el-button>
<el-button :icon="Delete" @click="deleteDraw">清除</el-button>
</el-button-group>
import { ref, onMounted, nextTick } from "vue";
import { Config } from "@/config";
//引入leaflet
import L from "leaflet";
import "leaflet/dist/leaflet.css";
let map = ref();
let myMap;
let points = [];
let polygon;
let timer;
//按钮和双击都能结束绘制
//点击按钮结束绘制
const offDraw = () => {
polygon.setLatLngs(points);
//触发双击事件,结束绘制
myMap.fire("dblclick");
myMap.off("dblclick");
};
//清除多边形
const deleteDraw = () => {
myMap.removeLayer(polygon);
};
//开始绘制
function drawPolygon() {
if (polygon) {
deleteDraw();
}
points = [];
polygon = new L.polygon(points, { color: "red" }).addTo(myMap);
//取消默认双击放大地图事件
myMap.off("dblclick");
myMap.on("click", onClick);
function onClick(e) {
// 先清定时器
clearTimeout(timer);
timer = setTimeout(() => {
// 再延迟执行
points.push([e.latlng.lat, e.latlng.lng]);
polygon.setLatLngs(points);
myMap.on("mousemove", onMove);
myMap.on("dblclick", onDoubleClick);
console.log("click", polygon._latlngs[0]);
}, 50);
}
function onMove(e) {
points.push([e.latlng.lat, e.latlng.lng]);
polygon.setLatLngs(points);
points.pop();
}
function onDoubleClick(e) {
clearTimeout(timer);
myMap.off("click");
myMap.off("mousemove");
}
//初始化
const initDate = () => {
myMap = L.map(map.value).setView([31, 117], 13);
L.tileLayer(Config.baseMap).addTo(myMap);
drawPolygon();//开始绘制多边形
};
onMounted(() => {
nextTick(() => {
initDate();
});
});
动态绘多边形(多个)
import { ref, onMounted, nextTick } from "vue";
import { Config } from "@/config";
import L from "leaflet";
import "leaflet/dist/leaflet.css";
let map = ref(); //地图容器
let myMap; //地图实例
let points = [];
let polygon;
let polygonGroup;
let timer;
//按钮和双击都能结束绘制
//点击按钮结束绘制
const offDraw = () => {
polygon.setLatLngs(points);
//触发双击事件,结束绘制
myMap.fire("dblclick");
myMap.off("click");
myMap.off("dblclick");
};
//清除多边形图层组
const deleteDraw = () => {
myMap.removeLayer(polygonGroup);
};
//开始绘制
function drawPolygons() {
if (polygonGroup) {
deleteDraw();
}
points = [];
polygon = new L.polygon(points, { color: "red" });
polygonGroup = L.layerGroup().addTo(myMap);
polygonGroup.addLayer(polygon);
myMap.off("dblclick"); //首次绘制时取消默认双击放大地图事件
myMap.on("click", onClick);
function onClick(e) {
clearTimeout(timer); // 先清定时器
timer = setTimeout(() => {
// 再延迟执行
points.push([e.latlng.lat, e.latlng.lng]);
polygon.setLatLngs(points);
myMap.on("mousemove", onMove);
myMap.on("dblclick", onDoubleClick);
}, 10);
}
function onMove(e) {
points.push([e.latlng.lat, e.latlng.lng]);
polygon.setLatLngs(points);
points.pop();
}
function onDoubleClick(e) {
clearTimeout(timer);
myMap.off("mousemove");
points = [];
polygon = new L.polygon(points, { color: "red" }).addTo(polygonGroup);
}
}
const initDate = () => {
myMap = L.map(map.value).setView([31, 117], 13);
L.tileLayer(Config.baseMap).addTo(myMap);
drawPolygons();
};
onMounted(() => {
nextTick(() => {
initDate();
});
});