0

I have Esri Leaflet feature layers representing traffic accidents in multiple cluster marker groups. The cluster marker groups are created based on attributes that specify the geographic areas to which each feature belongs - they must be separate to ensure that features from different administrative boundaries are not clustered together. (There are only three different countries in this example, but eventually the same data at 51 different geographic areas will be shown at other zoom levels).

The user needs to be able to filter the data to show various accident severity levels. As long as a filter is set on a single feature layer, the filter displays the expected results. But when the filter is set on multiple feature layers, I experience multiple issues.

In the example below:

  • From the initial zoom, if 'fatal' is chosen as a severity level, I expect five features in England and two Scotland. Instead, 13 are shown in England (in two clusters) and one is shown in Scotland.

  • If 'serious' is chosen as severity level, the correct number of total features are shown (96), but they are in a single cluster rather than three different clusters (one per country).

I also tried using the setWhere() method of the esri-leaflet feature layer on each layer of a layer group, but the results were the same.

Is it possible to get correct results from a filter in this situation?

<!DOCTYPE html>
<html>
  <head>
    <!-- Load Leaflet -->
    <link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css"/>
    <script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>

    <!-- Load Esri Leaflet -->
    <script src="https://unpkg.com/esri-leaflet/dist/esri-leaflet.js"></script>

    <!-- Load Leaflet MarkerCluster and Esri Leaflet Cluster from CDN -->
    <link rel="stylesheet" type="text/css"
      href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.Default.css"
      integrity="sha512-BBToHPBStgMiw0lD4AtkRIZmdndhB6aQbXpX7omcrXeG2PauGBl2lzq2xUZTxaLxYz5IDHlmneCZ1IJ+P3kYtQ=="
      crossorigin="">
    <link rel="stylesheet" type="text/css" href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.css"
      integrity="sha512-RLEjtaFGdC4iQMJDbMzim/dOvAu+8Qp9sw7QE4wIMYcg2goVoivzwgSZq9CsIxp4xKAZPKh5J2f2lOko2Ze6FQ=="
      crossorigin="">
    <script src="https://unpkg.com/leaflet.markercluster@1.4.1/dist/leaflet.markercluster.js"
      integrity="sha512-MQlyPV+ol2lp4KodaU/Xmrn+txc1TP15pOBF/2Sfre7MRsA/pB4Vy58bEqe9u7a7DczMLtU5wT8n7OblJepKbg=="
      crossorigin=""></script>
    <script src="https://unpkg.com/esri-leaflet-cluster@2.0.1/dist/esri-leaflet-cluster.js"
      integrity="sha512-2/Nwrks+A2omjKeWrF4TKFLIrUbAhSl8EDEm6xunuwXXYqMoJI71PZtlW0/vqt9d3DOyP1md/bzAnNH2KuAhaQ=="
      crossorigin=""></script>

    <div id="query" class="leaflet-bar">
      <label>
        Severity: 
        <select id="severity">
          <!-- make sure to encase string values in single quotes for valid sql -->
          <option value="1=1">Any</option>
          <option value="Accident_S=1">Fatal</option>
          <option value="Accident_S=2">Serious</option>
          <option value="Accident_S=3">Slight</option>
        </select>
      </label>
    </div>

    <style>
      html, body, #map {
        margin:0; padding:0;  width : 100%; height : 100%;
      }
        #query {
        position: absolute;
        top: 10px;
        right: 10px;
        z-index: 1000;
        background: white;
        padding: 1em;
      }
      #query select {
        font-size: 16px;
        float: right;
      }
      #severity {
        float: left
      }
      #reference {
        float: right;
        margin-right: 50px;
      }
    </style>
  </head>
  <body>
    <div id="map"></div>
    <script>
      var map = L.map('map').setView([54, -3.5], 6);
      L.esri.basemapLayer("Streets").addTo(map);

      var accidentsUrl = 'https://services5.arcgis.com/BMaSVn3J8DvKdFzq/arcgis/rest/services/accidents_2018_0730/FeatureServer/0';

      var accidents = L.esri.Cluster.featureLayer({
        url: accidentsUrl
      });

      var accidentsEngland =  L.esri.Cluster.featureLayer({
            url: accidentsUrl,
            where: "Country = 'England'",
            maxClusterRadius: 500,
        }).addTo(map);

    var accidentsScotland =  L.esri.Cluster.featureLayer({
            url: accidentsUrl,
            where: "Country = 'Scotland'",
            maxClusterRadius: 400,
        }).addTo(map);

    var accidentsWales =  L.esri.Cluster.featureLayer({
            url: accidentsUrl,
            where: "Country = 'Wales'",
            maxClusterRadius: 300,
        }).addTo(map);

    var severity = document.getElementById('severity');
    severity.addEventListener('change', function() {
    // attempt to set filter on multiple feature layers
    accidentsEngland.setWhere(severity.value);
    accidentsScotland.setWhere(severity.value);
    accidentsWales.setWhere(severity.value);
    });

    </script>
  </body>
</html>

1

I had not realized that the setWhere() method resets an existing filter. Though a filter was set with one condition when each feature layer was created, all desired conditions have to be included when setWhere() is called.

The desired results are produced upon rewriting these lines in the example in the question.

    severity.addEventListener('change', function() {
    // reset filter feature layers
    accidentsEngland.setWhere(severity.value + " and Country = 'England'");
    accidentsScotland.setWhere(severity.value + " and Country = 'Scotland'");
    accidentsWales.setWhere(severity.value + " and Country = 'Wales'");
    });
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.