1

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);
    });
raenara
  • 11
  • 1
  • The reason I can see is that in second feature inside route has no arc coodinate's. It just has only two coordinates source and destination. However in the first feature you are populating all the coordinates using arc array. – Dolly Mar 18 '21 at 18:44
  • @Dolly Thanks for pointing me in the right direction! That was actually the reason why. It's been fixed. – raenara Mar 19 '21 at 02:33

0 Answers0