- 前面的文章基本已经将OpenLayers的常用交互介绍完毕,由于业务需要开发了鼠标吸附功能,现在对鼠标吸附功能的实现和注意事项进行简单介绍。
一、背景
- 项目有需求希望能够将绘制出来的两个图斑严丝合缝的合并在一起,后面要使用ArcGIS进行后续处理。所以调研了OpenLayers的鼠标吸附功能,在这分享并记录一下。
二、Snap
1.Snap控件
- 实际上就是使用了OpenLayers官方提供的Snap插件,但是需要明确哪个图层是可以被吸附的,哪个图层是不能被吸附的。
- 我写的样例里面只有一个图层,但是在实际应用过程中,要对可以吸附的图层进行筛选。
2.注意事项
- 【注】:需要注意的是,Snap控件的初始化已经要在Draw控件的后面,否则是无法生效的。
三、鼠标吸附
1.代码实现
<template>
<!-- 初始化一个地图容器 -->
<div id="map"></div>
<div style="position: absolute; right: 50px">
<button @click="addDraw('Polygon')">绘制面</button>
</div>
</template>
<script setup>
import TileLayer from "ol/layer/Tile";
import { OSM } from "ol/source";
import { View } from "ol";
import { Map } from "ol";
import { onMounted } from "vue";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import { Fill, Stroke, Style } from "ol/style";
import { DoubleClickZoom, Draw, Select, Snap } from "ol/interaction";
import CircleStyle from "ol/style/Circle";
let map;
let vectorLayer;
let selectedFeature;
let draw;
let drawSource = new VectorSource();
let drawLayer = new VectorLayer({
source: drawSource,
style: new Style({
fill: new Fill({
color: "rgba(255, 255, 255, 0.2)",
}),
stroke: new Stroke({
color: "#ff0033",
width: 2,
}),
image: new CircleStyle({
radius: 3,
fill: new Fill({
color: "#ffcc33",
}),
}),
}),
});
let select;
const initialMap = () => {
map = new Map({
target: "map",
layers: [
new TileLayer({
source: new OSM(),
}),
drawLayer,
],
view: new View({
projection: "EPSG:4326",
center: [125.3574397847, 43.8865062907],
zoom: 18,
}),
});
select = new Select({
style: new Style({
fill: new Fill({
color: "rgba(255,0,0,0)",
}),
stroke: new Stroke({
color: "rgba(0,0,255,1)",
}),
}),
});
map.addInteraction(select);
select.on("select", (evt) => {
selectedFeature = select.getFeatures().getArray();
});
};
const addDraw = (type) => {
draw = new Draw({
source: drawSource,
type: type,
});
map.addInteraction(draw);
const snap = new Snap({
source: drawSource,
pixelTolerance: 20,
});
map.addInteraction(snap);
snap.setActive(true);
snap.on("change", (event) => {
console.log("change");
console.log(event);
});
snap.on("error", (event) => {
console.log("error");
console.log(event);
});
snap.on("snap", (event) => {
console.log("snap");
console.log(event);
});
draw.on("drawstart", (evt) => {});
draw.on("drawend", (evt) => {
console.log(evt);
});
const dblClickInteraction = map
.getInteractions()
.getArray()
.find((interaction) => {
return interaction instanceof DoubleClickZoom;
});
map.removeInteraction(dblClickInteraction);
map.on("dblclick", () => {
map.removeInteraction(draw);
});
};
onMounted(() => {
initialMap();
});
</script>
<style scoped>
#map {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
:deep(.ol-attribution) {
display: none;
}
</style>
2.实现效果