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; // 存放Feataure的图层
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: "#ffcc33",
      color: "#ff0033",
      width: 2,
    }),
    image: new CircleStyle({
      radius: 3,
      fill: new Fill({
        color: "#ffcc33",
      }),
    }),
  }),
});
let select; // 选中控件
/**
 * 初始化地图
 */
const initialMap = () => {
  map = new Map({
    target: "map", // 地图放到哪个容器中,值应该是div的id
    layers: [
      new TileLayer({
        source: new OSM(), // 加载OSM底图
      }),
      drawLayer,
    ],

    // 以EPSG:4326为坐标系定义地图的视图中心和缩放级别
    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选中事件
  select.on("select", (evt) => {
    selectedFeature = select.getFeatures().getArray();
  });
};

/**
 * 绘制功能
 * @param type 想要绘制什么类型的图斑
 */
const addDraw = (type) => {
  draw = new Draw({
    source: drawSource,
    type: type,
  });
  map.addInteraction(draw);

  const snap = new Snap({
    source: drawSource,
    // features: [vectorLayer.getSource().getFeatures()],
    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);
    // drawSource.addFeature(evt.feature);
  });

  // 移除双击缩放地图功能,使双击只用来结束绘制功能
  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.实现效果

鼠标吸附

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
OpenLayers 是一个开源的地图库,它提供了丰富的功能和工具来创建交互式地图应用程序。关于吸附功能OpenLayers 目前没有直接内置的吸附功能。然而,你可以通过编写自定义代码来实现吸附效果。 一种常见的方法是使用 OpenLayers 的事件监听器来捕获鼠标移动事件,并在需要吸附的位置附近检测其他对象或地物的位置。你可以使用 OpenLayers 的坐标转换功能来将鼠标位置转换为地图上的坐标,然后通过计算距离来判断是否需要吸附到其他对象。 以下是一个简单的示例代码,演示了如何使用 OpenLayers 中的事件监听器和坐标转换来实现吸附效果: ```javascript // 创建一个地图实例 var map = new ol.Map({ // ... 地图配置项 }); // 创建一个矢量图层 var vectorLayer = new ol.layer.Vector({ // ... 矢量图层配置项 }); // 将矢量图层添加到地图中 map.addLayer(vectorLayer); // 监听鼠标移动事件 map.on('pointermove', function(event) { // 获取鼠标在地图中的像素坐标 var pixel = event.pixel; // 将像素坐标转换为地图坐标 var coordinate = map.getCoordinateFromPixel(pixel); // 遍历矢量图层上的要素 vectorLayer.getSource().forEachFeature(function(feature) { // 获取要素的几何对象 var geom = feature.getGeometry(); // 计算鼠标位置与要素位置之间的距离 var distance = geom.distance(coordinate); // 如果距离小于一个阈值,进行吸附操作,例如设置新的坐标值等 if (distance < 10) { // 执行吸附操作 // ... } }); }); ``` 请注意,以上代码仅为示例,具体的吸附操作需要根据你的需求进行适当的调整和实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值