Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visualize Live animated moving Marker

I have a mapping solution that is using OpenStreetMaps, Leaflet JS API and PostGIS Database. I have an API that is called from tracking device. Device send data (Longitude and Latitude) with an interval of 30 seconds. I have plotted the data on the map as marker and draw polyline by joining the marker. Now I need to plot live and animated marker of tracking. I am looking for a a solution similar to the following gif image.

enter image description here

https://i.imgur.com/KrOy634.gif

There is a Plugin of Leaflet JS API Called Moving Marker but I was unable to resolve. It use three parameters (2 location and duration of animation). I can add the location but can not control the duration.

var myMovingMarker = L.Marker.movingMarker([[48.8567, 2.3508],[50.45, 30.523333]],
                        [20000]).addTo(map);

myMovingMarker.start();

What is the best way to visualize the live moving tracking? I know if there is a Speed parameter in device data then it can be possible. Unfortunately there is no Speed parameter from device data.

like image 352
Devil's Dream Avatar asked May 22 '16 10:05

Devil's Dream


2 Answers

To do this properly I have found that you need to obtain the point to point route and then iterate over the points to animate the marker across the path over the period between your location polling. The basic approach I have used is to obtain the route from the start to end location using a service suchs as OSRM. Typically you will need to translate the encoded polyline into a set of points and then create a timer which updates the marker location periodically to the point in the polyline that is the proportion of the time between location updates. So if you have 300 points in your polyline route between points and your location update is every 30 secs you would set up a timer that triggers each second and moves the marker to the index of the point array at ( secs_since_geocode/30 * number of points ). This could be smoothed even more be animating the transition from the starting marker location to the new marker location although the approach would need to ensure to be completed before the next timer event moves the marker again.

It's rough and ugly but you can see something that works ( need to wait about 20 secs ) at https://jsfiddle.net/pscott_au/1wt2o9Lw/

Basically what I am trying to achieve is to provide some kind of transition for the marker between getting the location GPS coordinates which would typically be polled at some interval ( say 30 secs ). Ideally you wish to show the marker moving smoothly between the locations in between these updates. If driving you would ideally want to show the marker animating along the expected drive path and so need to obtain a path from a routing service. I am using the public OSRM service although you would ideally set up your own backend for this or use a commercial offering. So when a new location is obtained the approach is to get the route from the last location to the new location and then step toward that location along the path. More recent OSRM versions include an option to provide the result as a list of lat/lng points so no need to decode the encoded polyline. So just need to create a queue of points and then pop locations off at small interval of say 500ms to move the marker. The other answer is excellent and provides a good approach to smoothing the animation even further. The path is constructed from the returned result as follows:

    $.ajax({ 
  url: url, 
 success: function(data){

 //console.log( 'Got route ' + JSON.stringify(data.route_geometry) );
 // if we assume that we have 30 secs until the next geo location then we need to animate 
 // across this path for this duration - to demonstrate we will animate every 2 secs over 20 secs
 // so to calculate the index offset we will divide the number of points in our path by 20
route_geometry = [];
// console.log( data.route_geometry );
var inc_offset = $(data.route_geometry ).size() / 20;
for (i = 0; i < 20; i++) { 
   console.log(i + ' x inc_offset of ' + inc_offset );
   route_geometry.push( data.route_geometry[ Math.round(i*inc_offset ) ] );
 }

 }
}); 

Over the next couple of days I will refine and clean this up and then update this answer.

like image 90
Peter Scott Avatar answered Nov 15 '22 06:11

Peter Scott


Your code works for me, see http://playground-leaflet.rhcloud.com/tozo/edit?html,output

I can add the location but can not control the duration.

Erm, it's the second parameter, with a value of 20000 msecs?

like image 24
IvanSanchez Avatar answered Nov 15 '22 06:11

IvanSanchez