二十四、openlayers官网示例Custom Interactions——自定义交互实现在地图上移动、拖拽feature

二十四、openlayers官网示例Custom Interactions——自定义交互实现在地图上移动、拖拽feature

码农世界 2024-05-23 后端 57 次浏览 0个评论

官网demo地址:

Custom Interactions

二十四、openlayers官网示例Custom Interactions——自定义交互实现在地图上移动、拖拽feature

这个示例介绍了如何在地图上自定义一个交互实现在地图上拖拽、移动要素。

首先是加载了三个要素到地图上,一个点、一个多边形、一条线。

const pointFeature = new Feature(new Point([0, 0]));
      const lineFeature = new Feature(
        new LineString([
          [-1e7, 1e6],
          [-1e6, 3e6],
        ])
      );
      const polygonFeature = new Feature(
        new Polygon([
          [
            [-3e6, -1e6],
            [-3e6, 1e6],
            [-1e6, 1e6],
            [-1e6, -1e6],
            [-3e6, -1e6],
          ],
        ])
      );
  new VectorLayer({
       source: new VectorSource({
          features: [pointFeature, lineFeature, polygonFeature],
        }),
        style: {
          "icon-src": "data/icon.png",
          "icon-opacity": 0.95,
          "icon-anchor": [0.5, 46], //设置图标锚点的位置  
          "icon-anchor-x-units": "fraction", //指定锚点的水平单位是比例值
          "icon-anchor-y-units": "pixels", //指定锚点的垂直单位是像素值
          "stroke-width": 3,
          "stroke-color": [255, 0, 0, 1],
          "fill-color": [0, 0, 255, 0.6],
        },
    }),

然后创建了一个类继承原本的PointerInteraction,将四个事件作为参数传递给PointerInteraction。来处理事件逻辑。

class Drag extends PointerInteraction {
    constructor() {
        super({
            handleDownEvent: handleDownEvent, //按下事件
            handleDragEvent: handleDragEvent, //拖动事件
            handleMoveEvent: handleMoveEvent, //移动事件
            handleUpEvent: handleUpEvent, //释放事件
        });
        //存储鼠标点击时的坐标
        this.coordinate_ = null;
        //用于存储鼠标悬停在要素上时的光标样式
        this.cursor_ = "pointer";
        //存储被拖拽的要素  
        this.feature_ = null;
        //存储之前的光标样式,以便恢复
        this.previousCursor_ = undefined;
    }
}

可以看下源码中PointerInteraction的定义。

二十四、openlayers官网示例Custom Interactions——自定义交互实现在地图上移动、拖拽feature

这里移动要素用了一个geometry.translate()方法,如果我们自己写方法来完成移动的话会比较麻烦。

/**
* @param {import("../src/ol/MapBrowserEvent.js").default} evt Map browser event.
*/
function handleDragEvent(evt) {
    //计算鼠标拖动的位移
    const deltaX = evt.coordinate[0] - this.coordinate_[0];
    const deltaY = evt.coordinate[1] - this.coordinate_[1];
    //平移被拖拽要素的几何图形
    const geometry = this.feature_.getGeometry();
    geometry.translate(deltaX, deltaY);
    //更新存储的坐标为当前鼠标的位置
    this.coordinate_[0] = evt.coordinate[0];
    this.coordinate_[1] = evt.coordinate[1];
}

 重新定义了一个Drag类,我放在了utils下的Drag.js中便于多次使用。

import Drag from '@/utils/Drag'
const map = new Map({
     interactions: defaultInteractions().extend([new Drag()]),
})

完整代码:

utils/Drag.js:

import {
    Pointer as PointerInteraction,
} from "ol/interaction.js";
class Drag extends PointerInteraction {
    constructor() {
        super({
            handleDownEvent: handleDownEvent, //按下事件
            handleDragEvent: handleDragEvent, //拖动事件
            handleMoveEvent: handleMoveEvent, //移动事件
            handleUpEvent: handleUpEvent, //释放事件
        });
        //存储鼠标点击时的坐标
        this.coordinate_ = null;
        //用于存储鼠标悬停在要素上时的光标样式
        this.cursor_ = "pointer";
        //存储被拖拽的要素  
        this.feature_ = null;
        //存储之前的光标样式,以便恢复
        this.previousCursor_ = undefined;
    }
}
/**
         * @param {import("../src/ol/MapBrowserEvent.js").default} evt Map browser event.
         * @return {boolean} `true` to start the drag sequence.
         */
function handleDownEvent(evt) {
    const map = evt.map;
    // 在地图上检测鼠标点击的位置是否有要素,如果有,则存储要素和点击位置的坐标
    const feature = map.forEachFeatureAtPixel(evt.pixel, function (feature) {
        return feature;
    });
    if (feature) {
        this.coordinate_ = evt.coordinate;
        this.feature_ = feature;
    }
    return !!feature;
}
/**
* @param {import("../src/ol/MapBrowserEvent.js").default} evt Map browser event.
*/
function handleDragEvent(evt) {
    //计算鼠标拖动的位移
    const deltaX = evt.coordinate[0] - this.coordinate_[0];
    const deltaY = evt.coordinate[1] - this.coordinate_[1];
    //平移被拖拽要素的几何图形
    const geometry = this.feature_.getGeometry();
    geometry.translate(deltaX, deltaY);
    //更新存储的坐标为当前鼠标的位置
    this.coordinate_[0] = evt.coordinate[0];
    this.coordinate_[1] = evt.coordinate[1];
}
/**
 * @param {import("../src/ol/MapBrowserEvent.js").default} evt Event.
 */
function handleMoveEvent(evt) {
    if (this.cursor_) {
        const map = evt.map;
        const feature = map.forEachFeatureAtPixel(
            evt.pixel,
            function (feature) {
                return feature;
            }
        );
        //检测鼠标移动到的要素,如果有要素则改变光标样式。
        const element = evt.map.getTargetElement();
        if (feature) {
            if (element.style.cursor != this.cursor_) {
                this.previousCursor_ = element.style.cursor;
                element.style.cursor = this.cursor_;
            }
            //如果鼠标移出要素,则恢复之前的光标样式
        } else if (this.previousCursor_ !== undefined) {
            element.style.cursor = this.previousCursor_;
            this.previousCursor_ = undefined;
        }
    }
}
/**
 * @return {boolean} `false` to stop the drag sequence.
 */
//重置存储的坐标和要素,表示拖拽序列结束
function handleUpEvent() {
    this.coordinate_ = null;
    this.feature_ = null;
    return false;
}
export default Drag

.vue文件: 




转载请注明来自码农世界,本文标题:《二十四、openlayers官网示例Custom Interactions——自定义交互实现在地图上移动、拖拽feature》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,57人围观)参与讨论

还没有评论,来说两句吧...

Top