2009-03-20 4 views
16

Ich habe eine kleine Anwendung für ein Handheld-Gerät mit JavaScript und Google Maps APIs geschrieben, jetzt muss ich mein Markersymbol irgendwo auf der Karte entlang einer Route mit einer Timer-Funktion bewegen. Ich habe ein Mannsymbol und ich muss es automatisch auf der Karte verschieben. Wie kann ich das machen?Wie animiert man einen benutzerdefinierten Google Maps-Marker entlang einer Route?

+0

bearbeitet ich den Titel den Inhalt der Frage zu reflektieren. @jyothi: Wenn Sie eine Frage stellen, nehmen Sie sich bitte Zeit, um den Inhalt zu überprüfen. Mit nur 2 Minuten zusätzlicher Überprüfung können Sie die Qualität um 100% verbessern, mit der Erwartung von mehr und besseren Antworten. –

+0

k Sir danke, kannst du meine Frage beantworten –

+0

@jyothi hast du eine Lösung für dieses ich muss genau dasselbe auf einer Kartenanwendung tun. Kannst du etwas Licht geben, wenn du es erreicht hast, wie es erreicht wurde? – devdar

Antwort

0

Es bewegt sich nichts automatisch, aber Sie sollten das Google Drive Experiment durch phatfusion überprüfen. Ein Blick auf den Code könnte Ihnen helfen.

8

Leider gibt es in der offiziellen GMaps-Sammlung keine automatische Marker-Bewegungsfunktion.

Wenn Sie jedoch eine GRoute haben, bedeutet das, dass Sie eine Reihe von Punkten haben. Um eine Schleife durch die Route Schritte, könnten Sie so etwas wie folgt verwenden:

for (var c = 0; c < yourroute.getNumSteps(); c++) { 
    yourmarker.setLatLng(yourroute.getStep(c).getLatLng()); 
} 

Natürlich, werden Sie wahrscheinlich diese asynchron mit den Timer zu tun:

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); 

Für eine noch glattere Bewegung, Sie könnte die Punkte von denen interpolieren, die Sie bereits haben.

+0

Ist diese Funktion in Google Maps V3 verfügbar?Das von DirectionsService zurückgegebene "steps" -Array scheint nur die Schritte der Anweisungen zu enthalten (dh links bei so-und-so) statt der einzelnen Punkte, aus denen die gerenderte Linie besteht. – Kevin

+0

@Puskvor ist es möglich, eine lange Koordinate zu erhöhen, um eine Route zu simulieren, die Route muss nicht nur auf Straßen liegen. – devdar

+1

@dev_darin: Ja. Nicht alle Routen sind jedoch gerade Linien; Zwischen den verschiedenen Routenpunkten ist Ihr Ansatz natürlich machbar. – Piskvor

16

Ein ziemlich cooles Beispiel ist hier:

http://www.kmcgraphics.com/google/

+0

Diese Seite verwendet eine ältere Version der Bibliothek unter http://econym.org.uk/gmap/epoly.htm, die einige nützliche Dienstprogrammfunktionen enthält, die Sie verwenden können, um die Länge einer Position entlang eines Pfades zu finden. Es sollte viel einfacher sein, einen animierten Marker zu erstellen. –

+0

Nur aus Interesse habe ich auch eine ähnliche Technik auf einer Seite verwendet, die ich letztes Jahr gebaut habe. Die Methoden sind wahrscheinlich etwas veraltet mit den neuesten APIs, aber es funktioniert gut. http://www.flushtracker.com/ – Matt

1

Hope this Sie hier helfen wird, eine Taste ist, und wenn Sie auf sie klicken Marker Bewegung von der Quelle zum Ziel Route. setRoutes-Methode wird verwendet, um die Route des Markers festzulegen.

function setRoutes(){ 

    var directionsDisplay = new Array(); 

    for (var i=0; i< startLoc.length; i++){ 

    var rendererOptions = { 
     map: map, 
     suppressMarkers : true, 
     preserveViewport: true 
    } 
    directionsService = new google.maps.DirectionsService(); 

    var travelMode = google.maps.DirectionsTravelMode.DRIVING; 

    var request = { 
     origin: startLoc[i], 
     destination: endLoc[i], 
     travelMode: travelMode 
    }; 

     directionsService.route(request,makeRouteCallback(i,directionsDisplay[i])); 

    } 

Route nach der Einstellung erstellen.

function makeRouteCallback(routeNum,disp){ 
     if (polyline[routeNum] && (polyline[routeNum].getMap() != null)) { 
     startAnimation(routeNum); 
     return; 
     } 
     return function(response, status){ 

      if (status == google.maps.DirectionsStatus.OK){ 

      var bounds = new google.maps.LatLngBounds(); 
      var route = response.routes[0]; 
      startLocation[routeNum] = new Object(); 
      endLocation[routeNum] = new Object(); 


      polyline[routeNum] = new google.maps.Polyline({ 
      path: [], 
      strokeColor: '#FFFF00', 
      strokeWeight: 3 
      }); 

      poly2[routeNum] = new google.maps.Polyline({ 
      path: [], 
      strokeColor: '#FFFF00', 
      strokeWeight: 3 
      });  


      // For each route, display summary information. 
      var path = response.routes[0].overview_path; 
      var legs = response.routes[0].legs; 


      disp = new google.maps.DirectionsRenderer(rendererOptions);  
      disp.setMap(map); 
      disp.setDirections(response); 


      //Markers    
      for (i=0;i<legs.length;i++) { 
       if (i == 0) { 
       startLocation[routeNum].latlng = legs[i].start_location; 
       startLocation[routeNum].address = legs[i].start_address; 
       // marker = google.maps.Marker({map:map,position: startLocation.latlng}); 
       marker[routeNum] = createMarker(legs[i].start_location,"start",legs[i].start_address,"green"); 
       } 
       endLocation[routeNum].latlng = legs[i].end_location; 
       endLocation[routeNum].address = legs[i].end_address; 
       var steps = legs[i].steps; 

       for (j=0;j<steps.length;j++) { 
       var nextSegment = steps[j].path;     
       var nextSegment = steps[j].path; 

       for (k=0;k<nextSegment.length;k++) { 
        polyline[routeNum].getPath().push(nextSegment[k]); 
        //bounds.extend(nextSegment[k]); 
       } 

       } 
      } 

     }  

     polyline[routeNum].setMap(map); 
     //map.fitBounds(bounds); 
     startAnimation(routeNum); 

    } // else alert("Directions request failed: "+status); 

    } 

} 

Endlich nennen wir Animationsfunktion

function startAnimation(index) { 
     if (timerHandle[index]) clearTimeout(timerHandle[index]); 
     eol[index]=polyline[index].Distance(); 
     map.setCenter(polyline[index].getPath().getAt(0)); 

     poly2[index] = new google.maps.Polyline({path: [polyline[index].getPath().getAt(0)], strokeColor:"#FFFF00", strokeWeight:3}); 

     timerHandle[index] = setTimeout("animate("+index+",50)",2000); // Allow time for the initial map display 
} 

Sie vollständigen Code zu finden beginnen auf GeekOnJava Blog und diesen Code kopieren und sie und die Ausgabe auf youtube laufen.

+0

Ich möchte den Marker in der Mitte für mehr als 2 Sekunden stoppen und neu starten, habe ich versucht, den Schlaf in updatepoly Funktion zu machen, aber es nicht zu stoppen? Kannst du mir hier helfen? – Raghu

1

Hier ist meine Lösung, die mit der v3-API funktioniert. Dies animiert den Marker nicht mit einer festen Geschwindigkeit, sondern basierend auf der berechneten Routendauer. Es gibt einen Geschwindigkeitsfaktor, so können Sie zum Beispiel die Route 10x schneller als in der Realität fahren.

Ich habe versucht, es so einfach wie möglich zu machen. Fühlen Sie sich frei, es zu benutzen.

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); 
} 

Verbrauch:

setAnimatedRoute("source address or LatLng ...", "destination address or LatLng ...", map); 
// start simulation on button click... 
$("#simulateRouteButton").click(function() { 
    startRouteAnimation(agentMarker); 
}); 
Verwandte Themen