Visualizing data: Mapping earthquakes with the Google Maps API
Overview
This tutorial shows you how to:
- Import data into your Maps application.
- Display that data on a map using simple markers.
- Use symbols and heatmaps to improve the appearance and legibility of your map, and to represent secondary information.
At the end of this tutorial, you will have created a map that displays real-time earthquake data, including magnitude. You can use these same techniques with your own data source to help you tell a more powerful story with the Google Maps API.
L to R: Basic
markers, sized circles, and
heatmaps.
Importing your dataset
For this example, we'll use real-time earthquake data from the United States Geological Survey (USGS). The USGS website provides their data in a number of formats, which can be copied over to your domain for local access by your application. For this tutorial, we'll request JSONP directly from the USGS servers.
var map;
function initialize() {
var mapOptions = {
zoom: 2,
center: new google.maps.LatLng(2.8, -187.3),
mapTypeId: google.maps.MapTypeId.TERRAIN
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
// Create a script tag and set the USGS URL as the source.
var script = document.createElement('script');
script.src = 'http://earthquake.usgs.gov/earthquakes/feed/geojsonp/2.5/week';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(script, s);
}
Placing basic markers
Once you've pulled the data into your application, you need to display it on the map. This section shows you how to place a basic marker at each earthquake's location.
The default marker on Google Maps is the red pin:
To display a pin for each earthquake, you must obtain the locations from the
USGS feed. In the previous lesson, you pulled in the feed by appending a
script
tag to the head of your document; that script tag points to a
document on the USGS server, the contents of which are a function called
eqfeed_callback
, and a GeoJSON object as the function's only parameter.
You'll need to define eqfeed_callback
in your code. In this example, we
create a function that takes the GeoJSON results
array, and loops through
that array to place a marker at each set of coordinates:
window.eqfeed_callback = function(results) {
for (var i = 0; i < results.features.length; i++) {
var coords = results.features[i].geometry.coordinates;
var latLng = new google.maps.LatLng(coords[1], coords[0]);
var marker = new google.maps.Marker({
position: latLng,
map: map,
});
}
}
The result is a map that displays a basic marker at the epicenter of every
earthquake in the USGS feed.
Beyond the basic marker
Seeing the location of an earthquake is useful, but due to the overlapping markers, it's difficult to tell which locations have the most earthquakes, let alone additional details in the USGS feed, such as magnitude or depth. Fortunately, the Maps API makes it easy to customize how rich datasets can be displayed.
The Maps API offers a number of different ways of visualizing data:
-
Circle size: Using Symbols, you can draw circles (or any other shape) whose size is relative to the magnitude of an earthquake. In this way, powerful earthquakes are represented on the map as the largest circles.
-
Heatmaps: The Heatmap Layer in the visualization library offers a simple yet powerful way of displaying the distribution of earthquakes. Heatmaps use colors to represent the density of points, making it easier to pick out areas of high activity. Heatmaps can also use weighted locations so that, for example, bigger earthquakes are displayed more prominently in the heatmap.
Circle size
One way to represent magnitude is with circles, whose size increases with the magnitude of an earthquake:
The code is very similar to the code in the marker example. When creating the
marker, an additional icon
parameter is passed, which defines a custom image
for the point instead of the default red marker:
window.eqfeed_callback = function(results) { for (var i = 0; i < results.features.length; i++) { var coords = results.features[i].geometry.coordinates; var latLng = new google.maps.LatLng(coords[1], coords[0]); var marker = new google.maps.Marker({ position: latLng, map: map, icon: getCircle(earthquake.properties.mag) }); } }
In this case, the icon
specified is a function, getCircle()
, to which we
pass the magnitude property of the earthquake. getCircle()
draws a circle
whose size is defined by the magnitude value, and sends that circle back to be
used as the earthquake's custom marker:
function getCircle(magnitude) {
var circle = {
path: google.maps.SymbolPath.CIRCLE,
scale: magnitude
};
return circle;
}
Here's the final code, with some additional styling on the circle to improve its appearance:
var map;
function initialize() {
var mapOptions = {
zoom: 2,
center: new google.maps.LatLng(2.8, -187.3),
mapTypeId: google.maps.MapTypeId.TERRAIN
};
map = new google.maps.Map(document.getElementById('map_canvas'),
mapOptions);
// Create a script tag and set the USGS URL as the source.
// Append this tag to the document's <head>.
var script = document.createElement('script');
script.src = 'http://earthquake.usgs.gov/earthquakes/feed/geojsonp/2.5/week';
document.getElementsByTagName('head')[0].appendChild(script);
}
window.eqfeed_callback = function(results) {
for (var i = 0; i < results.features.length; i++) {
var earthquake = results.features[i];
var coords = earthquake.geometry.coordinates;
var latLng = new google.maps.LatLng(coords[1],coords[0]);
var marker = new google.maps.Marker({
position: latLng,
map: map,
icon: getCircle(earthquake.properties.mag)
});
}
}
function getCircle(magnitude) {
return {
path: google.maps.SymbolPath.CIRCLE,
fillColor: 'red',
fillOpacity: .2,
scale: Math.pow(2, magnitude) / Math.PI,
strokeColor: 'white',
strokeWeight: .5
};
}
Heatmaps
Heatmaps make it easy for viewers to understand the distribution of the USGS-reported earthquakes. Rather than placing a marker on each epicenter, heatmaps use color and shape to represent the distribution of the data. In this example, red represents areas of high earthquake activity.
To display a heatmap, we'll make use of the visualization
library, which
contains a HeatmapLayer
class. When using a library, it must be loaded when
the Maps API JavaScript is called:
<script src="http://maps.googleapis.com/maps/api/js?libraries=geometry,visualization&sensor=true_or_false"> </script>
As with the previous examples, the USGS data is passed to the eqfeed_callback
function, which in this case adds the coordinates of each earthquake to a
heatmapData
array. That array is then passed to the HeatmapLayer
constructor, which creates the heatmap and displays it on the map.
window.eqfeed_callback = function(results) {
var heatmapData = [];
for (var i = 0; i < results.features.length; i++) {
var coords = results.features[i].geometry.coordinates;
var latLng = new google.maps.LatLng(coords[1], coords[0]);
heatmapData.push(latLng);
}
var heatmap = new google.maps.visualization.HeatmapLayer({
data: heatmapData,
dissipating: false,
map: map
});
}
If you'd like to weight the results by magnitude, you can pass
WeightedLocation
objects to the heatmapData
array instead:
window.eqfeed_callback = function(results) { var heatmapData = []; for (var i = 0; i < results.features.length; i++) { var coords = results.features[i].geometry.coordinates; var latLng = new google.maps.LatLng(coords[1], coords[0]); var magnitude = results.features[i].properties.mag; var weightedLoc = { location: latLng, weight: Math.pow(2, magnitude) }; heatmapData.push(weightedLoc); } var heatmap = new google.maps.visualization.HeatmapLayer({ data: heatmapData, dissipating: false, map: map }); }
Conclusion
In this class, you've learned how to pull data from an external source, plot geographic points on the map with simple markers, and to go beyond the red map pin by using circles and heatmaps to visualize data.
You can easily adapt this code to use your own local data, or to pull in data
from another source, such as the
World Bank.