如何使用传单检测多边形边缘的点击

How can I detect a click on the edge of a polygon with Leaflet?

本文关键字:边缘 多边形 检测 何使用 单检测      更新时间:2023-09-26

情况:我有一张传单地图(带有Leaflet.draw)。在此地图上是各种几何图形(点,线,多边形),添加为geoJson(使用L.geoJson)。每个几何图形都有一个单击处理程序。

问题:当有人在多边形内单击时,将触发单击事件。

溶液:我只希望在单击多边形边(闭合折线)时触发单击事件。解决方法是检测单击到边缘的距离。

我找不到记录在案的解决方案。将不胜感激。

在忽略@chrki的答案时开始这个答案,我的答案相似,但结果略有不同,使用更少的逻辑和更少的层。所以我想我把它扔在这里是为了好好衡量。

如前所述,传单中无法检测到边缘点击。将事件附加到要素后,它将响应整个元素。您可以做的是双重绘制要素,在 geojson 图层生成的面顶部放置一条折线,然后将侦听器附加到折线而不是面。

// Create geojson layer w/o adding data
var geojson = new L.GeoJSON(null, {
    // Don't draw the stroke
    style: function () {
        return {
            stroke: false
        }
    },
    onEachFeature: function (feature, layer) {
        // Check if layer is a polygon
        if (layer instanceof L.Polygon) {
            // Fetch coordinates from polygon
            var latLngs = layer.getLatLngs();
            // Push first coordinate to complete line
            latLngs.push(latLngs[0]);
            // Create polyline using coordinates
            var polyline = new L.Polyline(latLngs);
            // Add click listener
            polyline.on('click', function () {
                alert('Polyline clicked!');
            });
            // Add polyline to featuregroup
            polyline.addTo(featureGroup);
        }
    }
}).addTo(map);
// Create featuregroup, add it to the map
var featureGroup = new L.FeatureGroup().addTo(map);
// Test 
geojson.addData({
    "type": "FeatureCollection",
    "features": [{
        "type": "Feature",
        "properties": {},
        "geometry": {
            "type": "Polygon",
            "coordinates": [[
                [-45, -45],
                [-45, 45],
                [45, 45],
                [45, -45],
                [-45, -45]
            ]]
        }
    }]
});

Plunker的工作示例:http://plnkr.co/edit/d1tLOIEeBPsv7YFDWavA?p=preview

我能想到的一种方法是创建一条具有相同坐标的附加折线并将其放在多边形的顶部,并使多边形不可单击。这将需要使用 onEachFeature 添加一些用于创建 GeoJSON 要素的逻辑。

Leaflet 的多边形(和折线)由单个 SVG 元素组成,我不确定是否可以在不做一些 Javascript 数学或类似操作的情况下检测外边缘的点击,onclick事件只是附加到整个元素。

var polyoverlay = new L.featureGroup().addTo(map);
var edgeoverlay = new L.featureGroup().addTo(map);
var geojsonobj = {"type": "FeatureCollection", "features": [{"type": "Feature", "properties": {}, "geometry": {"type": "Polygon", "coordinates": [[[-87.027648, 20.820875 ], [-87.027648, 21.320875 ], [-86.527648, 21.320875 ], [-86.527648, 20.820875 ], [-87.027648, 20.820875 ] ] ] } } ] };
var poly = L.geoJson(geojsonobj, {
  onEachFeature: function(feature, layer){
    // latitude/longitude to longitude/latitude coordinates
    var lonlats = [];
    feature.geometry.coordinates[0].forEach(function(f){
      lonlats.push([f[1], f[0]]);
    });
    // add polyline to map
    var polyline = L.polyline(lonlats,{
        color: 'black'
      }).bindPopup('hello').addTo(edgeoverlay);
    // add polygon to map        
    var polygon = L.polygon(lonlats,{
        color: 'blue',
        clickable: false
      }).addTo(polyoverlay);
  }
});

http://plnkr.co/edit/w5Ta96X9TVOqHpHw1jZQ?p=preview