I have written a small application for a handheld device using JavaScript and Google Maps API's, now II need to move my marker icon anywhere on the map along a route using a timer function. I have a man icon and I need to move it automatically on the map. How can I do this?
Asked
Active
Viewed 4.8k times
23
-
I edited the title to reflect the contents of the question. @jyothi: when posting a question, please take your time to review the contents of it. With just 2 minutes of extra reviewing, you can improve the quality by 100%, with an expectation of more and better answers. – Aron Rotteveel Mar 20 '09 at 06:59
-
k sir thank u, can u answer my question – Mar 20 '09 at 07:37
-
@jyothi did you get a solution to this i need to do this exact same thing on a map application. Can you shed some light if you achieved it how it was achieved. – devdar Mar 26 '13 at 21:31
3 Answers
17
A pretty cool example is here:

Matt
- 1,247
- 8
- 16
-
That page uses an older version of the library at http://econym.org.uk/gmap/epoly.htm which contains some handy utility functions you can use to find the lat-long of a position along a path. Should make it much easier to build an animated marker. – Steve Hiner Jan 27 '12 at 23:25
-
Just out of interest I also used a similar technique on a site I buid last year. the methods are likely a little out of date with the latest APIs but it works well. http://www.flushtracker.com/ – Matt Feb 01 '12 at 09:15
-
@Matt It looks like the domain **flushtracker.com** now redirects to **domestos.com/uk/home.html**. – Anthony Walsh Feb 24 '19 at 00:06
9
Unfortunately, there is no automatic-marker-movement function in the official GMaps collection.
However, if you have a GRoute, that would mean you have a set of points. To loop through the route steps, you could use something like this:
for (var c = 0; c < yourroute.getNumSteps(); c++) {
yourmarker.setLatLng(yourroute.getStep(c).getLatLng());
}
Of course, you'll probably want to do this asynchronously using the timers:
function moveToStep(yourmarker,yourroute,c) {
if {yourroute.getNumSteps() > c) {
yourmarker.setLatLng(yourroute.getStep(c).getLatLng());
window.setTimeout(function(){
moveToStep(yourmarker,yourroute,c+1);
},500);
}
}
moveToStep(marker,route,0);
For even smoother movement, you could interpolate the points from those you already have.

Piskvor left the building
- 91,498
- 46
- 177
- 222
-
Is this functionality available in Google Maps V3? The "steps" array returned by the DirectionsService only seems to include the steps of the directions (ie turn left at so-and-so) instead of the individual points that make the rendered line. – Kevin Aug 31 '10 at 01:14
-
@Puskvor is it possible to keep incrementing a latlong coordinate to simulate a route,the route doesn't have to be only on streets. – devdar Mar 26 '13 at 21:34
-
1@dev_darin: Yes. Not all routes are straight lines though; in between the various route points, your approach is of course viable. – Piskvor left the building Mar 27 '13 at 18:17
-
@Puskvor can you tell me how it can be incremented the long lat i know its based on an angle as well i was thinking about using a randomizer to get values but i would like to know how can it be incremented – devdar Mar 27 '13 at 18:54
-
@dav_durin: get one coordinate, increment it by a given amount, get the other, increment by some other amount, create a new LatLng with the new coordinates, .setLatLng(yourNewLatLng). – Piskvor left the building Mar 29 '13 at 14:14
8
Here is my solution that works with the v3 API. This animates the marker not with a fixed velocity, but based on the calculated route duration. There is a speed factor, so for example you can drive through the route 10x faster than in reality.
I've tried to do it as simple as possible. Feel free to use it.
var autoDriveSteps = new Array();
var speedFactor = 10; // 10x faster animated drive
function setAnimatedRoute(origin, destination, map) {
// init routing services
var directionsService = new google.maps.DirectionsService;
var directionsRenderer = new google.maps.DirectionsRenderer({
map: map
});
//calculate route
directionsService.route({
origin: origin,
destination: destination,
travelMode: google.maps.TravelMode.DRIVING
},
function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
// display the route
directionsRenderer.setDirections(response);
// calculate positions for the animation steps
// the result is an array of LatLng, stored in autoDriveSteps
autoDriveSteps = new Array();
var remainingSeconds = 0;
var leg = response.routes[0].legs[0]; // supporting single route, single legs currently
leg.steps.forEach(function(step) {
var stepSeconds = step.duration.value;
var nextStopSeconds = speedFactor - remainingSeconds;
while (nextStopSeconds <= stepSeconds) {
var nextStopLatLng = getPointBetween(step.start_location, step.end_location, nextStopSeconds / stepSeconds);
autoDriveSteps.push(nextStopLatLng);
nextStopSeconds += speedFactor;
}
remainingSeconds = stepSeconds + speedFactor - nextStopSeconds;
});
if (remainingSeconds > 0) {
autoDriveSteps.push(leg.end_location);
}
} else {
window.alert('Directions request failed due to ' + status);
}
});
}
// helper method to calculate a point between A and B at some ratio
function getPointBetween(a, b, ratio) {
return new google.maps.LatLng(a.lat() + (b.lat() - a.lat()) * ratio, a.lng() + (b.lng() - a.lng()) * ratio);
}
// start the route simulation
function startRouteAnimation(marker) {
var autoDriveTimer = setInterval(function () {
// stop the timer if the route is finished
if (autoDriveSteps.length === 0) {
clearInterval(autoDriveTimer);
} else {
// move marker to the next position (always the first in the array)
marker.setPosition(autoDriveSteps[0]);
// remove the processed position
autoDriveSteps.shift();
}
},
1000);
}
Usage:
setAnimatedRoute("source address or LatLng ...", "destination address or LatLng ...", map);
// start simulation on button click...
$("#simulateRouteButton").click(function() {
startRouteAnimation(agentMarker);
});

Gaspar Nagy
- 4,422
- 30
- 42