#StandWithUkraine - Stop the Russian invasion

Join us and donate. All 2022 book royalties will be donated to:
Save Life in Ukraine and Ukraine Humanitarian Appeal.

Leaflet Maps with Open Data APIs

Learn how to code your own Leaflet map with an application programming interface (API) that continuously pulls the most current information directly from an open-data repository, similar to the Socrata Open Data map you learned about in Chapter 7. Leaflet maps can pull and display data from various open data repositories using APIs. Figure 12.40 shows an interactive map of North Dakota counties, colored by population density, with emergency medical service (EMS) locations and recent AmeriCorps projects.

Note: The original example showed hospital locations in North Dakota provided by Medicare.gov website. This example was modified on 23 March 2022 due to Medicare.gov replacing Socrata with a different database system. In this updated example, AmeriCorps NCCC projects in North Dakota are shown.

This map template pulls data from three different open repository sources:

Figure 12.40: Explore the interactive Leaflet Map with Open Data.

You can enable Leaflet to pull data from ArcGIS servers using a free esri-leaflet plugin. Data from Socrata can be pulled from SODA API using jQuery’s $.getJSON() function.

To adapt this template for your own project:

  1. Visit the GitHub repository that contains the code for the map in Figure 12.40, and press the Use this template button to copy the repo to your own GitHub account.
  2. All data is pulled form the code inside the <script> tag of index.html. To pull data from Socrata or another JSON/GeoJSON endpoint, modify the following code snippet with the appropriate URL and icon:
/*
  From AmeriCorps Socrata database, add projects in North Dakota
  using simple filtering on the `stabbr` column, and a JSON endpoint.
  Each point is a custom .png icon with a tooltip containing AmeriCorps
  sponsor name, and project description.
*/


$.getJSON("https://data.americorps.gov/resource/yie5-ur4v.json?stabbr=ND", function(data) {

  // Array of Leaflet markers
  var markers = [];
  
  // For each row in Socrata, create a Leaflet marker
  for (var i = 0; i < data.length; i++) {
    
    var item = data[i];

    // Extract coordinates for each project, convert strings to floats
    var coordinates = [
      parseFloat(item.geocoded_column.latitude),
      parseFloat(item.geocoded_column.longitude)
    ]

    // Create a marker with a custom icon
    var marker = L.marker(coordinates, {
        icon: L.icon({
          iconUrl: 'images/americorps.png',
          iconSize: [24, 24],
          iconAnchor: [12, 12],
          opacity: 0.5
        })
    }).bindTooltip(item.sponsor + '<br>' + item.project_description);

    // Add marker to the array of markers
    markers.push(marker);
  }

  // Create a Leaflet layer group from array of markers
  var layer = L.layerGroup(markers);
  layer.addTo(map); // add layer to the map

  // Add layer to the legend, together with the little icon
  legend.addOverlay(layer, 'AmeriCorps NCCC <img src="images/americorps.png" height="11" alt="AmeriCorps NCCC">')

})

The following code snippet uses esri-leaflet plugin to pull polygon data from an ArcGIS server, and creates a choropleth layer based on population density (stored in POP10_SQMI variable of each feature, or polygon).

var counties = L.esri.featureLayer({
  url:'https://ndgishub.nd.gov/arcgis/rest/services/All_GovtBoundaries/MapServer/20',
  style: function(feature) {
    return {
      fillOpacity: 0.5,
      weight: 0.5,
      color: 'silver',
      fillColor: getDensityColor(feature.properties.POP10_SQMI)
    }
  }
}).addTo(map)

Here, the getDensityColor() function returns a color for a given value based on pre-defined thresholds. In case of the North Dakota example, population density of over 100 people per square mile is assigned the darkest shade of red, while the density of 5 and under is shown with the lightest.

var getDensityColor = function(d) {
  return d > 100  ? '#7a0177' :
          d > 50  ? '#c51b8a' :
          d > 20  ? '#f768a1' :
          d > 5   ? '#fbb4b9' :
                    '#feebe2'
}

While it is convenient to pull data directly from the source databases, remember that those resources are out of your control (unless you administer them, of course). Data changes often come unannounced. For example, if the dataset owner decides to rename the population density field from POP10_SQMI to Pop10_sqmi, your map will stop showing values correctly. Datasets may get moved to a different domain name or get deleted entirely (we experienced both!), so it is wise to have a back-up file saved locally.

If you are more concerned about the long-term functioning of your map as opposed to displaying the most up-to-date version of the dataset, you may consider serving your data from local GeoJSON files instead (but ensure first that it is permitted by the data license).

Summary

In this chapter, we introduced Leaflet map templates for common map problems, such as telling stories about places using scrollable interface, showing point data from databases like Socrata, and creating heatmaps to visualize areas of high event density.

You can use these templates as a base to kickstart your own mapping projects. Leaflet.js is well-documented, and we recommend looking at their tutorials for more inspiration.

In the next chapter, we will talk about geospatial data and introduce several tools that can convert, create, and edit geospatial files.