[GIS] Conditionally coloring specific country using Leaflet

javascriptleaflet

I have an offline Leaflet map, where the countries are drawn from a huge Javascript variable with coordinates.

index.html is as such(an example from codepen, I load the libraries locally):

<html>

<head>

  <title>Leaflet</title>

  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" />

  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" />
  <script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet.js"></script>

</head>

<body>

  <div id="mapid" style="width: 100%; height: 800px;"></div>

</body>

</html>

And Map.js is as such:

var map = L.map('mapid').setView([0, 0], 2);

// Huge geojson of every country, one country sample here. 
var countries =  "type": "FeatureCollection",
"features": [{
    "type": "Feature",
    "id": "AFG",
    "properties": {
        "name": "Afghanistan"
    },
    "geometry": {
        "type": "Polygon",
        "coordinates": [
            [
                [61.210817, 35.650072],
                [62.230651, 35.270664],
                [62.984662, 35.404041],
                [63.193538, 35.857166],
                [63.982896, 36.007957],
                [64.546479, 36.312073],
                [64.746105, 37.111818],
                [65.588948, 37.305217],
                [65.745631, 37.661164],
                [66.217385, 37.39379],
                [66.518607, 37.362784],
                [67.075782, 37.356144]
                // .... goes on
            ]
        ]
    }
}]};

L.geoJSON(countries, {
  style: function(feature) {
    return {
      fillColor: "#D3D3D3", // Default color of countries.
      fillOpacity: 1,
      stroke: true,
      color: "grey", // Lines in between countries.
      weight: 2
    };
  }
}).bindPopup(function(layer) {
  return layer.feature.properties.name;
}).addTo(map);

This produces a nice looking output, which can be seen here: http://codepen.io/anon/pen/zZNjBy

However, I wish to color potentially each country depending on an input. Let's say we open an object with the potential input:

let colorratio = {
    1:"green",
    2:"blue",
    3:"yellow",
    4:"red"
};

I then receive the following:

let colorinput = {
    AFG: "1",
    DNK: "2",
    SWE: "3",
    USA: "1"
};

Where we in layman's terms want to color Afghanistan green, color Denmark blue, Sweden yellow, and USA blue. The remaining countries should just stay at the default color value(greyish).

These abbreviations match the "ID" key in the countries variable.

My question therefore goes on how to approach this issue; Obviously, I need to match the keys in the huge GeoJSON file. But it's almost 13000 lines long.

Apart from that, in the L.geoJSON where we call the countries variable, we return a default color of countries. Where do I potentially access a key to color each country? Should this variable be moved into the countries variable for each country, as a key that is then overwritten?

I've tried looking at the Leaflet documentation and examples; but most assume that you retrieve tiles online, which is not a possibility here. It must work offline without contacting a CDN or similar – which poses some challenges, needless to say.

Best Answer

You already have all you need :

L.geoJSON(countries, {
  style: function(feature) {
    return {
      fillColor: colorratio[colorinput[feature.id]] || "#D3D3D3",
      fillOpacity: 1,
      stroke: true,
      color: "grey", // Lines in between countries.
      weight: 2
    };
  }
}).bindPopup(function(layer) {
  return layer.feature.properties.name;
}).addTo(map);

If the country is not in colorinput or if its color code is not in colorration, it will get default color.

It works in your codepen.