2
votes

How do I group all the different L.geoJSON queries under a single L.control layerGroup? I can get it to work if the control shows every single queried L.geoJSON but when I try to group them it fails and when you toggle it displays nothing. When I add pointGroup = L.layerGroup... and CustomLayer.addOverlay... under pointCoordinates.push(geoJsonLayer) it displays the layers but each one is toggle-able.

enter image description here

jQuery.ajax({
    type: "GET",
    dataType: "json",
    url: "https://api.weather.gov/alerts?active=1&event=Red%20Flag%20Warning",
    error: function (err) { console.log(err)},
    success: function (data, status, xhr) {
        var pointCoordinates = [];
        var pointGroup;
        jQuery(data.features).each(function(index, el) {

            var zones = el.properties.affectedZones;

            // Iterate through each zone
            for (var i = 0; i < zones.length; i++) {
                jQuery.ajax({
                    type: "GET",
                    dataType: "json",
                    url: zones[i],
                    error: function (err) { console.log(err)},
                    success: function (results, status, xhr) {
                        var geoJsonLayer = L.geoJson(results, {
                            style: function (feature) {
                                return {color: '#ed1a39', weight: '1'};
                            }
                        });
                        pointCoordinates.push(geoJsonLayer);
                    }
                })
            }
        });
        pointGroup = L.layerGroup(pointCoordinates).addTo(map);
        CustomLayer.addOverlay(pointGroup, "Red Flag Warning(s)");
        jQuery("#red-flag-events").html(data.features.length);
    }
})

Map Javascript:

jQuery(document).ready(function($) {
    var point = [];
    var pointGroup;
    L.mapbox.accessToken = 'pk.eyJ1IjoidGhlcHJlcGFyZWRsaWZlIiwiYSI6ImNqZzh3ZWptOTI3ZWozM2xvcjY1YzFtNHUifQ.UchKM7tZByT6mZTxqMlaSQ';
    map = L.mapbox.map('map', 'mapbox.light')
        .setView([40, -100], 4)
        .addControl(L.mapbox.geocoderControl('mapbox.places', {
                keepOpen: false
    }));
    var overlays = {

    };
    CustomLayer = L.control.layers(null, overlays, { collapsed: false }).addTo(map);
    fnWildlandFires();
});

Unfortunately no data is passed when I group them under pointGroup and try to pass it as a L.layerGroup.

enter image description here

1

1 Answers

1
votes

Make sure you understand How do I return the response from an asynchronous call?

In your case, when you assign your pointGroup a Layer Group from your pointCoordinates array, the latter is still empty, i.e. none of your AJAX requests had time to complete and push anything into it.

By default JavaScript is not reactive, so when your AJAX requests eventually complete, they do push something into pointCoordinates, but that does not update pointGroup.

A very easy solution however would be to build your pointGroup in outer scope as a Layer Group beforehand, and to add the GeoJSON Layer Groups that you build in your AJAX requests callback directly into that pointGroup, instead of using an intermediary plain array.

When you add them to the Layer Group, Leaflet will also update the map accordingly.

var map = L.map('map').setView([38, -100], 3);

//var point = [];
var pointGroup = L.layerGroup().addTo(map); // Build the Layer Group in outer scope and beforehand.
var overlays = {
  "Red Flag Warning(s)": pointGroup
};

CustomLayer = L.control.layers(null, overlays, {
  collapsed: false
}).addTo(map);

jQuery.ajax({
  type: "GET",
  dataType: "json",
  url: "https://api.weather.gov/alerts?active=1&event=Red%20Flag%20Warning",
  error: function(err) {
    console.log(err)
  },
  success: function(data, status, xhr) {
    //var pointCoordinates = [];
    //var pointGroup;
    jQuery(data.features).each(function(index, el) {

      var zones = el.properties.affectedZones;

      // Iterate through each zone
      for (var i = 0; i < zones.length; i++) {
        jQuery.ajax({
          type: "GET",
          dataType: "json",
          url: zones[i],
          error: function(err) {
            console.log(err)
          },
          success: function(results, status, xhr) {
            var geoJsonLayer = L.geoJson(results, {
              style: function(feature) {
                return {
                  color: '#ed1a39',
                  weight: '1'
                };
              }
            }).addTo(pointGroup); // Add directly to the Layer Group.
            //pointCoordinates.push(geoJsonLayer);
          }
        })
      }
    });
    //pointGroup = L.layerGroup(pointCoordinates).addTo(map);
    //CustomLayer.addOverlay(pointGroup, "Red Flag Warning(s)");
  }
});

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/[email protected]/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<script src="https://unpkg.com/[email protected]/dist/leaflet-src.js" integrity="sha512-GosS1/T5Q7ZMS2cvsPm9klzqijS+dUz8zgSLnyP1iMRu6q360mvgZ4d1DmMRP2TDEEyCT6C16aB7Vj1yhGT1LA==" crossorigin=""></script>
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>

<div id="map"></div>