Simple example of displaying a route in Leaflet using d3.js.
Last active
May 28, 2019 05:09
-
-
Save mtaptich/182f63d3aef39bc96e59 to your computer and use it in GitHub Desktop.
Simple Traveler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<meta charset="utf-8" /> | |
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" /> | |
<script src="http://d3js.org/d3.v3.min.js" type="text/javascript"></script> | |
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script> | |
<style> | |
html, | |
body { | |
height: 100%; | |
width: 100%; | |
} | |
body { | |
margin: 0; | |
} | |
#map { | |
width: 100%; | |
height: 100%; | |
} | |
svg { | |
position: relative; | |
} | |
path { | |
fill: none; | |
stroke-width: 8px; | |
stroke-dasharray: 8px, 8px; | |
stroke: #e74c3c; | |
stroke-opacity: 0.99; | |
} | |
.traveler{ | |
fill: #3498db; | |
stroke: #2980b9; | |
stroke-width: 3px; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="map"></div> | |
</body> | |
<script type="text/javascript"> | |
var padding = 50, loc = 0, transition_speed = 750; | |
// (1) Initiate the map, including proper tiles, attribution, and map view. | |
var mapboxTiles = L.tileLayer('http://stamen-tiles-{s}.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}.png', { | |
attribution: 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a> — Map data © <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>' | |
}); | |
var map = L.map('map') | |
.addLayer(mapboxTiles) | |
.setView([38.865, -122.26], 13); | |
// (2) Add an svg to the the overlayPane | |
var svg = d3.select(map.getPanes().overlayPane).append("svg"); | |
var g = svg.append("g") | |
.attr("class", "leaflet-zoom-hide"); | |
// (3) Load the geojson data | |
d3.json("polyline.json", function(rt) { | |
var transform = d3.geo.transform({point: projectPoint}), | |
cors = rt.features[0].geometry.coordinates, | |
path = d3.geo.path().projection(transform), | |
center = map.containerPointToLatLng(path.centroid(rt)) | |
// Center map about route cetroid | |
map.setView(center, 14); | |
route = g.selectAll("path") | |
.data(rt.features) | |
.enter().append("path"); | |
od = g.append("circle") | |
.attr("r", 8*1.61803398875) | |
.attr("id", "marker") | |
.attr("class", "traveler") | |
.attr('transform', function(){ | |
var c = cors[0], | |
b = map.latLngToLayerPoint(new L.LatLng(c[1], c[0])) | |
return "translate("+[b.x,b.y]+")" | |
}); | |
map.on("viewreset", reset); | |
//(4) Update the path based on the updated map projection using projectPoint | |
reset(); | |
progress(); | |
function reset() { | |
var bounds = path.bounds(rt); | |
svg.attr("width", bounds[1][0] - bounds[0][0] + padding*3) | |
.attr("height", bounds[1][1] - bounds[0][1] + padding*3) | |
.style("left", bounds[0][0] - padding + "px") | |
.style("top", bounds[0][1] - padding + "px"); | |
g.attr("transform", "translate(" + (-bounds[0][0] + padding) + "," + (-bounds[0][1] + padding) + ")"); | |
route.attr("d", path); | |
} | |
function progress(){ | |
loc = loc < cors.length-1 ? loc+1 : 0; | |
var c = cors[loc], | |
b = map.latLngToLayerPoint(new L.LatLng(c[1], c[0])) | |
od.transition() | |
.duration(transition_speed* Math.random() + 400) // You could calibrate this to speed if you had the data | |
.ease('quad') | |
.attr("transform",function(d,i){ | |
return "translate("+[b.x,b.y]+")" | |
}) | |
.each('end', progress) | |
} | |
function projectPoint(x, y) { | |
var point = map.latLngToLayerPoint(new L.LatLng(y, x)); | |
this.stream.point(point.x, point.y); | |
} | |
}); | |
</script> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment