Created
May 19, 2016 22:14
-
-
Save ErwanLent/d1506533d6f9f86f5fa7e7bedcb30adb to your computer and use it in GitHub Desktop.
Animated Mabox Routing - http://codepen.io/erwanlent/pen/bpPVOV?editors=0010
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
L.mapbox.accessToken = 'pk.eyJ1IjoiZXJ3YW5sZW50IiwiYSI6IjA4YzY2Zjg2OTBkNDY5MDEyODBmN2RkOTdjMDc0NTY0In0.NY4En8vkN8h4JvlSDlhLfw'; | |
var map = L.mapbox.map('map', 'ian-cintric.fc32b7db', { | |
zoomControl: false | |
}).setView([37.7708, -122.4502], 13); | |
// map.on('click', function(e) { | |
// console.log(e.latlng); | |
// var marker = new L.marker(e.latlng).addTo(map); | |
// }); | |
setTimeout(test, 500); | |
$('#plotter-button').click(function() { | |
var coordinatesToAdd = $('#plotter-input').val(); | |
var lat = Number(coordinatesToAdd.split(',')[0].trim()); | |
var lon = Number(coordinatesToAdd.split(',')[1].trim()); | |
$('#plotter-input').val(''); | |
var marker = new L.marker(L.latLng(lat, lon)).addTo(map); | |
}); | |
function test() { | |
var startLocation = { | |
lon: -122.4851, | |
lat: 37.7840 | |
}; | |
var endLocation = { | |
lon: -122.27439880371094, | |
lat: 37.79974730744888 | |
}; | |
var route = getRoute(startLocation, endLocation, function(route) { | |
plotRoute(route); | |
}); | |
} | |
function getRoute(startLocation, endLocation, callback) { | |
var url = 'https://api.mapbox.com/directions/v5/mapbox/driving/{0},{1};{2},{3}?access_token={4}'; | |
url = url.format(startLocation.lon, startLocation.lat, endLocation.lon, endLocation.lat, L.mapbox.accessToken); | |
$.get(url, function(response) { | |
// Response validation | |
if (response.code != "Ok") { | |
callback(); | |
return; | |
} | |
var route = { | |
duration: response.routes[0].duration, | |
distance: response.routes[0].distance, | |
decodedPolyline: polyline.decode(response.routes[0].geometry) | |
}; | |
callback(route); | |
}); | |
} | |
var routePlotAmount; | |
function plotRoute(route) { | |
//http://leafletjs.com/reference.html#path-options | |
var routePath = []; | |
var allRouteIntermediaryPoints = []; | |
routePlotAmount = route.distance / 40; | |
for (var i = 0; i < route.decodedPolyline.length; i++) { | |
routePath.push(L.latLng(route.decodedPolyline[i][0], route.decodedPolyline[i][1])); | |
//new L.marker(L.latLng(route.decodedPolyline[i][0], route.decodedPolyline[i][1])).addTo(map); | |
if (i + 1 < route.decodedPolyline.length) { | |
var lineStartLocation = { | |
lat: route.decodedPolyline[i][0], | |
lon: route.decodedPolyline[i][1] | |
}; | |
var lineEndLocation = { | |
lat: route.decodedPolyline[i + 1][0], | |
lon: route.decodedPolyline[i + 1][1] | |
}; | |
var distanceOfLine = L.latLng(lineStartLocation.lat, lineStartLocation.lon).distanceTo(L.latLng(lineEndLocation.lat, lineEndLocation.lon)); | |
var numOfPointsOnLineAmount = Math.ceil((distanceOfLine * (routePlotAmount / route.distance))); | |
var pointsToPlot = getIntermediatePointsOnLine(lineStartLocation, lineEndLocation, numOfPointsOnLineAmount); | |
allRouteIntermediaryPoints.push.apply(allRouteIntermediaryPoints, pointsToPlot); | |
} | |
} | |
// Draw route with low opacity | |
var basePolyline = L.polyline(routePath, { | |
color: '#a0c658', | |
opacity: .3 | |
}); | |
map.fitBounds(basePolyline.getBounds()); | |
// Animate route | |
animateRoute(allRouteIntermediaryPoints, 0); | |
} | |
function getIntermediatePointsOnLine(lineStartLocation, lineEndLocation, numOfPointsOnLineAmount) { | |
var intermediatePoints = []; | |
intermediatePoints.push(lineStartLocation); | |
for (var i = 0; i <= numOfPointsOnLineAmount; i++) { | |
var calculatedLocation = calculatePointOnLine(intermediatePoints[intermediatePoints.length - 1], lineEndLocation, i, numOfPointsOnLineAmount); | |
intermediatePoints.push(calculatedLocation); | |
} | |
return intermediatePoints; | |
} | |
function calculatePointOnLine(lineStartLocation, lineEndLocation, k, numOfPointsOnLineAmount) { | |
var calculatedLat = (k * ((lineEndLocation.lat - lineStartLocation.lat) / numOfPointsOnLineAmount)) + lineStartLocation.lat; | |
var calculatedLon = (k * ((lineEndLocation.lon - lineStartLocation.lon) / numOfPointsOnLineAmount)) + lineStartLocation.lon; | |
return { | |
lat: calculatedLat, | |
lon: calculatedLon | |
}; | |
} | |
var animatedRouteLines = []; | |
var currentLocationMarker; | |
function animateRoute(routePoints, pathIndex) { | |
if (pathIndex + 1 < routePoints.length) { | |
//new L.marker(L.latLng(routePoints[i].lat, routePoints[i].lon)).addTo(map); | |
var currentPoint = L.latLng(routePoints[pathIndex].lat, routePoints[pathIndex].lon); | |
var nextPoint = L.latLng(routePoints[pathIndex + 1].lat, routePoints[pathIndex + 1].lon); | |
var routePath = []; | |
routePath.push(currentPoint); | |
routePath.push(nextPoint); | |
var distanceToNextMarker = currentPoint.distanceTo(nextPoint); | |
var nextTimeout = distanceToNextMarker / 4; | |
// Delete current location marker | |
if (currentLocationMarker) { | |
map.removeLayer(currentLocationMarker); | |
} | |
// Add current location marker | |
currentLocationMarker = new L.circleMarker(nextPoint, { | |
radius: 8, | |
color: '#fff', | |
fillColor: '#fff', | |
fillOpacity: .6, | |
opacity: 1, | |
weight: 2 | |
}).addTo(map); | |
// Add route | |
var animatedLine = L.polyline(routePath, { | |
color: '#3498db', | |
opacity: 1, | |
weight: 4 | |
}).addTo(map); | |
animatedRouteLines.push(animatedLine); | |
if (nextTimeout < 1) { | |
animateRoute(routePoints, pathIndex + 1); | |
return; | |
} | |
setTimeout(function() { | |
animateRoute(routePoints, pathIndex + 1); | |
}, nextTimeout) | |
} else { | |
setTimeout(function() { | |
//clearAnimatedRoute(); | |
setTimeout(function() { | |
//animateRoute(routePoints, 0); | |
}, 500); | |
}, 1000) | |
} | |
} | |
function clearAnimatedRoute() { | |
if (currentLocationMarker) { | |
map.removeLayer(currentLocationMarker); | |
} | |
for (var i = 0; i < animatedRouteLines.length; i++) { | |
map.removeLayer(animatedRouteLines[i]); | |
} | |
animatedRouteLines = []; | |
} | |
if (!String.prototype.format) { | |
String.prototype.format = function() { | |
var args = arguments; | |
return this.replace(/{(\d+)}/g, function(match, number) { | |
return typeof args[number] != 'undefined' ? | |
args[number] : | |
match; | |
}); | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment