【问题标题】:Adding event handler to feature in OpenLayers 3?将事件处理程序添加到 OpenLayers 3 中的功能?
【发布时间】:2014-10-15 20:08:51
【问题描述】:

我正在使用以下代码向 OpenLayers 3 (OL3) 中的矢量图层添加特征:

marker = new ol.Feature({
    geometry: new ol.geom.Point([longitude, latitude]),
    name: "Location Marker"
});
markerStyle = new ol.style.Style({
  image: new ol.style.Icon({
    anchor: [0.5, 1.0],
    anchorXUnits: "fraction",
    anchorYUnits: "fraction",
    src: "Content/Images/OpenLayers/marker_trans.png"
  }),
  zIndex: 100000
});
marker.setStyle(markerStyle);
marker.on("click", function(e) {
  // do something
}, marker);
map.getSource().addFeature(marker);

标记按预期显示,但点击事件永远不会触发。我做错了什么?

我应该注意到在地图级别已经有一个与“点击”相关的处理程序,即

map.on("click", function(e) {
  // do something
}, marker);

【问题讨论】:

    标签: javascript openlayers openlayers-3


    【解决方案1】:

    第一:功能不会触发点击!有关触发的事件功能的信息,请查看http://openlayers.org/en/master/apidoc/ol.Feature.html

    为了检查一个特征是否被点击,ol.Map 有.forEachFeatureAtPixel(pixel, callback) 函数。 (http://openlayers.org/en/master/apidoc/ol.Map.html#forEachFeatureAtPixel) 回调在像素的每个特征上执行。回调传递了 2 个参数:特征和特征所在的层。

    很高兴知道.getEventPixel(event) 函数,如果您不使用openlayers 事件处理程序而是使用视口上的处理程序。如果您使用 openlayers 事件处理程序,则该事件具有属性 .pixel。 (http://openlayers.org/en/master/apidoc/ol.Map.html#getEventPixel) .getEventCoordinate(event).getCoordinateFromPixels(pixels) 方法也可能有用。

    所以你可以像这样将它添加到你的 map.on("click", ... :

    map.on("click", function(e) {
        map.forEachFeatureAtPixel(e.pixel, function (feature, layer) {
            //do something
        })
    });
    

    与 jQuery 相同:

    $(map.getViewport()).on("click", function(e) {
        map.forEachFeatureAtPixel(map.getEventPixel(e), function (feature, layer) {
            //do something
        });
    });
    

    与纯 JS 相同:

    map.getViewport().addEventListener("click", function(e) {
        map.forEachFeatureAtPixel(map.getEventPixel(e), function (feature, layer) {
            //do something
        });
    });
    

    您可能还想查看这个示例,这个函数有两种用途,第一种是 openlayers 事件,第二种是 jQuery 事件: http://openlayers.org/en/master/examples/icon.js

    注意

    也可以使用 ol.interaction.Select (http://openlayers.org/en/master/apidoc/ol.interaction.Select.html?unstable=true) 来执行此操作,但在这种情况下这有点过分了。并且它有一些不直观的警告,因为 openlayers 在内部将选定的特征移动到另一个所谓的非托管层。

    无论如何,这可以通过将侦听器添加到属于交互的集合来实现。可以使用.getFeatures() 检索该集合。

    interaction.getFeatures().on("add", function (e) { 
        // do something. e.element is the feature which was added
    });
    

    【讨论】:

    • 根据openlayers.org/en/v3.0.0/apidoc/ol.Feature.html#on 可以添加这样的处理程序。有什么想法支持这个事件吗?仅仅是“变化”和“变化:几何”事件吗?您对不属于 DOM 的功能的评论有助于我理解为什么“点击”不会触发功能。使用 OL2,我可以将“悬停”事件添加到功能/标记中。新方法是否与您为“点击”事件描述的相同,即使用 map.on("onmouseover", function(e){map.forEachFeatureAtPixel(...)}}
    • 当然你可以添加这样的处理程序,但它永远不会被触发......你可以在文档中阅读,就在构造函数的描述下方。不,没有任何未记录的-我也为您检查了代码:P(顺便说一句,文档非常完整-如果您取消选中仅稳定的复选框)。我不认为 ol.Map 会触发一个名为“onmouseover”的事件,但您可以使用 jquery 或基本 js 来做到这一点。 $(map.getViewport()).on("mousemove", function(e){map.forEachFeatureAtPixel(map.getEventPixel(e), ...)} 请查看示例。
    • 我已将此标记为答案,因为它解决了我关于我想要的特定点击交互的问题。但是,对于其他功能交互,例如“悬停”,我认为openlayers.org/en/v3.0.0/examples/select-features.html 使用 ol.interaction 提供了更好的方法
    • 如果地图有交互,更简洁的方法是使用ol.interaction实例的getFeatures()方法而不是forEachFeatureAtPixel()
    • openlayers.org/en/master/apidoc/… 说:为了停止检测,回调函数可以返回一个真实值。
    【解决方案2】:

    如果您只想点击地图,请this will work 为您服务。

      var map = new ol.Map({
        target: 'map',
        layers: [
          new ol.layer.Tile({
            source: new ol.source.MapQuest({layer: 'sat'})
          })
        ],
        view: new ol.View({
          center: ol.proj.transform([37.41, 8.82], 'EPSG:4326', 'EPSG:3857'),
          zoom: 4
        })
      });
    
    map.on("click", function(evt) {
        var coord = ol.proj.transform(evt.coordinate, 'EPSG:3857', 'EPSG:4326');
        var lon = coord[0];
        var lat = coord[1];
        alert(lon);
        alert(lat);
    });
    

    【讨论】:

      【解决方案3】:

      如果您只需要在地图上添加一个可点击的标记,您可以使用叠加层。在您的 HTML 标头中定义标记的样式:

      <style>
          #marker {
              width: 20px;
              height: 20px;
              border: 1px solid #088;
              border-radius: 10px;
              background-color: #0FF;
              opacity: 0.5;
          }
      </style>
      

      然后在文件的脚本部分,在地图创建后:

          // add marker
          var pos = ol.proj.fromLonLat([0.01123, 0.00612]);
          var marker = new ol.Overlay({
              position: pos,
              positioning: 'center-center',
              element: $('<div id="marker" title="Marker"></div>')
                  .popover({
                      'placement': 'top',
                      'html': true,
                      'content': '<strong>anything...</strong>'
                  })
                  .on('click', function (e) { $(".location-popover").not(this).popover('hide'); }),
              stopEvent: false
          });
          map.addOverlay(marker);
      

      【讨论】:

      • 这个问题是 ol.Feature 特有的
      猜你喜欢
      • 2021-02-26
      • 2018-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多