|
<!DOCTYPE html> |
|
<head> |
|
<meta charset="utf-8"> |
|
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' /> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> |
|
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.12.0/mapbox-gl.js'></script> |
|
<script src='https://api.tiles.mapbox.com/mapbox.js/plugins/turf/v2.0.0/turf.min.js'></script> |
|
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.12.0/mapbox-gl.css' rel='stylesheet' /> |
|
|
|
<style> |
|
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } |
|
#map { |
|
position:absolute; |
|
width: 100%; |
|
height: 100%; |
|
} |
|
svg { |
|
position: absolute; |
|
width: 100%; |
|
height: 100%; |
|
} |
|
</style> |
|
</head> |
|
|
|
<body> |
|
<div id="map"></div> |
|
<script> |
|
|
|
mapboxgl.accessToken = 'pk.eyJ1IjoiZW5qYWxvdCIsImEiOiJjaWhtdmxhNTIwb25zdHBsejk0NGdhODJhIn0.2-F2hS_oTZenAWc0BMf_uw' |
|
|
|
//Setup mapbox-gl map |
|
var map = new mapboxgl.Map({ |
|
container: 'map', |
|
style: 'mapbox://styles/mapbox/light-v9', |
|
center: [-122.36427866890976, 37.75709473263497], |
|
zoom: 9 |
|
|
|
}); |
|
// map.scrollZoom.disable() |
|
map.addControl(new mapboxgl.Navigation()); |
|
|
|
// Setup our svg layer that we can manipulate with d3 |
|
var container = map.getCanvasContainer() |
|
var svg = d3.select(container).append("svg") |
|
|
|
|
|
function project(d) { |
|
return map.project(getLL(d)); |
|
} |
|
function getLL(d) { |
|
return new mapboxgl.LngLat(+d.lon, +d.lat) |
|
} |
|
|
|
d3.csv("dots.csv", function(err, data) { |
|
//console.log(data[0], getLL(data[0]), project(data[0])) |
|
var dots = svg.selectAll("circle.dot") |
|
.data(data) |
|
|
|
dots.enter().append("circle").classed("dot", true) |
|
.attr("r", 5) |
|
.style({ |
|
fill: 'red', |
|
stroke: "#004d60", |
|
"stroke-width": 1 |
|
}) |
|
.transition().duration(9000) |
|
.attr("r", 5) |
|
|
|
function render() { |
|
dots |
|
.attr({ |
|
cx: function(d) { |
|
var x = project(d).x; |
|
return x |
|
}, |
|
cy: function(d) { |
|
var y = project(d).y; |
|
return y |
|
}, |
|
}) |
|
} |
|
|
|
// re-render our visualization whenever the view changes |
|
map.on("viewreset", function() { |
|
render() |
|
}) |
|
map.on("move", function() { |
|
render() |
|
}) |
|
|
|
// render our initial visualization |
|
render() |
|
}) |
|
map.on('load', function() { |
|
|
|
map.addSource('route', { |
|
'type': 'geojson', |
|
'data': routeLineString |
|
}); |
|
|
|
map.addLayer({ |
|
'id': 'route', |
|
'type': 'line', |
|
'source': 'route', |
|
'paint': { |
|
'line-color': 'black', |
|
'line-width': .001 |
|
} |
|
}); |
|
|
|
map.addSource('train', { |
|
"type": "geojson", |
|
"data": trainOnRoute(0) |
|
}); |
|
|
|
map.addLayer({ |
|
"id": "train", |
|
"source": "train", |
|
"type": "circle", |
|
"paint": { |
|
"circle-radius": 4, |
|
"circle-color": "#70004e" |
|
} |
|
}); |
|
|
|
function animateTrain(timestamp) { |
|
// Update the data to a new position based on the animation timestamp. The |
|
// divisor in the expression `timestamp / 1000` controls the animation speed. |
|
map.getSource('train').setData( |
|
trainOnRoute(timestamp / 1000) |
|
); |
|
|
|
// Request the next frame of the animation. |
|
requestAnimationFrame(animateTrain); |
|
} |
|
|
|
// Start the animation. |
|
animateTrain(0); |
|
|
|
}); |
|
|
|
function trainOnRoute(distance) { |
|
return turf.along(routeLineString, distance, 'miles'); |
|
} |
|
|
|
|
|
var routeLineString = { |
|
"type": "Feature", |
|
"properties": {}, |
|
"geometry": { |
|
"type": "LineString", |
|
"coordinates": [ |
|
[-122.386794090271, 37.60012220289819], |
|
[-122.40074157714844, 37.61416342563735], |
|
[-122.40829467773436, 37.62480307085124], |
|
[-122.41767168045044, 37.640215957670726], |
|
[-122.42168426513672, 37.64611177340781], |
|
[-122.42683410644533, 37.6518202441499], |
|
[-122.43548154830931, 37.656610943427125], |
|
[-122.44019150733948, 37.66179202556475], |
|
[-122.44824886322021, 37.66721054100796], |
|
[-122.44992256164551, 37.669435584815766], |
|
[-122.452712059021, 37.67363071495582], |
|
[-122.45807647705078, 37.67736706842431], |
|
[-122.46163845062254, 37.68140891166475], |
|
[-122.46814012527466, 37.68623166333117], |
|
[-122.46987819671631, 37.68967871970675], |
|
[-122.46994256973268, 37.694755619331595], |
|
[-122.47101545333861, 37.697879692484264], |
|
[-122.4709939956665, 37.702786259018616], |
|
[-122.47097253799438, 37.70377092874501], |
|
[-122.46620893478394, 37.7094240379944], |
|
[-122.46481418609618, 37.710052134627205], |
|
[-122.46367692947388, 37.710120036647], |
|
[-122.45676755905153, 37.71025584049998], |
|
[-122.45445013046265, 37.71105368311011], |
|
[-122.44960069656372, 37.71512763910703], |
|
[-122.44837760925292, 37.71711361144011], |
|
[-122.44803428649902, 37.71909953053827], |
|
[-122.44672536849974, 37.724904219581596], |
|
[-122.44451522827147, 37.72739907772295], |
|
[-122.44013786315918, 37.72969019994345], |
|
[-122.42346525192261, 37.740177543351415], |
|
[-122.41812229156493, 37.748559561800654], |
|
[-122.42035388946533, 37.77220734485087], |
|
[-122.41986036300658, 37.774615805204256], |
|
[-122.39481925964355, 37.79448684840749], |
|
[-122.37595796585083, 37.80274827178258], |
|
[-122.3573112487793, 37.80624076600696], |
|
[-122.33799934387206, 37.80946185212675], |
|
[-122.3299741744995, 37.8099026214036], |
|
[-122.30667114257812, 37.807868279712665], |
|
[-122.29967594146727, 37.8063933469406], |
|
[-122.29759454727174, 37.8058677890642], |
|
[-122.28974103927614, 37.80278218028747], |
|
[-122.28351831436157, 37.801256282156544], |
|
[-122.2779607772827, 37.798662182986924], |
|
[-122.2762441635132, 37.79850958608104], |
|
[-122.27429151535034, 37.79906910652822], |
|
[-122.26761817932127, 37.81005519477107], |
|
[-122.26877689361571, 37.81168262440736], |
|
[-122.27053642272949, 37.81334392182851], |
|
[-122.270987033844, 37.81566628515953], |
|
[-122.26613759994507, 37.83432729676272], |
|
[-122.26912021636963, 37.83819111265065], |
|
[-122.27150201797485, 37.84856140722196], |
|
[-122.26706027984619, 37.86043800837439], |
|
[-122.26846575736998, 37.87224494293345], |
|
[-122.26901292800903, 37.873049507350586], |
|
[-122.26966738700865, 37.87358305575012], |
|
[-122.27127671241759, 37.87377784229819], |
|
[-122.27961301803587, 37.87272768263811], |
|
[-122.2812008857727, 37.8731087906969], |
|
[-122.28537440299986, 37.874768705025524], |
|
[-122.28711247444151, 37.875903522887256], |
|
[-122.29626417160036, 37.899019513198624], |
|
[-122.29917168617249, 37.90291380078861], |
|
[-122.30101704597472, 37.90522487837832], |
|
[-122.3044502735138, 37.90945743301735], |
|
[-122.31707811355591, 37.92540351171852], |
|
[-122.32012510299683, 37.92910176319838], |
|
[-122.32216358184813, 37.93046423001139], |
|
[-122.32452392578125, 37.93112429802159], |
|
[-122.32995271682739, 37.931352781721266], |
|
[-122.33520984649657, 37.93136970641152], |
|
[-122.34608888626097, 37.931522028448406], |
|
[-122.34842777252196, 37.93245287848293], |
|
[-122.35379219055174, 37.936971564791975] |
|
] |
|
} |
|
}; |
|
|
|
|
|
|
|
</script> |
|
</body> |