【问题标题】:Select one feature of multiple overlapping features (here polygons) on a Leaflet map在传单地图上选择多个重叠特征(此处为多边形)中的一个特征
【发布时间】:2016-07-10 14:37:27
【问题描述】:

我有一张地图,上面渲染了多个可以相互重叠的多边形。我使用来自https://github.com/mapbox/leaflet-pipleafletPip.pointInLayer(point, layer) 来确定哪些多边形重叠。这发生在 processClick 函数中。在 Vue 对象中,我使用多边形创建地图和 GeoJSON 图层。我现在想要的是以下功能:如果您单击地图上的一个点并且该点包含在多个多边形中,那么您将拥有类似于选择工具的东西,例如在弹出窗口中,单击其中一个多边形并仅针对该特定多边形触发 .on('click') 函数。我搜索了所有 Leaflet 功能,但找不到任何真正有用的东西。现在,如果您单击包含在多个多边形中的一个点,您只会触发在空间上包含其他多边形的多边形的 .on('click')。

var mapVue = new Vue({
  parent: vue_broadcaster,
  el: '#map',
  data: {
    map: null,
    layer: null
  },
  created: function () {
   // Adding Leaflet map here
    var map = L.map('map').setView([51.959, 7.623], 14);
    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
      attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);
    this.$set('map', map);
    this.get_zones();
  },
  methods: {
    switch_zone: function (zoneid) {
      this.$dispatch('zoneSelected', zoneid)
    },
    get_zones: function () {
      this.$http.get('/api/zones/', function (data) {
      // Creation of the GeoJSON layer
        var geoZone = {
          "type": "FeatureCollection",
          "features": []
        };
        for (var i = 0; i < data['Zones'].length; i++) {
          geoZone.features.push({
            "type": "Feature",
            "geometry": {
              "type": "Polygon",
              "coordinates": [[]]
            },
            "properties": {
              "name": ""
            }
          })
          geoZone.features[i].properties.name = data['Zones'][i]['Name'];
          for (var j = 0; j < data['Zones'][i]['Geometry']['Coordinates'].length; j++) {
            geoZone.features[i].geometry.coordinates[0].push([data['Zones'][i]['Geometry']['Coordinates'][j][1], data['Zones'][i]['Geometry']['Coordinates'][j][0]])
          }
          this.layer = new L.geoJson(geoZone)
            .bindPopup(data['Zones'][i]['Name'])
            .on('click', dispatchZoneID(data['Zones'][i]['Zone-id'], this))
            .on('click', function (e) {
              processClick(e.latlng.lat, e.latlng.lng)
            })
            .addTo(this.map)
        };
      })
    }
  }
});
// function for processing the clicks on the map
function processClick(lat, lng) {
  var info = '';
  var point = [lng, lat];
  var match = leafletPip.pointInLayer(point, mapVue.layer, false);
  if (match.length) {
    for (var i = 0; i < match.length; i++) {
      info +=
      "<b>" + match[i].feature.properties.name + "<br>"
    }
  }
  if (info) {
    mapVue.map.openPopup(info, [lat, lng]);
  }
};
// not important for this one
function dispatchZoneID(id, vue) {
  return function () {
    vue.$dispatch('zoneSelected', id)
  }
};

【问题讨论】:

    标签: javascript leaflet geojson vue.js point-in-polygon


    【解决方案1】:

    我找到了一个适合我的解决方案,但它可能不是最优雅的。如果单击的点包含在多个多边形 (match.length > 1) 中,我会生成这个 info 字符串。在每次迭代中,for 循环都会创建一个可点击的链接,然后根据 id 在点击时调用一个函数。所以我基本上必须在一个字符串中生成大量 HTML,并使用文字和字符串连接。然后我用 info 作为我的 html 参数调用 openPopup 函数。

    function processClick(lat, lng) {
      var info = '';
      var point = [lng, lat];
      var match = leafletPip.pointInLayer(point, mapVue.layer, false);
      if (match.length > 1) {
        for (var i = 0; i < match.length; i++) {
          id = match[i].feature.properties.zoneid;
          name = match[i].feature.properties.name;
          info +=
          "<b><a onclick='dispatchZoneID(\"" + id + "\")();'>"+ name + "</a><br>"
        }
      }
      else dispatchZoneID(mapVue.zoneid)();
    
      if (info) {
        mapVue.map.openPopup(info, [lat, lng]);
      }
    };
    

    【讨论】:

    • 我认为您的方法没有任何问题。也许您可以使用数据集生成元素并在其上附加事件侦听器,而不是使用带有内联 onclick 的 HTML 字符串,但您可能需要更多代码。
    • “使用数据集生成元素”到底是什么意思?
    • 类似var p = document.createElement("p"); p.dataset.zoneid = id; p.addEventListener(fnDispatch);
    猜你喜欢
    • 1970-01-01
    • 2022-04-26
    • 2015-08-16
    • 1970-01-01
    • 2016-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-12
    相关资源
    最近更新 更多