2013-04-27 191 views
4

我想將多個Google地圖路線輸出到一個Google地圖上。數據來自具有多個標記的XML文件。每個標記都有一個起點和一個終點(以緯度和經度值的形式)。然後將這些標記添加到地圖中,並調用Google Maps Directions Service來繪製每個標記的起點和終點之間的路線。在一張地圖上顯示多個Google地圖標記和路線

我遇到的問題是隻繪製一條路線(如果我刷新頁面,它似乎只是隨機選取其中一個標記並繪製這兩個標記之間的方向)。其他標記完全不顯示。

我已經console.logged for循環來檢查它是否運行在XML(這是)每個標記。我猜這是什麼做這裏這兩條線,但是這是一個猜測...

directionsDisplay = new google.maps.DirectionsRenderer(); 
directionsService = new google.maps.DirectionsService(); 

我讀過這個問題 - Using Google Maps 3 API to get multiple routes on a Map,但真的不理解答案/知道如何與我的情況有關。謝謝。

jQuery(document).ready(function($) { 

    var map = new google.maps.Map(document.getElementById("map_canvas"), { 
     zoom: 13, 
     mapTypeId: 'roadmap' 
    }); 

    // Try HTML5 geolocation 
    if(navigator.geolocation) { 
     navigator.geolocation.getCurrentPosition(function(position) { 
      var pos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); 
      map.setCenter(pos); 
      map.setZoom(13); 
     }, function() { 
      handleNoGeolocation(true); 
     }); 
    } else { 
     // Browser doesn't support Geolocation 
     handleNoGeolocation(false); 
    } 

    directionsDisplay = new google.maps.DirectionsRenderer(); 
    directionsService = new google.maps.DirectionsService(); 

    // Change this depending on the name of your PHP file 
    downloadUrl("xml.php", function(data) { 
     var xml = data.responseXML; 
     var markers = xml.documentElement.getElementsByTagName("marker"); 
     for (var i = 0; i < markers.length; i++) { 
      var title = markers[i].getAttribute("title"); 
      mode = markers[i].getAttribute("mode"); 
      startpoint = new google.maps.LatLng(
       parseFloat(markers[i].getAttribute("startlat")), 
       parseFloat(markers[i].getAttribute("startlng"))); 
      endpoint = new google.maps.LatLng(
       parseFloat(markers[i].getAttribute("endlat")), 
       parseFloat(markers[i].getAttribute("endlng"))); 
      calcRoute(); 
      console.log('marker'); 
     } 
    }); 
    directionsDisplay.setMap(map); 

}); 


function calcRoute() { 
    var request = { 
     origin: startpoint, 
     destination: endpoint, 
     //waypoints: waypts, 
     travelMode: google.maps.DirectionsTravelMode[mode] 
    }; 
    directionsService.route(request, function(response, status) { 
     if (status == google.maps.DirectionsStatus.OK) { 
      directionsDisplay.setDirections(response); 
     } 
    }); 
} 

function downloadUrl(url, callback) { 
    var request = window.ActiveXObject ? 
    new ActiveXObject('Microsoft.XMLHTTP') : 
    new XMLHttpRequest; 

    request.onreadystatechange = function() { 
     if (request.readyState == 4) { 
      request.onreadystatechange = doNothing; 
      callback(request, request.status); 
     } 
    }; 

    request.open('GET', url, true); 
    request.send(null); 
} 

function doNothing() {} 

回答

4

我想在您鏈接到答案的關鍵點是,每個路線都需要自己的DirectionsRenderer對象。它沒有提到它,但似乎每條路線都應該有它自己的DirectionsService對象。您在所有路線中共享這些對象中的單個對象。我懷疑這些共享對象正在被覆蓋每個路線。

這裏是一個應該解決的是通過爲每個路由創建新對象的更新:

jQuery(document).ready(function($) { 

    var map = new google.maps.Map(document.getElementById("map_canvas"), { 
     zoom: 13, 
     mapTypeId: 'roadmap' 
    }); 

    // Try HTML5 geolocation 
    if(navigator.geolocation) { 
     navigator.geolocation.getCurrentPosition(function(position) { 
      var pos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); 
      map.setCenter(pos); 
      map.setZoom(13); 
     }, function() { 
      handleNoGeolocation(true); 
     }); 
    } else { 
     // Browser doesn't support Geolocation 
     handleNoGeolocation(false); 
    } 

    // Change this depending on the name of your PHP file 
    $.get("xml.php", function(xml) { 
     var markers = xml.documentElement.getElementsByTagName("marker"); 
     for (var i = 0; i < markers.length; i++) { 
      addMarkerPair(markers[i]); 
     } 
    }, 'xml'); 
}); 

function addMarkerPair(pair) { 
    function get(name) { 
     return pair.getAttribute(name); 
    } 
    var title = get("title"); 
    var mode = get("mode"); 
    var startpoint = new google.maps.LatLng(
     +get("startlat"), 
     +get("startlng") 
    ); 
    var endpoint = new google.maps.LatLng(
     +get("endlat"), 
     +get("endlng") 
    ); 
    calcRoute(mode, startpoint, endpoint); 
    console.log('marker'); 
} 

function calcRoute(mode, startpoint, endpoint) { 
    var directionsService = new google.maps.DirectionsService(); 
    var directionsDisplay = new google.maps.DirectionsRenderer(); 
    directionsDisplay.setMap(map); 
    var request = { 
     origin: startpoint, 
     destination: endpoint, 
     //waypoints: waypts, 
     travelMode: google.maps.DirectionsTravelMode[mode] 
    }; 
    directionsService.route(request, function(response, status) { 
     if (status == google.maps.DirectionsStatus.OK) { 
      directionsDisplay.setDirections(response); 
     } 
    }); 
} 

我也採取了固定的自由和簡化的幾件事情:

  1. 移動標記循環體出於更好的可讀性出於單獨的addMarkerPair功能。
  2. addMarkerPair內增加了一個get函數,作爲pair.getAttribute的簡寫。
  3. 使用+而不是parseInt。任何一個人都會做同樣的事情;爲了簡潔,我喜歡+
  4. 添加幾個丟失的var聲明。
  5. 將所需參數傳遞給calcRoute作爲函數參數而不是全局變量。
  6. 使用$.get而不是downloadUrl。當jQuery擁有它時,不需要您自己的函數。

此外,作爲XML解析的另一種替代方法,您可以使用jQuery來訪問XML元素。但是我更接近於你已經在做的代碼。

+0

謝謝你的答案邁克爾。我已經嘗試了你的代碼,但得到了'未捕獲的TypeError:無法在此行讀取'undefined'屬性'documentElement' - var markers = xml.documentElement.getElementsByTagName(「marker」);有任何想法嗎? – GuerillaRadio 2013-04-27 18:44:32

+0

對不起,我的糟糕,我忘了仔細檢查代碼,當我改變它使用'$ .get()'而不是'downloadUrl()'時。我更新了代碼以移除'var xml = data.responseXML;',因爲這已不再需要,並且在'$ .get()'調用中添加一個顯式的''xml'數據類型(最後一個參數,在回調之後)。如果你的服務器爲XML文件設置了正確的MIME類型頭信息,那麼這可能不是必須的,但是添加該參數可以確保jQuery爲你解析XML。 – 2013-04-27 19:39:53

+0

非常完美,非常感謝Michael。 – GuerillaRadio 2013-04-27 19:51:08