【问题标题】:Leaflet event: how to propagate to overlapping layers传单事件:如何传播到重叠层
【发布时间】:2017-03-24 18:46:03
【问题描述】:

假设我有一些重叠的图层,每个图层都有一个点击事件。当我点击地图时,我想知道点击了哪些图层,尽管点击事件在第一层之后停止并且不会传播到其底层。我怎样才能做到这一点?

这是一个示例小提琴及其代码:https://jsfiddle.net/r0r0xLoc/

<div id="mapid" style="width: 600px; height: 400px;"></div>

<script>
  var mymap = L.map('mapid').setView([51.505, -0.09], 13);

  L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
    maxZoom: 18,
    attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
      '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
      'Imagery © <a href="http://mapbox.com">Mapbox</a>',
    id: 'mapbox.streets'
  }).addTo(mymap);

  L.polygon([
    [51.509, -0.08],
    [51.503, -0.06],
    [51.51, -0.047]
  ]).addTo(mymap).on('click', function() {
    console.log('clicked on 1st polygon')
  });

  L.polygon([
    [51.609, -0.1],
    [51.503, -0.06],
    [51.51, -0.047]
  ]).addTo(mymap).on('click', function() {
    console.log('clicked on 2nd polygon')
  });

</script>

如果您单击每个多边形,您会看到其相关消息。如果单击重叠部分,您只会看到第二个多边形的消息。

【问题讨论】:

    标签: javascript leaflet


    【解决方案1】:

    您必须直接收听地图"click" 事件并“手动”确定哪些图层包含点击位置。

    您可以使用leaflet-pip 插件(多边形中的点)例如进行此确定:

    map.on("click", function (event) {
      var clickedLayers = leafletPip.pointInLayer(event.latlng, geoJSONlayerGroup);
      // Do something with clickedLayers
    });
    

    演示:https://jsfiddle.net/ve2huzxw/526/(收听"mousemove"而不是"click"

    【讨论】:

    • 最后我使用了同样的方法,并在地图本身上监听了点击事件。我没试过leaflet-pip;相反,我使用 turfjs/inside 来确定图层是否包含点击点。不过,我认为假设事件应该传播到所有层是合乎逻辑的。
    • 只是一个旁注,这些都是很好的建议。不幸的是,当您的图层是简单的线条时,这无济于事。
    【解决方案2】:

    有一个传单插件用于将事件传播到底层:https://github.com/danwild/leaflet-event-forwarder

    您可以在 javascript 中使用它来启用事件转发,例如:

    const myEventForwarder = new L.eventForwarder({
      map: map,
      events: {click: true, mousemove: false}
    });
    

    【讨论】:

      【解决方案3】:

      问题在于添加层(几何)的顺序。就我而言,我有一个几何数组,我所做的只是使用其边界L.LatLngBounds#contains 对几何数组进行排序,因此如果一个几何包含另一个几何,则应稍后添加。

      var geometries = [layerOne, layerTwo, ...];
      geometries
        .sort((a, b) => {
          // in my case a separate function is required because the geometry could be a Circle, Rectangle, Polygon or Marker
          // and the methods to get the corresponding bounds are different.
          var boundsA = this.getBoundsFromGeometry(a);
          var boundsB = this.getBoundsFromGeometry(b);
          // if the second geometry contains the first, the order must be change so the layers don't overlap
          return boundsB.contains(boundsA) ? 1 : -1;
        })
        .forEach(l => this.map.addLayer(l));
      

      【讨论】:

        【解决方案4】:

        对我来说,解决方案是在创建上层时使用选项interactive: false

         var options = {
               style: feature => this.__determineStyle(feature),
               interactive: false,
         };
        
         var overlay = L.geoJson(geoJsonData, options);
         overlay.addTo(this.map);
        

        https://leafletjs.com/reference-1.0.3.html#interactive-layer

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-02-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-21
          • 1970-01-01
          相关资源
          最近更新 更多