I'm aware of a similar question posted: Animate multiple point along routes using Mapbox-GL.JS
My problem is different as I have multiple points and multiple routes to be animated and the coordinates in the route object consist of the multiple pair of origin and destination.
I have followed the documentation provided in mapbox website (https://docs.mapbox.com/mapbox-gl-js/example/animate-point-along-route/). And tweaked the animate function similar to the one provided in the stackoverflow post. However, I still am unable to animate the multiple points on the map. (only one point will be animated) And i can't figure out why.
This is a sample data of what I mean by just a pair of origin and destination coordinates in each route feature coordinate.
// San Francisco
var origin = [-122.414, 37.776];
var origin_2 = [-122.5, 37.676];
// Washington DC
var destination = [-77.032, 38.913];
var destination_2 = [-77.132, 38.813];
// A simple line from origin to destination.
var route = {
type: "FeatureCollection",
features: [
{
type: "Feature",
geometry: {
type: "LineString",
coordinates: [origin_2, destination_2],
},
},
{
type: "Feature",
geometry: {
type: "LineString",
coordinates: [origin, destination],
},
},
],
};
// A single point that animates along the route.
// Coordinates are initially set to origin.
var point = {
type: "FeatureCollection",
features: [
{
type: "Feature",
properties: {},
geometry: {
type: "Point",
coordinates: origin_2,
},
},
{
type: "Feature",
properties: {},
geometry: {
type: "Point",
coordinates: origin,
},
},
],
};
// Calculate the distance in kilometers between route start/end point.
var maxDistance = 0;
route.features.forEach((element) => {
console.log(element);
});
var lineDistance = turf.length(route.features[0]);
// console.log(route);
// console.log(point);
// console.log(lineDistance);
var arc = [];
// Number of steps to use in the arc and animation, more steps means
// a smoother arc and animation, but too many steps will result in a
// low frame rate
var steps = 500;
// Draw an arc between the `origin` & `destination` of the two points
for (var i = 0; i < lineDistance; i += lineDistance / steps) {
var segment = turf.along(route.features[0], i);
arc.push(segment.geometry.coordinates);
}
// Update the route with calculated arc coordinates
route.features[0].geometry.coordinates = arc;
// Used to increment the value of the point measurement against the route.
var counter = 0;
map.on("load", function () {
// Add a source and layer displaying a point which will be animated in a circle.
map.addSource("route", {
type: "geojson",
data: route,
});
map.addSource("point", {
type: "geojson",
data: point,
});
map.addLayer({
id: "route",
source: "route",
type: "line",
paint: {
"line-width": 2,
"line-color": "#007cbf",
},
});
map.addLayer({
id: "point",
source: "point",
type: "symbol",
layout: {
"icon-image": "car-15",
"icon-size": 1.5,
"icon-rotation-alignment": "map",
"icon-allow-overlap": true,
"icon-ignore-placement": true,
},
});
function animate(featureIdx, cntr) {
// Update point geometry to a new position based on counter denoting
// the index to access the arc.
if (
cntr >= route.features[featureIdx].geometry.coordinates.length - 1
) {
return;
}
point.features[featureIdx].geometry.coordinates = route.features[featureIdx].geometry.coordinates[cntr];
point.features[featureIdx].properties.bearing = turf.bearing(
turf.point(route.features[featureIdx].geometry.coordinates[cntr >= steps ? cntr - 1 : cntr]),
turf.point(route.features[featureIdx].geometry.coordinates[cntr >= steps ? cntr : cntr + 1])
);
// Update the source with this new data
map.getSource("point").setData(point);
// Request the next frame of animation as long as the end has not been reached
if (cntr < steps) {
console.log("ALLO LADIES");
requestAnimationFrame(function () {
animate(featureIdx, cntr + 1);
});
}
}
document.getElementById("replay").addEventListener("click", function () {
// Set the coordinates of the original point back to origin
point.features[0].geometry.coordinates = origin;
// Update the source layer
map.getSource("point").setData(point);
// Reset the counter
counter = 0;
// Restart the animation
animate(0, counter);
animate(1, counter);
});
// Start the animation
animate(0, 0);
animate(1, 0);
});