2

I have about 1000 polygons I'm load onto a map and I'm trying to color them based on a properties value. I have the code below which produces the following results.

mapLayerFieldGrid = new L.GeoJSON.AJAX("/../static/data/fields/field001.geojson", {style: styleFieldGrid});

mapLayerFieldGrid.eachLayer(function(layer) {
    if(layer.feature.properties.health == 1) {
      layer.setStyle({fillColor: plantHealth1});
    } else if(layer.feature.properties.health == 2) {
      layer.setStyle({fillColor: plantHealth2});
    } else if(layer.feature.properties.health == 3) {
      layer.setStyle({fillColor: plantHealth3});
    } else if(layer.feature.properties.health == 4) {
      layer.setStyle({fillColor: plantHealth4});
    } else if(layer.feature.properties.health == 5) {
    layer.setStyle({fillColor: plantHealth5});
    }
});


mapLayerFieldGrid.addTo(mapField);

enter image description here

The polygons are there but they aren't colored correctly. When I run the eachLayer function in the console I do get the right result, which looks like this.

enter image description here

So my question is why does this work in the console, but not when the page loads, and how do I correct this? Any help is greatly appreciated.

user2962197
  • 218
  • 2
  • 12

1 Answers1

3

The first "A" in "AJAX" is for Asynchronous.

After you instantiate your new L.GeoJSON.AJAX, you have a Leaflet GeoJSON Layer Group in your mapLayerFieldGrid variable, but it is still empty. Leaflet-ajax needs some time to fetch your GeoJSON data from the network (even locally). During this time, the rest of your script continues execution, so mapLayerFieldGrid.eachLayer works on an empty array of layers.

When you perform code execution in your console, leaflet-ajax had already time to retrieve your GeoJSON data and to fill your mapLayerFieldGrid layer group, so now mapLayerFieldGrid.eachLayer works on a non-empty array of layers.

You could either:

  1. Listen to the "data:loaded" event and execute your code in the event listener callback
  2. Perform the re-styling directly in the style option of the L.geoJSON factory (same for L.GeoJSON.AJAX), since you already use it.

In more details:

  1. Using the "data:loaded" event of L.GeoJSON.AJAX:
var mapLayerFieldGrid = new L.GeoJSON.AJAX(url, options).on("data:loaded", function () {
  mapLayerFieldGrid.eachLayer(function (layer) {
    // Perform some operations, re-styling, etc.
  });
});
  1. Using the style option: simply get some inspiration from the Leaflet choropleth map tutorial:
new L.GeoJSON.AJAX(url, {
  style: style
}).addTo(mapField);

function getColor(d) {
  return d === 1 ? plantHealth1 :
    d === 2 ? plantHealth2 :
    d === 3 ? plantHealth3 :
    d === 4 ? plantHealth4 :
    d === 5 ? plantHealth5 :
    defaultColor;
}

function style(feature) {
  return {
    fillColor: getColor(feature.properties.health),
    // Whatever values in your styleFieldGrid style.
    weight: 2,
    opacity: 1,
    color: 'white',
    dashArray: '3',
    fillOpacity: 0.7
  };
}
ghybs
  • 47,565
  • 6
  • 74
  • 99