Mapbox – Visualizing the earthquakes on world map

geo mapping earthquakes on world map

In this blog post, I will show you how to visualize earthquakes on a world map using Mapbox.

We have seen, how to render the world map on the browser using Mapbox service in of our previous blog post. We will extend the same code to visualize the earthquakes on the map.

Create react application using the steps mentioned in the linked post or you can clone the repo from GitHub.

We can obtain the earthquake information using the following URL provided by the U.S. Geological Survey.

https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&eventtype=earthquake&minmagnitude=2&starttime=2020-09-09T12:00:00.000Z

The information returned by URL is in the format of GeoJSON.

GeoJSON is a geospatial data interchange format based on JavaScript Object Notation (JSON). It defines several types of JSON objects and
the manner in which they are combined to represent data about geographic features, their properties, and their spatial extents.
GeoJSON uses a geographic coordinate reference system

GeoJSON supports Point, LineString, Polygon, MultiPoint, MultiLineString, and MultiPolygon geometry types.

Following JSON object represents a point on the map at given longitude and latitude

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        prop1: xx,
        prop2 : "yy"
      },
      "geometry": {
        "type": "Point",
        "coordinates": [
          longitude,
          latitude,
          elevation
        ]
      }
    }
  ]
}Code language: Java (java)

GeoJSON format can also represent LineString, Polygon, MultiPoint, MultiLineString, and MultiPolygon using GeoJSON. You can experiment with GeoJSON editor to create different representations.

In GeoJSON format
“geometry” – section contains the type of geometry and longitude and latitude where it should form.
“properties” – section will have user-defined properties, it is used to carry some data.

A sample response from USGS URL will look like below.
"geometry ” section contains earthquake co-ordinates,
properties" sections contain information about earthquake like magnitude, place and time

{
   "type":"FeatureCollection",
   "metadata":{
		...
   },
   "features":[
      {
         "type":"Feature",
         "properties":{
            "mag":6.9,
            "place":"central Mid-Atlantic Ridge",
            "time":1600465439448,
            "updated":1600494397132,
            ....
         },
         "geometry":{
            "type":"Point",
            "coordinates":[
               -26.8495,
               0.9454,
               10
            ]
         },
         "id":"us7000bq10"
      }
      
}Code language: Java (java)

Now let’s write code to visualize the earthquakes on the map.

Add earthquake data as source in map load event callback method

  map.on("load", () => {
        setMap(map);
        map.resize();
        map.addSource("earthquakes", {
          type: "geojson",
          data:
            "https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&eventtype=earthquake&minmagnitude=2&starttime=" +
            prevWeekDate,
          generateId: true, // This ensures that all features have unique IDs
        });
      });Code language: JavaScript (javascript)
https://gist.github.com/sureshgadupu/4fe1cd2e6f85c36cae4119cadc7098c0

Next, to display the earthquake points we need to add them as a layer to the map. We will display earthquake locations as circles on the map using below code

map.addLayer({
          id: "earthquakes-viz",
          type: "circle",
          source: "earthquakes",
          paint: {
            "circle-radius": 5,
            "circle-color": "#AAAAAA",
            "circle-stroke-color": "#000",
            "circle-stroke-width": 1,
          },
         });Code language: JavaScript (javascript)
https://gist.github.com/sureshgadupu/7fc4895962a5daa8e9a692ffcbbd00bd
  • id – unique id assigned to the layer
  • type – shape to draw on corresponding locations
  • source – data source name to read the data ( In this example add the data source name given in above step).
  • paint – define how data for that layer is styled.

Now start the application using npm start command and you should see the map like below with earthquake locations represented by circles.

Mapbox showing earth quakes on map

Now we will add events to earthquake points.
Whenever we hover a mouse pointer on circles.
1. We will change the circle size and colour corresponding to its magnitude
2. Show the earthquake info like magnitude, place name and time on the screen

First we will change the layer code like below

map.addLayer({
          id: "earthquakes-viz",
          type: "circle",
          source: "earthquakes",
          // paint: {
          //   "circle-radius": 5,
          //   "circle-color": "#AAAAAA",
          //   "circle-stroke-color": "#000",
          //   "circle-stroke-width": 1,
          // },
          paint: {
            "circle-radius": [
              "case",
              ["boolean", ["feature-state", "hover"], false],
              [
                "interpolate",
                ["linear"],
                ["get", "mag"],
                1,
                8,
                1.5,
                10,
                2,
                12,
                2.5,
                14,
                3,
                16,
                3.5,
                18,
                4.5,
                20,
                6.5,
                22,
                8.5,
                24,
                10.5,
                26,
              ],
              5,
            ],

            "circle-stroke-color": "#000",
            "circle-stroke-width": 1,
            // The feature-state dependent circle-color expression will render
            // the color according to its magnitude when
            // a feature's hover state is set to true
            "circle-color": [
              "case",
              ["boolean", ["feature-state", "hover"], false],
              [
                "interpolate",
                ["linear"],
                ["get", "mag"],
                1,
                "#fff7ec",
                1.5,
                "#fee8c8",
                2,
                "#fdd49e",
                2.5,
                "#fdbb84",
                3,
                "#fc8d59",
                3.5,
                "#ef6548",
                4.5,
                "#d7301f",
                6.5,
                "#b30000",
                8.5,
                "#7f0000",
                10.5,
                "#000",
              ],
              "#AAA",
            ], // end of circle color
          }, // end of paint
        }); //layerCode language: JavaScript (javascript)
https://gist.github.com/sureshgadupu/8bbecaac2f8b7dfca81849b7d17a9ba4
  • Define boolean feature-state hover property and set to false by default.
  • For circle-colour and circle-radius define values corresponding to their magnitude.

For displaying earthquake info declare div and corresponding style class.

.quakeInfo {
  position: absolute;
  font-family: sans-serif;
  margin-top: 5px;
  margin-left: 5px;
  padding: 5px;
  width: 30%;
  border: 2px solid black;
  font-size: 14px;
  color: #222;
  background-color: #fff;
  border-radius: 3px;
  z-index: 2;
}Code language: JavaScript (javascript)
https://gist.github.com/sureshgadupu/1b84a613fae4f4ddc7cbe9e3b9d08750
<>
      <div ref={(el) => (mapContainer.current = el)} style={styles} />
      <div className="quakeInfo">
        <div>
          <strong>Magnitude:</strong> <span id="mag">{earthquakeInfo.mag}</span>
        </div>
        <div>
          <strong>Location:</strong> <span id="loc">{earthquakeInfo.loc}</span>
        </div>
        <div>
          <strong>Date:</strong> <span id="date">{earthquakeInfo.date}</span>
        </div>
      </div>
    </>Code language: JavaScript (javascript)

Now we will add mouse events to map to change the colour and size of the circle on hover. Whenever the mouse moves over the earthquake layer, capture the event and if that point is corresponding to earthquake then we will change hover property to true, which results in a change of size and colour of the circle.

      let quakeID = null;
      map.on("mousemove", "earthquakes-viz", (e) => {
        map.getCanvas().style.cursor = "crosshair";
        // Set variables equal to the current feature's magnitude, location, and time
        let quakeMagnitude = e.features[0].properties.mag;
        let quakeLocation = e.features[0].properties.place;
        let quakeDate = new Date(e.features[0].properties.time);

        // Check whether features exist
        if (e.features.length > 0) {
          setEarthquakeInfo({
            mag: quakeMagnitude,
            loc: quakeLocation,
            date: quakeDate.toISOString(),
          });

          // If quakeID for the hovered feature is not null,
          // use removeFeatureState to reset to the default behavior
          if (quakeID) {
            map.removeFeatureState({
              source: "earthquakes",
              id: quakeID,
            });
          }

          quakeID = e.features[0].id;
          // When the mouse moves over the earthquakes-viz layer, update the
          // feature state for the feature under the mouse
          map.setFeatureState(
            {
              source: "earthquakes",
              id: quakeID,
            },
            {
              hover: true,
            }
          );

          map.on("mouseleave", "earthquakes-viz", (e) => {
            if (quakeID) {
              map.setFeatureState(
                {
                  source: "earthquakes",
                  id: quakeID,
                },
                {
                  hover: false,
                }
              );
            }

            quakeID = null;

            setEarthquakeInfo({ mag: "", loc: "", date: "" });
            // Reset the cursor style
            map.getCanvas().style.cursor = "";
          });
        }
      });Code language: JavaScript (javascript)
https://gist.github.com/sureshgadupu/9e259830e9e9588cf6d7dac7f163aef3

After all the above changes whenever a user places the mouse over a circle you should use the result like below.

Map showing earthquake details

You can download source code for the example from GitHub

Similar Posts