对地图框中的标记进行多重过滤

Multiple Filtering on markers in mapbox

本文关键字:过滤 地图      更新时间:2023-09-26

我正在尝试在mapbox中加载geojson数据,我想在其中使用标记上的复选框应用多个过滤。我尝试查看这里给出的示例:https://www.mapbox.com/mapbox.js/example/v1.0.0/non-exclusive-markers/

因此,此处的筛选基于每个标记的运行状况和资产代码。无论是"正常"、"警告"、"已停止"还是"123125"、"123135"、"123145"。该代码用于加载地图,并根据其运行状况的颜色放置标记。过滤器菜单还获取六个过滤器选项。但是,当选择具有相同标记的两个过滤器时,标记会从屏幕上消失。

例如,选择"123125",然后选择"警告"时。黄色标记出现在屏幕上,但当取消选择任何一个过滤器时,它会消失。我不知道如何防止这种情况。"123135"、"已停止"和"123145"、"健康"也会发生同样的事情。

请查看下面的代码并帮助我。

<script src='https://code.jquery.com/jquery-1.11.0.min.js'></script>
<script src="/js/leaflet-0.7.2/leaflet.ajax.min.js"></script>
<script>
L.mapbox.accessToken = 'pk.eyJ1IjoiZG9zcyIsImEiOiI1NFItUWs4In0.-9qpbOfE3jC68WDUQA1Akg';
var map = L.mapbox.map('map', 'mapbox.streets');
var featureLayerGeoJSON = {
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "title":"Volkswagen Group",
        "healthy":false,
        "warning":true,
        "stopped":false,
        "marker-color":"#FFFF00",
        "marker-size":"medium",
        "Asset_Code": "123125",
        "Health_Code": "Warning"
      },
      "geometry": {
       "type": "Point",
       "coordinates":  [ -43.172502,-22.965881 ]
    }
    },
    {
      "type": "Feature",
      "properties": {
        "title":"Volkswagen Group",
        "healthy":false,
        "warning":true,
        "stopped":false,
        "marker-color":"#FF0000",
        "marker-size":"medium",
        "Asset_Code": "123135",
        "Health_Code": "Stopped"
      },
      "geometry": {
       "type": "Point",
       "coordinates":  [ -8.990956,38.581054 ]
    }
    },
    {
      "type": "Feature",
      "properties": {
        "title":"Volkswagen Group",
        "healthy":false,
        "warning":true,
        "stopped":false,
        "marker-color":"#1EB01E",
        "marker-size":"medium",
        "Asset_Code": "123145",
        "Health_Code": "Healthy"  
      },
      "geometry": {
       "type": "Point",
       "coordinates":  [ 139.740667,35.626567 ]
    }
    }
  ]
};
map.featureLayer.setGeoJSON(featureLayerGeoJSON);
// Find and store a variable reference to the list of filters.
var filters = document.getElementById('filters');
// Wait until the marker layer is loaded in order to build a list of possible
// types. If you are doing this with another featureLayer, you should change
// map.featureLayer to the variable you have assigned to your featureLayer.
var makeCheckboxes1 = function() {
  // Collect the types of symbols in this layer. you can also just
  // hardcode an array of types if you know what you want to filter on,
  // like var types = ['foo', 'bar'];
  var typesObj = {}, types = [];
  map.featureLayer.eachLayer(function (entity) {
    typesObj[entity.feature.properties['Asset_Code']] = true;
  })
  for (var k in typesObj) types.push(k);
  var checkboxes = [];
  // Create a filter interface.
  for (var i = 0; i < types.length; i++) {
    // Create an an input checkbox and label inside.
    var item = filters.appendChild(document.createElement('div'));
    var checkbox = item.appendChild(document.createElement('input'));
    var label = item.appendChild(document.createElement('label'));
    checkbox.type = 'checkbox';
    checkbox.id = types[i];
    checkbox.checked = true;
    // create a label to the right of the checkbox with explanatory text
    label.innerHTML = types[i];
    label.setAttribute('for', types[i]);
    // Whenever a person clicks on this checkbox, call the update().
    checkbox.addEventListener('change', update);
    checkboxes.push(checkbox);
  }
  // This function is called whenever someone clicks on a checkbox and changes
  // the selection of markers to be displayed.
  function update() {
    var enabled = {};
    // Run through each checkbox and record whether it is checked. If it is,
    // add it to the object of types to display, otherwise do not.
    for (var i = 0; i < checkboxes.length; i++) {
      if (checkboxes[i].checked) enabled[checkboxes[i].id] = true;
    }
    map.featureLayer.setFilter(function(feature) {
      // If this symbol is in the list, return true. if not, return false.
      // The 'in' operator in javascript does exactly that: given a string
      // or number, it says if that is in a object.
      // 2 in { 2: true } // true
      // 2 in { } // false
      return (feature.properties['Asset_Code'] in enabled);
    });
  }
}
var makeCheckboxes2 = function() {
  // Collect the types of symbols in this layer. you can also just
  // hardcode an array of types if you know what you want to filter on,
  // like var types = ['foo', 'bar'];
  var typesObj = {}, types = [];
  map.featureLayer.eachLayer(function (entity) {
    typesObj[entity.feature.properties['Health_Code']] = true;
  })
  for (var k in typesObj) types.push(k);
  var checkboxes = [];
  // Create a filter interface.
  for (var i = 0; i < types.length; i++) {
    // Create an an input checkbox and label inside.
    var item = filters.appendChild(document.createElement('div'));
    var checkbox = item.appendChild(document.createElement('input'));
    var label = item.appendChild(document.createElement('label'));
    checkbox.type = 'checkbox';
    checkbox.id = types[i];
    checkbox.checked = true;
    // create a label to the right of the checkbox with explanatory text
    label.innerHTML = types[i];
    label.setAttribute('for', types[i]);
    // Whenever a person clicks on this checkbox, call the update().
    checkbox.addEventListener('change', update);
    checkboxes.push(checkbox);
  }
  // This function is called whenever someone clicks on a checkbox and changes
  // the selection of markers to be displayed.
  function update() {
    var enabled = {};
    // Run through each checkbox and record whether it is checked. If it is,
    // add it to the object of types to display, otherwise do not.
    for (var i = 0; i < checkboxes.length; i++) {
      if (checkboxes[i].checked) enabled[checkboxes[i].id] = true;
    }
    map.featureLayer.setFilter(function(feature) {
      // If this symbol is in the list, return true. if not, return false.
      // The 'in' operator in javascript does exactly that: given a string
      // or number, it says if that is in a object.
      // 2 in { 2: true } // true
      // 2 in { } // false
      return (feature.properties['Health_Code'] in enabled);
    });
  }
}
makeCheckboxes1();
makeCheckboxes2();
</script>
<style>
 body { margin:0; padding:0; }
  #map { position:absolute; top:0; bottom:0; width:100%; }
.filter-ui {
  background:#fff;
  position:absolute;
  top:10px;
  right:10px;
  z-index:100;
  padding:10px;
  border-radius:3px;
  }
</style>
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Multiple filters on markers</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.mapbox.com/mapbox.js/v2.3.0/mapbox.js'></script>
<link href='https://api.mapbox.com/mapbox.js/v2.3.0/mapbox.css' rel='stylesheet' />
</head>
<body>  
  <nav id='filters' class='filter-ui'>
    <h4 align='center'>Filter based on Health</h4>
  </nav>
  <div id='map'></div>
</body>
</html>

请帮我解决这个问题。

您在代码中定义了两个追加函数;

checkboxes.push(checkbox); //this is first when makeCheckboxes1() call.
checkboxes.push(checkbox); //this is first when makeCheckboxes2() call.

当复选框列表为空时,它将清除所有部分。您需要创建一个包含这两个列表的复选框对象,然后可以追加。

小提琴示例

问题:现在您有重复的对象。您需要控制类型,如果存在,请不要将对象推送到类型。