1

지도에 폴리선이 그려진 여러 마커가 있습니다. 각 마커의 동시 이동을 시뮬레이트하기 위해 폴리 라인 경로를 따라 각 마커를 이동하고 싶습니다.여러 마커 애니메이션하기

저는이 작업을 수행하는 데 문제가 있습니다. 마지막 마커 만 이동 중이며 나머지는 그렇지 않습니다. 이 프로그래밍 기술을 사용하는 것에 익숙하지 않은 나는 내 코드에서 특히 각 마커에 애니메이션을 적용하는 방식이 잘못되었다고 생각합니다. 이것에 대한 지침이 필요해.

여기 내 작업은 지금까지의 : 당신은 varfor() 내부 루프가 선언되지 않은 변수를 많이 사용하고 Jsbin DEMO

var startLoc = new Array(); 
    startLoc[0] = 'rio claro, trinidad'; 
    startLoc[1] = 'preysal, trinidad'; 
    startLoc[2] = 'san fernando, trinidad'; 
    startLoc[3] = 'couva, trinidad'; 

    var endLoc = new Array(); 
    endLoc[0] = 'princes town, trinidad'; 
    endLoc[1] = 'tabaquite, trinidad'; 
    endLoc[2] = 'mayaro, trinidad'; 
    endLoc[3] = 'arima, trinidad'; 


    var Colors = ["#FF0000", "#00FF00", "#0000FF"]; 


function initialize() { 

    infowindow = new google.maps.InfoWindow(
    { 
     size: new google.maps.Size(150,50) 
    }); 

    var myOptions = { 
     zoom: 10, 
     mapTypeId: google.maps.MapTypeId.ROADMAP 
    } 
    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); 

    address = 'Trinidad and Tobago' 
    geocoder = new google.maps.Geocoder(); 
    geocoder.geocode({ 'address': address}, function(results, status) { 
    map.setCenter(results[0].geometry.location); 

    }); 
    } 


function createMarker(latlng, label, html) { 
// alert("createMarker("+latlng+","+label+","+html+","+color+")"); 
    var contentString = '<b>'+label+'</b><br>'+html; 
    var marker = new google.maps.Marker({ 
     position: latlng, 
     map: map, 
     title: label, 
     zIndex: Math.round(latlng.lat()*-100000)<<5 
     }); 
     marker.myname = label; 


    google.maps.event.addListener(marker, 'click', function() { 
     infowindow.setContent(contentString); 
     infowindow.open(map,marker); 
     }); 
    return marker; 
} 

function setRoutes(){ 

    var directionsDisplay = new Array(); 

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

    var rendererOptions = { 
     map: map, 
     suppressMarkers : 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(directionsDisplay[i])); 

    } 


    function makeRouteCallback(disp){ 
     return function(response, status){ 

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

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


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

      poly2 = 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; 


      //Routes 
      if (status == google.maps.DirectionsStatus.OK){ 
       console.log(response); 

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


      //Markers    
      for (i=0;i<legs.length;i++) { 
       if (i == 0) { 
       startLocation.latlng = legs[i].start_location; 
       startLocation.address = legs[i].start_address; 
       // marker = google.maps.Marker({map:map,position: startLocation.latlng}); 
       marker = createMarker(legs[i].start_location,"start",legs[i].start_address,"green"); 
       } 
       endLocation.latlng = legs[i].end_location; 
       endLocation.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.getPath().push(nextSegment[k]); 
        //bounds.extend(nextSegment[k]); 
       } 

       } 
      }  

      } 


     } 
     polyline.setMap(map); 
     //map.fitBounds(bounds); 
     startAnimation(); 




    } 

    } 

} 

    var lastVertex = 1; 
    var stepnum=0; 
    var step = 50; // 5; // metres 
    var tick = 100; // milliseconds 
    var eol; 
//----------------------------------------------------------------------     
function updatePoly(d) { 
// Spawn a new polyline every 20 vertices, because updating a 100-vertex poly is too slow 
    if (poly2.getPath().getLength() > 20) { 
      poly2=new google.maps.Polyline([polyline.getPath().getAt(lastVertex-1)]); 
      // map.addOverlay(poly2) 
     } 

    if (polyline.GetIndexAtDistance(d) < lastVertex+2) { 
     if (poly2.getPath().getLength()>1) { 
      poly2.getPath().removeAt(poly2.getPath().getLength()-1) 
     } 
      poly2.getPath().insertAt(poly2.getPath().getLength(),polyline.GetPointAtDistance(d)); 
    } else { 
     poly2.getPath().insertAt(poly2.getPath().getLength(),endLocation.latlng); 
    } 
} 
//---------------------------------------------------------------------------- 

function animate(d) { 

    if (d>eol) { 

     marker.setPosition(endLocation.latlng); 
     return; 
    } 
    var p = polyline.GetPointAtDistance(d); 

    //map.panTo(p); 
    marker.setPosition(p); 
    updatePoly(d); 
    timerHandle = setTimeout("animate("+(d+step)+")", tick); 
} 

//------------------------------------------------------------------------- 

function startAnimation() { 
     eol=polyline.Distance(); 
     map.setCenter(polyline.getPath().getAt(0)); 

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

     setTimeout("animate(50)",2000); // Allow time for the initial map display 
} 

//----------------------------------------------------------------------------  



</script> 
</head> 
<body onload="initialize()"> 

<div id="tools"> 

    <button onclick="setRoutes();">Start</button> 

</div> 

<div id="map_canvas" style="width:100%;height:100%;"></div> 

+0

'makeRouteCallback (directionsDisplay는 [I])'잘못된해야합니다. 'directionsDisplay'는 절대로 채워지지 않는 빈 배열입니다. –

답변

2

여러 마커를 애니메이트하려면 여러 마커를 처리하기 위해 animate 및 startAnimation 함수를 변경해야합니다 (아마 모든 변수를 배열로 만듭니다).

example

코드는 :

var map; 
 
    var directionDisplay; 
 
    var directionsService; 
 
    var stepDisplay; 
 
    
 
    var position; 
 
    var marker = []; 
 
    var polyline = []; 
 
    var poly2 = []; 
 
    var poly = null; 
 
    var startLocation = []; 
 
    var endLocation = []; 
 
    var timerHandle = []; 
 
    
 
    
 
    var speed = 0.000005, wait = 1; 
 
    var infowindow = null; 
 
    
 
    var myPano; 
 
    var panoClient; 
 
    var nextPanoId; 
 
    
 
    var startLoc = new Array(); 
 
    startLoc[0] = 'rio claro, trinidad'; 
 
    startLoc[1] = 'preysal, trinidad'; 
 
    startLoc[2] = 'san fernando, trinidad'; 
 
    startLoc[3] = 'couva, trinidad'; 
 

 
    var endLoc = new Array(); 
 
    endLoc[0] = 'princes town, trinidad'; 
 
    endLoc[1] = 'tabaquite, trinidad'; 
 
    endLoc[2] = 'mayaro, trinidad'; 
 
    endLoc[3] = 'arima, trinidad'; 
 

 

 
    var Colors = ["#FF0000", "#00FF00", "#0000FF"]; 
 

 

 
function initialize() { 
 

 
    infowindow = new google.maps.InfoWindow(
 
    { 
 
     size: new google.maps.Size(150,50) 
 
    }); 
 

 
    var myOptions = { 
 
     zoom: 10, 
 
     mapTypeId: google.maps.MapTypeId.ROADMAP 
 
    } 
 
    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); 
 

 
    address = 'Trinidad and Tobago' 
 
    geocoder = new google.maps.Geocoder(); 
 
    geocoder.geocode({ 'address': address}, function(results, status) { 
 
    map.fitBounds(results[0].geometry.viewport); 
 

 
    }); 
 
    // setRoutes(); 
 
    } 
 

 

 
function createMarker(latlng, label, html) { 
 
// alert("createMarker("+latlng+","+label+","+html+","+color+")"); 
 
    var contentString = '<b>'+label+'</b><br>'+html; 
 
    var marker = new google.maps.Marker({ 
 
     position: latlng, 
 
     map: map, 
 
     title: label, 
 
     zIndex: Math.round(latlng.lat()*-100000)<<5 
 
     }); 
 
     marker.myname = label; 
 

 

 
    google.maps.event.addListener(marker, 'click', function() { 
 
     infowindow.setContent(contentString); 
 
     infowindow.open(map,marker); 
 
     }); 
 
    return marker; 
 
} 
 

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

 
    } 
 

 

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

 
    } 
 

 
} 
 

 
    var lastVertex = 1; 
 
    var stepnum=0; 
 
    var step = 50; // 5; // metres 
 
    var tick = 100; // milliseconds 
 
    var eol= []; 
 
//----------------------------------------------------------------------     
 
function updatePoly(i,d) { 
 
// Spawn a new polyline every 20 vertices, because updating a 100-vertex poly is too slow 
 
    if (poly2[i].getPath().getLength() > 20) { 
 
      poly2[i]=new google.maps.Polyline([polyline[i].getPath().getAt(lastVertex-1)]); 
 
      // map.addOverlay(poly2) 
 
     } 
 

 
    if (polyline[i].GetIndexAtDistance(d) < lastVertex+2) { 
 
     if (poly2[i].getPath().getLength()>1) { 
 
      poly2[i].getPath().removeAt(poly2[i].getPath().getLength()-1) 
 
     } 
 
      poly2[i].getPath().insertAt(poly2[i].getPath().getLength(),polyline[i].GetPointAtDistance(d)); 
 
    } else { 
 
     poly2[i].getPath().insertAt(poly2[i].getPath().getLength(),endLocation[i].latlng); 
 
    } 
 
} 
 
//---------------------------------------------------------------------------- 
 

 
function animate(index,d) { 
 
    if (d>eol[index]) { 
 

 
     marker[index].setPosition(endLocation[index].latlng); 
 
     return; 
 
    } 
 
    var p = polyline[index].GetPointAtDistance(d); 
 

 
    //map.panTo(p); 
 
    marker[index].setPosition(p); 
 
    updatePoly(index,d); 
 
    timerHandle[index] = setTimeout("animate("+index+","+(d+step)+")", tick); 
 
} 
 

 
//------------------------------------------------------------------------- 
 

 
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 
 
} 
 

 
//----------------------------------------------------------------------------  
 
google.maps.event.addDomListener(window,'load',initialize);
html{height:100%;} 
 
body{height:100%;margin:0px;font-family: Helvetica,Arial;}
<script type="text/javascript" src="http://maps.google.com/maps/api/js"></script> 
 
<script type ="text/javascript" src="http://www.geocodezip.com/scripts/v3_epoly.js"></script> 
 

 
<div id="tools"> 
 

 
    <button onclick="setRoutes();">Start</button> 
 

 
</div> 
 

 
<div id="map_canvas" style="width:100%;height:100%;"></div>

+0

대단히 고맙습니다. Google 애널리틱스 태그가 요청에 따라 삭제되었습니다. – devdar

+0

사용자가 '시작'버튼을 여러 번 클릭하면 현재 동일한 코드가 다시 생성됩니다. 중복 마커를 방지하기 위해 마커가 있는지 확인했습니다. 그러나 마주 보는 문제는 마커 애니메이션이 시작 버튼을 두 번 클릭하면 신속한 동작으로 앞뒤로 움직이는 것이 이상하다는 것입니다. 어떻게 멈출 수 있고 그 원인을 알려주시겠습니까? – devdar

+1

마커 애니메이션을 다시 시작하려면 기존 타이머를 지워야합니다. 예제를 수정했습니다. – geocodezip

0

. 특히 for (i=...makeRouteCallback(disp)에 이미 의 변수가있는 경우 setRoutes()에 있습니다. 나는 이것이이 행동을 일으키는 것 같아요.