2013-05-11 19 views
3

喜歡在標題:如何實現多義線捕捉到標記拖動街道?我花了很多時間尋求答案,但我已經放棄了。如果沒有DirectionsRenderer,我只想使用DirectionsService。下面是我清理版本的代碼,其中不是爲每個工作而僅爲最後一個標記和路徑進行捕捉工作不清理。幫助將不勝感激。如何實現可拖動捕捉道路折線?

我對jsfiddle這裏代碼:

var map, 
path = [], 
    markers = [], 
    directionsService = new google.maps.DirectionsService(), 
    poly; 

function addMarker(p) { 
    var marker = new google.maps.Marker({ 
     position: p, 
     map: map, 
     draggable: true 
    }); 
    markers.push(marker); 

    google.maps.event.addListener(marker, "drag", function() { 
     var request = { 
      origin: path[path.length - 1], 
      destination: marker.getPosition(), 
      travelMode: google.maps.DirectionsTravelMode.DRIVING 
     }; 
     directionsService.route(request, function (response, status) { 
      if (status == google.maps.DirectionsStatus.OK) { 
       marker.setPosition(response.routes[0].legs[0].end_location); 
       path = path.concat(response.routes[0].overview_path); 
       poly.setPath(path); 
      } 
     }); 
    }); 
} 

function initialize() { 
    var myOptions = { 
     zoom: 17, 
     center: new google.maps.LatLng(40.7143528, -74.00597310000001), 
     mapTypeId: google.maps.MapTypeId.ROADMAP, 
     draggableCursor: "crosshair" 
    } 

    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); 

    google.maps.event.addListener(map, 'click', function (event) { 

     if (path.length == 0) { 
      path.push(event.latLng); 
      poly = new google.maps.Polyline({ 
       map: map 
      }); 
      poly.setPath(path); 
      addMarker(event.latLng); 
     } else { 
      var request = { 
       origin: path[path.length - 1], 
       destination: event.latLng, 
       travelMode: google.maps.DirectionsTravelMode.DRIVING 
      }; 
      directionsService.route(request, function (response, status) { 
       if (status == google.maps.DirectionsStatus.OK) { 
        addMarker(response.routes[0].legs[0].end_location); 

        path = path.concat(response.routes[0].overview_path); 
        poly.setPath(path); 
       } 
      }); 
     } 
    }); 
} 

回答

3

這是一個相當困難的同時保持良好的性能,下面我的代碼中陳述的理由實現的事情。捕捉道路雖然拖動標記是您的要求,但這樣做存在限制和問題。我會爲您提供代碼,以便在拖動時不會捕捉道路,而是在標記拖動的結束處。請注意,如果取消註釋下面的一行代碼,則可以按照您的要求拖動到道路上,但由於下面列出的原因,我建議您不要這樣做。請參閱評論對這裏的我的代碼結束,在這裏http://jsfiddle.net/VvR5k/1/

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
<head> 
<meta http-equiv="content-type" content="text/html; charset=utf-8"> 
<title>Some Title</title> 
</head> 
<body> 
<p>Click on map to place markers, drag markers to change route</p> 
<p>Please view comment block towards end of javascript code!</p> 
<p><button type="button" onclick="resetMarkers();">Reset Markers</button></p> 
<div id="map_canvas" style="width:800px; height:600px;"> 
</div> 
<script src="http://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script> 
<script type="text/javascript"> 

function init() { 
    var markers = [], 
     segments = [], 
     myOptions = { 
      zoom: 12, 
      center: new google.maps.LatLng(34.0504, -118.2444), 
      mapTypeId: google.maps.MapTypeId.ROADMAP, 
      disableDoubleClickZoom: true, 
      draggableCursor: "crosshair" 
     }, 
     alphas = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''), 
     alphaIdx = 0, 
     map = new google.maps.Map(document.getElementById("map_canvas"), myOptions), 
     service = new google.maps.DirectionsService(), 
     poly = new google.maps.Polyline({ 
      map: map, 
      strokeColor: '#00FFFF', 
      strokeOpacity: 0.6, 
      strokeWeight: 5 
    }); 
    window.resetMarkers = function() { 
     for (var i = 0; i < markers.length; i++) { 
      markers[i].setMap(null); 
     } 
     alphaIdx = 0; 
     segments = []; 
     markers = []; 
     poly.setPath([]); 
    }; 
    function getSegmentsPath() { 
     var a, i, 
      len = segments.length, 
      arr = []; 
     for (i = 0; i < len; i++) { 
      a = segments[i]; 
      if (a && a.routes) { 
       arr = arr.concat(a.routes[0].overview_path); 
      } 
     } 
     return arr; 
    } 

    function addSegment(start, end, segIdx) { 
     service.route(
      { 
       origin: start, 
       destination: end, 
       travelMode: google.maps.DirectionsTravelMode.DRIVING 
      }, 
      function (result, status) { 
       if (status == google.maps.DirectionsStatus.OK) { 
        //store the entire result, as we may at some time want 
        //other data from it, such as the actual directions 
        segments[segIdx] = result; 
        poly.setPath(getSegmentsPath()); 
       } 
      } 
     ); 
    } 
    google.maps.event.addListener(map, "click", function (e) { 
     //limiting the number of markers added to no more than 26, as if we have 
     //that many we have used up all our alphabetical characters for the icons 
     if (alphaIdx > 25) { 
      return; 
     } 
     var evtPos = e.latLng, 
      c = alphas[alphaIdx++], 
      marker = new google.maps.Marker({ 
       map: map, 
       position: evtPos, 
       draggable: true, 
       icon: 'http://www.google.com/mapfiles/marker'+ c +'.png' 
     }); 
     marker.segmentIndex = markers.length - 1; 
     marker.iconChar = c;//just storing this for good measure, may want at some time 
     function updateSegments() { 
      var start, end, inserts, i, 
       idx = this.segmentIndex, 
       segLen = segments.length, //segLen will always be 1 shorter than markers.length 
       myPos = this.getPosition(); 
      if (segLen === 0) { //nothing to do, this is the only marker 
       return; 
      } 
      if (idx == -1) { //this is the first marker 
       start = [myPos]; 
       end = [markers[1].getPosition()]; 
       inserts = [0]; 
      } else if (idx == segLen - 1) { //this is the last marker 
       start = [markers[markers.length - 2].getPosition()]; 
       end = [myPos]; 
       inserts = [idx]; 
      } else {//there are markers both behind and ahead of this one in the 'markers' array 
       start = [markers[idx].getPosition(), myPos]; 
       end = [myPos, markers[idx + 2].getPosition()]; 
       inserts = [idx, idx + 1]; 
      } 
      for (i = 0; i < start.length; i++) { 
       addSegment(start[i], end[i], inserts[i]); 
      } 
     } 
     /********************************************************************** 
     Note that the line below which sets an event listener for the markers 
     'drag' event and which is commented out (uncomment it to test, 
     but I do not recommend using it in reality) causes us to constantly 
     poll google for DirectionsResult objects and may perform poorly at times 
     while a marker is being dragged, as the application must wait for a 
     directions request to be sent and received from google many many many 
     times while the marker is dragged. For these reasons, I personally would 
     only use the dragend event listener. Additionally, using the below line can 
     very quickly run you up against google maps api services usage limit of 
     2500 directions requests per day, as while a marker is being dragged it 
     could cause hundreds and hundreds of directions requests to be made! Not good! 
     see about usage limits: https://developers.google.com/maps/documentation/directions/#Limits 
     ***********************************************************************/ 
     //google.maps.event.addListener(marker, 'drag', updateSegments); 
     google.maps.event.addListener(marker, 'dragend', updateSegments); 
     markers.push(marker); 
     if (markers.length > 1) { 
      addSegment(markers[markers.length - 2].getPosition(), evtPos, marker.segmentIndex); 
     } 
    }); 
} 
init(); 

</script> 
</body> 
</html> 
+0

這是很好的參考代碼,就如何使標記捕捉到的道路有任何建議行動中可見? – 2014-03-17 11:05:22

+0

感謝astupidname,這段代碼真的幫助了我!現在我試圖找到一種方法在現有多段線上添加「控制點」(標記)。例如說我有一段很長的段落,我想點擊它的中間並在那裏添加一個新的標記。然後我可以從新標記中拖動路線。 任何人都有一個想法,我可以做到這一點? – 2014-06-26 15:26:43

+0

@KyleGoslan我面臨同樣的問題,我無法添加對齊路標 – 2017-10-13 02:29:37