#StandWithUkraine - Stop the Russian invasion

Join us and donate. We are contributing all book royalties from 2022 to present 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.43 shows an interactive map of Hawaii, colored by seismic hazard risk, along with locations of volcanoes and large hotels.

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

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

Note: Our original 2021 map showed hospital locations in North Dakota provided by Medicare.gov website. We updated the map in March 2022 when Medicare.gov replaced Socrata with a different database system, and instead we displayed AmeriCorps NCCC projects in North Dakota. We updated the map once again in August 2024 when the North Dakota database moved, and we now show large hotels, volcanos, and seismic hazards in Hawaii. Overall, these map revisions over time illustrate the dynamic nature of third-party data providers and web systems.

You can enable Leaflet to pull data from various ArcGIS services, including MapServer or FeatureServer, using a free esri-leaflet plugin. Data from regular JSON endpoints, such as USGS Volcano API or Socrata’s SODA API, can be pulled 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.43, 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:
$.getJSON('https://volcanoes.usgs.gov/vsc/api/volcanoApi/volcanoesUS', function(apiResults) {

    // Create an empty array to store Lefalet markers
    let volcanoMarkers = [];

    // Let's go through every element of the array returned by the Volcanoes API
    for (var i in apiResults) {

        // Let's only add volcanoes that are located around Hawaii
        if (apiResults[i].subregion === 'Hawaii') {

        // Extract coordinates from the volcano object
        var lat = apiResults[i].latitude;
        var lon = apiResults[i].longitude;

        // Create a Leaflet marker with a custom image
        var marker = L.marker([lat, lon], {
            icon: L.icon({
            iconUrl: 'images/volcano.png',
            iconSize: [24, 24],
            iconAnchor: [12, 12],
            opacity: 0.5
            })
        }).bindTooltip(apiResults[i].vName); // Add a tooltip with volcano name

        // Add our volcano marker to the array of all other markers
        volcanoMarkers.push(marker);

        }
    }

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

    // Add layer to the legend, together with the little icon
    legend.addOverlay(
        volcanoLayer,
        'Volcanoes <img src="images/volcano.png" height="13" alt="Volcano emoji">'
    )

})

The following code snippet uses esri-leaflet plugin to pull polygon data from an ArcGIS FeatureServer, and creates a choropleth layer based on the modelled hazard value stored in the low_cont variable of each polygon feature.

var seismicHazardLayer = L.esri.featureLayer({
    url: 'https://services1.arcgis.com/Hp6G80Pky0om7QvQ/ArcGIS/rest/services/Seismic_Ground_Motion_Hazards_with_2_5_or_10_Percent_Probability_in_50_years/FeatureServer/5',
    style: function(feature) {
        return {
            fillOpacity: 0.5,
            weight: 0, // the polygons are quite dense, so let's not draw boundaries
            fillColor: getHazardColor(feature.properties.low_cont)
        }
    }
}).addTo(map)

legend.addOverlay(seismicHazardLayer, 'Seismic hazard')

Here, the getHazardColor() function returns a color for a given value based on pre-defined thresholds. In our case, we define 5 buckets, assigning the darkest red to values over 1.5 (centered around the volcano in the middle of the largest Hilo island), and the palest red to the values of 0.2 and under.

var getHazardColor = function(d) {
    return d > 1.5   ? '#7a0177' :
            d > 1.0  ? '#c51b8a' :
            d > 0.5  ? '#f768a1' :
            d > 0.2  ? '#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 value field from low_cont to hazard_value, 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, 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 and polygon data from sources such as ArcGIS/Esri MapServer and JSON API endpoints, 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.