【问题标题】:How to simultaneously add new markers and remove old markers associated with polygon clicks in leaflet如何在传单中同时添加新标记并删除与多边形点击相关的旧标记
【发布时间】:2018-05-11 15:41:03
【问题描述】:

我有一张包含 Geojson 多边形的地图,其中每个多边形都由唯一的 ID 标识。我有一个单独的点标记 Geojson,其中每个点都与具有相同多边形 ID 的多边形相关联,以及每个单独点的唯一标识符。

初始地图显示只有多边形。每次单击多边形都会显示与单击的多边形相关联的点。单击新多边形时,我想绘制与新多边形关联的点,同时删除以前绘制的点。因此,每次用户单击多边形时,只会显示该多边形内的点。

这里是一些最低限度可重现的代码:https://jsfiddle.net/3v7hd2vx/1146/

var polys = {
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "stroke": "#555555",
        "stroke-width": 2,
        "stroke-opacity": 1,
        "fill": "#555555",
        "fill-opacity": 0.5,
        "polygon": "one"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              -87.33032226562499,
              37.90953361677018
            ],
            [
              -85.374755859375,
              37.90953361677018
            ],
            [
              -85.374755859375,
              39.036252959636606
            ],
            [
              -87.33032226562499,
              39.036252959636606
            ],
            [
              -87.33032226562499,
              37.90953361677018
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "stroke": "#555555",
        "stroke-width": 2,
        "stroke-opacity": 1,
        "fill": "#555555",
        "fill-opacity": 0.5,
        "polygon": "two"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              -85.3857421875,
              37.90953361677018
            ],
            [
              -83.3642578125,
              37.90953361677018
            ],
            [
              -83.3642578125,
              39.04478604850143
            ],
            [
              -85.3857421875,
              39.04478604850143
            ],
            [
              -85.3857421875,
              37.90953361677018
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "stroke": "#555555",
        "stroke-width": 2,
        "stroke-opacity": 1,
        "fill": "#555555",
        "fill-opacity": 0.5,
        "polygon": "three"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              -87.34130859375,
              36.90597988519294
            ],
            [
              -83.3642578125,
              36.90597988519294
            ],
            [
              -83.3642578125,
              37.91820111976663
            ],
            [
              -87.34130859375,
              37.91820111976663
            ],
            [
              -87.34130859375,
              36.90597988519294
            ]
          ]
        ]
      }
    }
  ]
}; 
var pts = {
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "marker-color": "#7e7e7e",
        "marker-size": "medium",
        "marker-symbol": "",
        "id": "one",
        "animal": "bear"
      },
      "geometry": {
        "type": "Point",
        "coordinates": [
          -86.72607421875,
          38.77121637244273
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "marker-color": "#7e7e7e",
        "marker-size": "medium",
        "marker-symbol": "",
        "id": "one",
        "animal": "fish"
      },
      "geometry": {
        "type": "Point",
        "coordinates": [
          -86.583251953125,
          38.487994609214795
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "marker-color": "#7e7e7e",
        "marker-size": "medium",
        "marker-symbol": "",
        "id": "two",
        "animal": "tiger"
      },
      "geometry": {
        "type": "Point",
        "coordinates": [
          -84.276123046875,
          38.38472766885085
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "marker-color": "#7e7e7e",
        "marker-size": "medium",
        "marker-symbol": "",
        "id": "two",
        "animal": "lizard"
      },
      "geometry": {
        "type": "Point",
        "coordinates": [
          -85.067138671875,
          38.70265930723801
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "marker-color": "#7e7e7e",
        "marker-size": "medium",
        "marker-symbol": "",
        "id": "three",
        "animal": "dog"
      },
      "geometry": {
        "type": "Point",
        "coordinates": [
          -83.880615234375,
          37.483576550426996
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "marker-color": "#7e7e7e",
        "marker-size": "medium",
        "marker-symbol": "",
        "id": "three",
        "animal": "horse"
      },
      "geometry": {
        "type": "Point",
        "coordinates": [
          -85.93505859374999,
          37.709899354855125
        ]
      }
    }
  ]
};

var map = L.map("map", {
    center: [37.5, -85], 
  zoom: 7
});
L.tileLayer("http://{s}.tile.osm.org/{z}/{x}/{y}.png").addTo(map);

var defaultStyle = {
  fillColor: "whitesmoke", 
  color: "#171717", 
  fillOpacity: 1, 
  weight: 1
};

// create polygon geojson, add to map 
var polyJson = L.geoJson(polys, defaultStyle).addTo(map);

// empty layer group to add markers to 
var layerGroup = L.layerGroup();

// loop through polygon layers for events
polyJson.eachLayer(function(layer){

    // zoom to bbox on each polygon click
    layer.on("click", function(e){
    var bbox = e.target.getBounds();
    var sw = bbox.getSouthWest();
    var ne = bbox.getNorthEast();
    map.fitBounds([sw, ne]);

    // the clicked polygon identifier 
    var clickedPoly = e.target.feature.properties.polygon;

    // pts added to map when they match the clickedpoly id
    L.geoJson(pts, {
        pointToLayer: function(feature, latlng){
        if(feature.properties.id === clickedPoly){

           var clicked = L.circleMarker(latlng, { 
             color: "red"
           }).addTo(map).addTo(layerGroup);
        }
      }
    });
  });
});

polyJson.on("click", function(){
    if(map.hasLayer(layerGroup)){
    map.removeLayer(layerGroup);
  }else{
    map.addLayer(layerGroup);
    //layerGroup.removeLayers();
  }
});

在此示例中,根据代码块末尾的条件语句,每隔一次单击就会删除整个 layerGroup 点。但是每次新的单击都会继续将标记附加到图层组,因此每隔一次单击就会显示所有选定的标记。

我倾向于让每个标记“组”由它们所在的多边形命名,因此当显示的标记与当前单击的多边形 ID 不匹配时,它们将从地图和 layerGroup 中删除。我在 R 中与 Leaflet 进行了广泛的合作,但我不确定如何在 JS 中实现这一点(或者不同语言中的逻辑是否相同)。我无法手动定义每一层,因为我将遍历许多动态加载的多边形和点。

【问题讨论】:

    标签: javascript leaflet


    【解决方案1】:

    用所需点填充图层的一种简单方法是:

    • 将您的layerGroup 设为永久层,
    • empty this layer 当用户点击带有layerGroup.clearLayers() 的多边形时
    • 用有效标记(由filter property 确定)填充layerGroup,让Leaflet 处理标记而不干扰pointToLayer

    基本上,简化事情:)。

    例如:

    layer.on("click", function(e){
        var bbox = e.target.getBounds();
        var sw = bbox.getSouthWest();
        var ne = bbox.getNorthEast();
        map.fitBounds([sw, ne]);
    
        // the clicked polygon identifier 
        var clickedPoly = e.target.feature.properties.polygon;
    
        layerGroup.clearLayers();
        layerGroup.addLayer(L.geoJson(pts, {
            pointToLayer: function(feature, latlng){
                return L.circleMarker(latlng, { 
                    color: "red"
                });
            },
            filter: function (feature) {
                return feature.properties.id === clickedPoly;
            }
        }));
    });
    

    还有一个演示https://jsfiddle.net/3v7hd2vx/1147/

    【讨论】:

    • 太棒了!谢谢@nikoshr 那么pointToLayer 应该专门用于几何形状的样式吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-07
    • 1970-01-01
    • 2012-11-06
    • 2019-09-28
    • 1970-01-01
    • 1970-01-01
    • 2019-09-24
    相关资源
    最近更新 更多