Skip to content

Instantly share code, notes, and snippets.

@grovduck
Last active November 15, 2017 21:14
Show Gist options
  • Save grovduck/bee7638e3e0b935bf059d4cd4916acc8 to your computer and use it in GitHub Desktop.
Save grovduck/bee7638e3e0b935bf059d4cd4916acc8 to your computer and use it in GitHub Desktop.
[Mapbox GL JS animated earthquakes] Code for generating animated earthquakes using GeoJSON data and Mapbox GL JS. Need a simple webserver to run, e.g. 'python -m SimpleHTTPServer 8000' #mapbox #web_mapping
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title></title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.37.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.37.0/mapbox-gl.css' rel='stylesheet' />
<link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700' rel='stylesheet'>
<style>
body {
font: 400 15px/22px 'Source Sans Pro', 'Helvetica Neue', Sans-serif;
margin:0;
padding:0;
}
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<style>
.map-overlay {
font: 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;
position: absolute;
width: 25%;
top: 0;
left: 0;
padding: 10px;
}
.map-overlay .map-overlay-inner {
background-color: #fff;
box-shadow:0 1px 2px rgba(0, 0, 0, 0.20);
border-radius: 3px;
padding: 10px;
margin-bottom: 10px;
}
.map-overlay h2 {
line-height: 24px;
display: block;
margin: 0 0 10px;
}
.map-overlay .legend .bar {
height: 10px;
width: 100%;
background: linear-gradient(to right, #FCA107, #7F3121);
}
.map-overlay input {
background-color: transparent;
display: inline-block;
width: 100%;
position: relative;
margin: 0;
cursor: ew-resize;
}
</style>
<div id='map'></div>
<div class='map-overlay top'>
<div class='map-overlay-inner'>
<div id='legend' class='legend'>
<div class='date'>
<p id='currentDate'><p>
</div>
<div class='bar'></div>
<div>Magnitude (m)</div>
</div>
</div>
</div>
<script src='https://d3js.org/d3.v3.min.js' charset='utf-8'></script>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoiZ3JvdmR1Y2siLCJhIjoiYXVYb29zbyJ9.TO2NcqGJDyWDCSvOfBBUIQ';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v9',
center: [31.4606, 20.7927],
zoom: 0.5
});
var earthquakes;
var currentTimestamp;
map.on('load', function() {
d3.json("./significant-earthquakes-2015.geojson", function(err, data) {
if (err) throw err;
data.features = data.features.map(function(d) {
var current = new Date(d.properties.time);
d.properties.startAnimation = new Date(current.getTime()).setDate(current.getDate() - 5);
d.properties.endAnimation = new Date(current.getTime()).setDate(current.getDate() + 5);
d.properties.currentMag = 0;
return d;
});
earthquakes = {
"type": "geojson",
"data": data
};
map.addSource("earthquakes", earthquakes);
map.addLayer({
'id': 'earthquake-circles',
'type': 'circle',
'source': 'earthquakes',
'paint': {
'circle-color': {
property: 'mag',
stops: [
[5, '#ffff00'],
[6, '#FCA107'],
[7, '#7F3121'],
[8, '#7F3121']
]
},
'circle-opacity': 0.30,
'circle-stroke-width': 0.5,
'circle-radius': {
property: 'currentMag',
stops: [
[0, 0],
[6, 15],
[8, 40]
]
}
}
});
currentTimestamp = new Date('2015-01-01');
endTimestamp = new Date('2016-01-01');
delay = '200';
transitionStyle = 'linear';
setTimeout(function(){
function animate() {
currentTimestamp.setHours(currentTimestamp.getHours() + 3);
if (currentTimestamp >= endTimestamp) {
currentTimestamp.setYear(2015);
}
updateCurrentDate();
map.fire('move earthquakes');
requestAnimationFrame(animate);
}
animate();
}, 1000);
});
});
function updateCurrentDate() {
var p = document.getElementById('currentDate');
var d = currentTimestamp;
var dateString = d.getFullYear() + "-"
+ ("0" + (d.getMonth()+1)).slice(-2) + "-"
+ ("0" + d.getDate()).slice(-2);
p.innerHTML = dateString;
}
map.on('move earthquakes', function() {
map.getSource('earthquakes').setData(showActiveEarthquakes());
});
function showActiveEarthquakes() {
for (var i = 0; i < earthquakes.data.features.length; i++) {
var marker = earthquakes.data.features[i];
if (marker.properties.startAnimation <= currentTimestamp &&
marker.properties.endAnimation >= currentTimestamp) {
var start = marker.properties.startAnimation;
var end = marker.properties.endAnimation;
var eTime = marker.properties.time;
if (currentTimestamp < eTime) {
var w1 = (currentTimestamp - start) / (eTime - start);
var w2 = 1.0 - w1;
var currentMag = w1 * marker.properties.mag;
} else if (currentTimestamp > eTime) {
var w1 = (currentTimestamp - eTime) / (end - eTime);
var w2 = 1.0 - w1;
var currentMag = w2 * marker.properties.mag;
}
marker.properties.currentMag = currentMag;
}
}
return earthquakes.data;
}
</script>
</body>
</html>
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment