2009-03-20 18 views
16

Ho scritto una piccola applicazione per un dispositivo palmare utilizzando JavaScript e le API di Google Maps, ora ho bisogno di spostare l'icona del mio indicatore ovunque sulla mappa lungo un percorso utilizzando una funzione timer. Ho un'icona uomo e ho bisogno di spostarlo automaticamente sulla mappa. Come posso fare questo?Come animare un indicatore personalizzato di Google Maps lungo un percorso?

+0

ho modificato il titolo in modo da riflettere il contenuto della domanda. @jyothi: quando pubblichi una domanda, ti preghiamo di prenderti il ​​tempo di rivederne il contenuto. Con soli 2 minuti di revisione extra, puoi migliorare la qualità del 100%, con l'aspettativa di risposte migliori e migliori. –

+0

k signore grazie, puoi rispondere alla mia domanda –

+0

@jyothi hai trovato una soluzione a questo ho bisogno di fare esattamente la stessa cosa su un'applicazione mappa. Puoi far luce se hai raggiunto come è stato realizzato. – devdar

risposta

0

Non sposta nulla automaticamente, ma è necessario controllare l'esperimento Google Drive di phatfusion. Guardare il codice potrebbe aiutarti.

8

Sfortunatamente, non esiste una funzione di movimento marcatore automatico nella raccolta GMaps ufficiale.

Tuttavia, se si dispone di un GRoute, ciò significa che si dispone di una serie di punti. Per eseguire un ciclo attraverso i passi del percorso, si potrebbe usare qualcosa di simile:

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

Certo, probabilmente si vorrà fare questo in modo asincrono utilizzando i timer:

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

Per il movimento ancora più liscia, è potrebbe interpolare i punti di quelli che hai già.

+0

Questa funzionalità è disponibile in Google Maps V3?L'array "steps" restituito da DirectionsService sembra solo includere i passi delle direzioni (cioè girare a sinistra a così-e-così) invece dei singoli punti che formano la linea renderizzata. – Kevin

+0

@Puskvor è possibile continuare ad incrementare una coordinata latlong per simulare un percorso, il percorso non deve essere solo sulle strade. – devdar

+1

@dev_darin: Sì. Tuttavia, non tutte le rotte sono linee rette; tra i vari punti del percorso, il tuo approccio è naturalmente percorribile. – Piskvor

16

Un esempio piuttosto fresco è qui:

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

+0

Quella pagina utilizza una versione precedente della libreria all'indirizzo http://econym.org.uk/gmap/epoly.htm che contiene alcune utili funzioni di utilità che è possibile utilizzare per trovare il lat-long di una posizione lungo un percorso. Dovrebbe rendere molto più facile costruire un marcatore animato. –

+0

Solo per interesse ho usato anche una tecnica simile su un sito che ho comprato l'anno scorso. i metodi sono probabilmente un po 'obsoleti con le ultime API ma funziona bene. http://www.flushtracker.com/ – Matt

1

Spero che questo vi aiuterà ecco un bottone e quando si fa clic su di essi marcatore movimento da origine al percorso di destinazione. Il metodo setRoutes viene utilizzato per impostare il percorso dell'indicatore.

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

    } 

Rendere il percorso dopo averli impostati.

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

    } 

} 

Finalmente noi chiamiamo avviare la funzione di animazione

codice completo
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 
} 

Si può essere trovato su GeekOnJava blog e copiare il codice e li e l'uscita girare su youtube.

+0

Vorrei fare in modo che il marcatore si fermi al punto medio per oltre 2 secondi e ricominciare, ho provato a fare in modo che il sonno funzioni updatepoly ma non si fermi? Puoi aiutarmi qui – Raghu

1

Ecco la mia soluzione che funziona con l'API v3. Questo anima il marcatore non con una velocità fissa, ma in base alla durata del percorso calcolato. C'è un fattore di velocità, quindi ad esempio puoi percorrere il percorso 10 volte più velocemente che nella realtà.

Ho provato a farlo nel modo più semplice possibile. Sentiti libero di usarlo.

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