Tutorial: Live earthquake map

This tutorial goes through the earthquake map. The earthquake map takes a live feed from USGS (United states geological survey) and displays the earthquakes as scaled markers in a Leaflet map. Compared to the previous maps we have worked with this one has some new features. Read this if you want to learn the following concepts. If you simply want to reuse the existing map just go to this link and copy the iframe code.

  • Custom scaled markers (based on earth quake magnitude)
  • It uses an external data feed

HTML request for loading external data

The biggest difference from previous maps such as the news map is that this map loads an external data feed. In this case the map will load a geojson with up to date information about recent earthquakes in the world. You can choose what recent period you want the collection of earthquakes from, and how powerful they will be by choosing the feed you want from USGS. You can choose a period from the past hour or as far as 30 days back. You can also choose what strength (earthquake magnitude) you want in your feed.

In order to load this feed into our map application we have to set up an html request. The html request loads external data in to our leaflet app.

var xhr = new XMLHttpRequest();
            xhr.onload = function () {
                var results = JSON.parse(xhr.responseText);
                layerGroup.addData(results);
                document.getElementById("mapTitle").innerText = results.metadata.title;
                document.getElementById("mapDescription").innerText = "Click on an earthquake to see more details";
            };
            xhr.open('GET', FEED, true);
            xhr.send();

The code above can be found in the complete file. This code sets up a new XMLHttpRequest object and it also sets up a function that is to run once the data has loaded. This is specified with the .onload function that you can read more about on developer.mozilla.org. The last part is important because if you set that function to run immediately there is a good chance the data will not have been loaded when the function is run, and wothout any data to work with the function will fail and nothing will be shown on our map.

Read more about XMLHttpRequest on w3schools

When the data is loaded it will be added to a layerGroup that was made before the html request. The layerGroup is an instance of a leaflet geojson object. You can read more about the leaflet geosjon object on leafletjs.com. The short version is that the geojson object can parse (read) the geojson data and add the features to a map.

The creation of the geojson object

The Leaflet geojson object was created before the html request and has been waiting for something to do, until now. As soon as the on loaded function runs the geosjon object will start generating map features from the loaded data. Let’s look at the code for that starting on line 152.

var layerGroup = L.geoJSON([], {
                onEachFeature: function (feature, layer) {
                    var props = feature.properties;

The three lines above are only the start of the geojson object. You can see that we are creating a Leaflet geojson object called layerGroup. The next line in with the onEachFeature method will go through every geojson feature in the data and do some stuff to make it appear on the map. The first thing it does is to set the props object to contain all the properties of that feature. Remember that you can place your own data inside the properties object of any geojson feature. This can be useful for example if you want to display a map with a lot of data. Place the data for each map location inside the features properties object. A future article might cover this topic in more detail, for now lets move on.

Adding a custom marker

var quakeIcon = new L.Icon({

Earthquakes should not look like pins. The visual marker needs to give visual ques as to what is happening below the ground. I made this icon to use as a custom marker. It does the job but at certain sizes there is some interference between the rings of the marker. I think this will happen at some point not matter how the marker is designed so it will have to do.

The marker needs to be published on the same server as the html for this to work. If you are using WordPress the url might look similar to this:

iconUrl: 'https://gauteheggen.com/wp-content/uploads/quakeIcon3.png',

If you upload your image via ftp a relative url from the html page might look like this:

/iconUrl: 'img/quakeIcon3.png',

Magnitude scale and spaghetti visualization of earthquakes.

I was trying to figure out how to scale my earthquake markers and was searching the internet for clues. Technically the markers are similar to bubble markers, but the scale is different in this case. When setting setting the radius of a bubble marker you should always use the square root of the value so the area of the marker is proportional to the value. But that applies to numbers on a linear scale and the earthquake magnitude is not a linear scale, it is logarithmic. You can read more about the earthquake magnitude scale on livescience.com. Here is a video that explores the same topic with spaghetti.

So an increase in magnitude from 6.0 to 7.0 represents a 33 time increase in strength meaning that two steps on the scale represents 1089 times increase in strength. How do we scale markers on a map with such enormous differences in strength?

There is no absolute correct way to do this. The magnitude scale measures the power output for eartquakes. We are trying to communicate that force by placing and scaling a round, flat graphic on a flat map based on a a non linear scale. The values in the scale might vary depending on what feed you choose from USGS, and that is also ou might want to consider when choosing a scale factor for your map.

At the same time using the numbers from the scale will simply be to flat as an increase from 6.0 to 7.0 should be represented by a larger increase in marker radius than just 16,66%. I tried to set the magnitude value to the power of 2 and 3 but have not yet decided what I think works best. The code that does the scaling is defined in the objects for quakeIcon and highlighIcon and can be found between line 161 and 180.

 iconSize:     [((Math.pow(props.mag, 2)) * bubbleRadiusMultiplier), ((Math.pow(props.mag, 2)) * bubbleRadiusMultiplier)]

You can read more about the Math.pow function on MDN or W3schools. If you are interested you can also try other functions in the Math object as well on either MDN or W3schools.

Since both the numerical magnitude scale and the actual strength it represents are unsuitable as a basis for scaling these markers it boils down to a design choice of what we think communicates well. Raising the magnitude value to the power of 2 or 3 might be ok, but it also depends on the earthquake feed we choose. USGS has several feeds where you can choose to include or exclude earthquakes with low strength and you can choose how far back in time you want quakes. Depending on the feed you can try to alter the code scaling the markers.