【问题标题】:How to clear leaflet layer after click点击后如何清除传单层
【发布时间】:2020-03-25 18:23:05
【问题描述】:

我尝试使用鼠标单击来选择/取消选择图层。首先我的地图是这样的

点击一个图层后,我想选择它并突出显示

现在,如果我再次单击之前选择的图层,我想取消选择它并重置高亮。这是我用来执行此操作的代码:

  onEachFeature: function(feature,layer) {

      layer.setStyle({fillOpacity: 0.0 , color: '#424a44', weight: 2});
      layer.on('click', function(e) {

      let isLayerAlreadySelected =  // Some logic to undestand if layer alreeady selected

      if(isLayerAlreadySelected) 
         layer.setStyle({fillOpacity: 0.0 , color: '#424a44', weight: 2});
      else
          layer.setStyle({fillOpacity: 0.4 , color: '#004691', weight: 3});
      }

  }

但有时当我尝试取消选择先前选择的图层时,图层样式不会重置不透明度。对此有何建议?

【问题讨论】:

  • 你能创建 stackblitz 吗?

标签: javascript angular leaflet


【解决方案1】:

您只需使用resetStyle() 方法即可将给定矢量图层的样式重置为原始GeoJSON 样式。

var map = L.map('map').setView([37.8, -96], 4);

	L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
		maxZoom: 18,
		attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
	}).addTo(map);




	// get color depending on population density value
	function getColor(d) {
		return d > 1000 ? '#800026' :
				d > 500  ? '#BD0026' :
				d > 200  ? '#E31A1C' :
				d > 100  ? '#FC4E2A' :
				d > 50   ? '#FD8D3C' :
				d > 20   ? '#FEB24C' :
				d > 10   ? '#FED976' :
							'#FFEDA0';
	}

	function style(feature) {
		return {
			weight: 2,
			opacity: 1,
			color: 'white',
			dashArray: '3',
			fillOpacity: 0.7,
			fillColor: getColor(feature.properties.density)
		};
	}

	function highlightFeature(e) {
    geojson.resetStyle();
		var layer = e.target;

		layer.setStyle({
			weight: 5,
			color: '#666',
			dashArray: '',
			fillOpacity: 0.7
		});

		if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
			layer.bringToFront();
		}

	}

	var geojson;

	function resetHighlight(e) {
		geojson.resetStyle(e.target);
	}

	function zoomToFeature(e) {
		map.fitBounds(e.target.getBounds());
	}
    // Set style function that sets fill color property
function style(feature) {
    return {
        fillColor: '#004691', 
        fillOpacity: 0.5,  
        weight: 1,
        opacity: 1,
        color: '#424a44',
        dashArray: '1'
    };
}
	var highlight = {
		'fillColor': 'yellow',
		'weight': 1,
		'opacity': 1
	};

	function onEachFeature(feature, layer) {
		layer.on({
			
			click: highlightFeature
		});
        
	}

	geojson = L.geoJson(statesData, {
		style: style,
		onEachFeature: onEachFeature
	}).addTo(map);
#map {
         width: 600px;
         height: 400px;
         }
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" crossorigin=""/>
    <script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"crossorigin=""></script>
      
       <div id='map'></div>
      <script type="text/javascript" src="https://leafletjs.com/examples/choropleth/us-states.js"></script>

您可以参考thisthis 了解更多信息。

希望对你有帮助。

【讨论】:

    【解决方案2】:

    首先,您可以通过使用 Leaflet GeoJSON factory style 选项设置您的“基本”样式来稍微简化您的代码。这样,您的高亮功能可以使用 Leaflet GeoJSON Layer Group resetStyle() 方法方便地重置样式:

    let selected = false;
    
    function onEachFeature(feature, layer) {
      layer.on("click", function() {
        selected = !selected;
        if (selected) {
          layer.setStyle({
            fillOpacity: 0.4,
            color: '#004691',
            weight: 3
          });
        } else {
          geojsonLayerGroup.resetStyle(layer);
        }
      });
    }
    
    const map = L.map('map').setView([48.86, 2.35], 11);
    
    const geojsonData = {
      "type": "Feature",
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [2.35, 48.88],
            [2.32, 48.84],
            [2.38, 48.84],
            [2.35, 48.88]
          ]
        ]
      },
      "properties": {}
    };
    
    const geojsonLayerGroup = L.geoJSON(geojsonData, {
      onEachFeature: onEachFeature,
      style: {
        fillOpacity: 0.0,
        color: '#424a44',
        weight: 2
      }
    }).addTo(map);
    
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);
    html,
    body,
    #map {
      height: 100%;
      margin: 0;
    }
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin="" />
    <script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js" integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew==" crossorigin=""></script>
    
    <div id="map"></div>

    现在从您的 cmets 看来,您可能会遇到 Angular 区域的有趣麻烦。发生在 Angular Zone 之外的动作可能不会被浏览器绘制。

    如果您尝试取消选择图层但似乎没有任何反应,请在浏览器的其他位置尝试其他操作:单击其他位置,调整窗口大小等。如果取消选择突然触发,则很可能是 Angular Zone 的影响.

    【讨论】:

      【解决方案3】:

      您可以通过颜色和/或权重进行检查,这意味着您必须覆盖当前的高亮行为(悬停,即鼠标悬停和鼠标悬停)行为,以便您可以区分点击时的行为。这将意味着做类似的事情

      function onEachFeature(feature, layer) {
          layer.on({
              mouseover: highlightFeature,
              mouseout: resetHighlight,
              click: selectLayer
          });
      }
      

      那么 selectLayer 将是

      function selectLayer(e) {
            let isLayerAlreadySelected =  ((e.target.options.color === '#004691') &&(e.target.options.weight === 3))
      
            if(isLayerAlreadySelected) 
               layer.setStyle({fillOpacity: 0.0 , color: '#424a44', weight: 2});
            else
                layer.setStyle({fillOpacity: 0.4 , color: '#004691', weight: 3});
      }
      

      这意味着highlightFeature如下

      //Here you should set the highlight features different from when its clicked particularly take note of your wight and color since its what we use for the logic.
      function highlightFeature(e) {
          let layer = e.target;
      
          layer.setStyle({
              weight: 1,
              color: '#666',
              fillOpacity: 0.1
          });
      
      }
      

      同样resetHighlight会像

      //basically you will be putting the styles to their default here what ever values you choosed as default
      function resetHighlight(e) {
          let layer = e.target;
      
          layer.setStyle({
              weight: 0,
              color: '#424a44',
              fillOpacity: 0
          });
      
      }
      

      您可能会发现此文档很有用 leaflet layer

      【讨论】:

        【解决方案4】:

        您可以更喜欢交换鼠标事件函数来执行高亮层的选择

        layer.setStyle({
                            fillColor: getRandomColor(),
                            fillOpacity: 0.50,
                            stroke: false
                        });
                        layer.on('mouseover', function(e) {
                   highlightFeature(e);
          //open popup;
            var popup = L.popup()
           .setLatLng(e.latlng)
           .setContent(feature.properties.Name)
           .openOn(mymap);
        
           });
              layer.on('mouseout', function(e) {
                   defaultFeature(e);
          //open popup;
            var popup = L.popup()
           .setLatLng(e.latlng)
           .setContent(feature.properties.Name)
           .openOn(mymap);
            });
        

        defaultfeature() 被定义为执行取消选择

        function getRandomColor() {
          var letters = '0123456789ABCDEF';
          var color = '#';
          for (var i = 0; i < 6; i++) {
            color += letters[Math.floor(Math.random() * 16)];
          }
          return color;
        }
        
        
        function highlightFeature(e) {
            highlightLayer = e.target;
            if (e.target.feature.geometry.type === 'LineString') {
              highlightLayer.setStyle({
                color: '#ffff00',
              });
            } else {
              highlightLayer.setStyle({
                fillColor: getRandomColor(),
                fillOpacity: .25
              });
            }
        }
        function defaultFeature(e) {
        
            if (e.target!=null) {
              highlightLayer.setStyle({
                color: getRandomColor(),
                fillOpacity:.50
              });
            } else {
              highlightLayer.setStyle({
                fillColor: highlightFeature(),
                fillOpacity: .25
              });
            }
        }
        

        【讨论】:

          【解决方案5】:

          您可以测试图层的颜色:

          onEachFeature: function(feature,layer) {
          
                layer.setStyle({fillOpacity: 0.0 , color: '#424a44', weight: 2});
                layer.on('click', function(e) {
          
                    let isLayerAlreadySelected =  e.target.options.color === '#004691';
          
                    if(isLayerAlreadySelected) 
                       e.target.setStyle({fillOpacity: 0.0 , color: '#424a44', weight: 2});
                    else
                       e.target.setStyle({fillOpacity: 0.4 , color: '#004691', weight: 3});
          
               });
          }
          

          【讨论】:

          • 我测试了你所说的,但有时我看到选择的图层也是突出显示的 layer.options.color 是 #424a44
          • 对不起,你必须使用e.target.options.color,我更新了答案
          • 同样的问题 :(
          • 这不是系统性错误,但它仍然经常发生
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-14
          • 2023-02-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多