openlayer 鼠标点击船舶,打开船舶简单弹框

背景:

对创建的地图对象,可以添加上监听事件,常用的有:地图点击事件、鼠标移动事件。

通过监听这些事件,又可以区分不同图层的不同要素,获取不同数据;

根据这些数据,又可以发起网络请求、打开另一个弹框等后续操作。

在这里,主要介绍对船舶的不同点击或鼠标移动事件,二者的实现思路,仅供参考。

效果展示:

船舶的点击效果:点击船舶,选中的船舶添加上选中效果,是一个红色框。2.选中弹框更详细

船舶的鼠标移动效果:当鼠标移动到船舶对象上,选中的船舶变成选中效果,是原来船舶黑色边框变为红色边框,代表选中。 2.选中弹框包括一下基础信息。

一、监听地图对象的点击事件

1.监听鼠标点击

javascript 复制代码
    //覆盖图层点击事件
    MAPutils.GlobalMap.on('singleclick', function (e) {
        ...
        方法体
        ...
    })

2. 鼠标点击触发的方法

判断鼠标移动的地图对象是否存在。接着判断是哪一个图层,根据不同图层,触发不同是事件。这里自定义了一个事件featureClick(参数1,参数2).

不同的实现思路,不同的代码

javascript 复制代码
   /**
   * 图层点击事件
   * @return {Function}
   */
  featureClick: (function () {
    var _layerType = {
      ...
        // 船舶图层
      shipLayer: function (feature, offset) {
        // MAPutils.shipPop(feature.getId(), offset);
        MAPutils.drawFocus({ id: feature.getId(), layer: MAPutils.shipLayer });
        MAPutils.openShipDetailsV2(feature.getId());
      },
      ...
    }
    return function (feature, e) {
      var authId = feature.get('authId');
      // 如果此按钮是需要校验权限的并且此用户无权限,直接return
      if (authId && !WGAuth.click('button', authId))
        return;
      var layerType = feature.get("layerType"),
        offset = MAPutils.getLayerPixel(e);

      _layerType[layerType] && _layerType[layerType](feature, offset, e);
    }
  })(),

3.打开详细的船舶弹框

此处省略具体方法

openShipDetailsV2:function(){

//方法体

主要是根据参数发起网络请求、打开详情弹框、在详情弹框中的操作等等

}

以上是鼠标点击的省略思路,参照上面的,这篇文章主要详细介绍鼠标移上船舶、移下船舶的具体实现思路。。。

二、监听地图对象的鼠标移动事件pointermove

1.监听鼠标移动

javascript 复制代码
MAPutils.GlobalMap.on('pointermove', function (e) {
      if(e.dragging){
        return
      }
      const pixel = MAPutils.GlobalMap.getEventPixel(e.originalEvent);
      const hit = MAPutils.GlobalMap.hasFeatureAtPixel(pixel);
      if (hit) {
        MAPutils.GlobalMap.getTargetElement().style.cursor = 'pointer';
        var feature = MAPutils.GlobalMap.forEachFeatureAtPixel(e.pixel,function (feature) {return feature;});
        if (feature && feature.get("layerType") == "shipLayer") {
          if(feature !== MAPutils.oldFeature){
            MAPutils.oldFeature = feature
            MAPutils.featureMove(feature, e);
          }
        }else{
          MAPutils.oldFeature = null
          MAPutils.oldMmsi = null
        }
      }else{
        MAPutils.GlobalMap.getTargetElement().style.cursor = 'default';
        //关闭弹框
        MAPutils.DialogIndex && layer.close(MAPutils.DialogIndex || 0);
      }
    });

核心代码:

触发打开船舶简介弹框的核心代码:

javascript 复制代码
       if (feature && feature.get("layerType") == "shipLayer") {
          if(feature !== MAPutils.oldFeature){
            MAPutils.oldFeature = feature
            MAPutils.featureMove(feature, e);
          }
        }else{
          MAPutils.oldFeature = null
          MAPutils.oldMmsi = null
        }
备注:判断鼠标移动的地图对象是否存在。接着判断是哪一个图层,根据不同图层,
触发不同是事件。这里自定义了一个事件featureMove(参数1,参数2).
特别说明:这里还做了一个防抖处理。因为鼠标移动事件触发很频繁。并且鼠标摸船
显示弹框,鼠标移开关闭弹框。我这里通过两个变量来做的防抖。
不同的实现思路,不同的代码、

2.鼠标移动触发的方法

封装代码:

javascript 复制代码
/**
   * 图层点击事件
   * @return {Function}
   */
  featureMove: (function () {
    var _layerType = {
      //鼠标移动到船舶上
      shipLayer: function (feature, offset) {
        var myFeature = feature.get('data')
        var myColor = MAPutils.getAisColor(myFeature.aisType)
        let _style = new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: '#FF6B6B',
                width: 2
            }),
            fill: new ol.style.Fill({
                color: myColor
            })
        });
        feature.setStyle(_style);
        MAPutils.shipTipPop(feature.getId(), offset);
      }
    };

    return function (feature, e) {
      var authId = feature.get('authId');
      // 如果此按钮是需要校验权限的并且此用户无权限,直接return
      if (authId && !WGAuth.click('button', authId))
        return;
      var layerType = feature.get("layerType"),
        offset = MAPutils.getLayerPixel(e);

      _layerType[layerType] && _layerType[layerType](feature, offset, e);
    }
  })(),

3.打开船舶详情弹框

核心代码:

javascript 复制代码
   /**
   * 船舶tips弹窗
   * @param   id 船舶的id(mmsi)
   * @param  {Array} offset 弹窗位置
   */
  shipTipPop: function (id, offset) {
    var data = {};
    var myTimer = 1000;
    if(MAPutils.oldMmsi !== id){
      MAPutils.oldMmsi = id
    }else{
      return;
    }
    debounce(function () {
      $.post('ship/getByMMSI', { mmsi: id }, function (res) {
        if (res.code == 200 && !!res.data) {
          data = res.data
        }
        ...
        //根据结果渲染弹框
        ...
相关推荐
Cao_Ron37 分钟前
用 SVG image symbol 画 ECharts graph 圆形节点
前端
hxy060142 分钟前
React-Call让你的React组件像异步函数一样调用
前端·react.js
Hilaku43 分钟前
为什么 AI 写前端时,总是优先选择 React,而不是 Vue?
前端·javascript·程序员
京东云开发者1 小时前
GPT-5.6、ChatGPT Work 与 Codex 更新食用指南
前端
Cao_Ron1 小时前
用 ECharts graph 画出卡片式矩形节点
前端
skiyee1 小时前
换个底座的 Wot Starter 居然让 AI 更懂项目!
前端·ai编程
anyup1 小时前
这一套绝了!AI 大模型写故事,星云 SDK 驱动 3D 数字人实时演绎
前端·人工智能·aigc
耀耀切克闹灬1 小时前
短链跳转
前端
孟陬2 小时前
高质量全方位的 AI 工具 sse-stuntman — Mock SSE 接口
前端·node.js·openai
Cao_Ron2 小时前
给 ECharts 6 graph 节点叠加角标:从原理到性能优化
前端