在一张地图上显示多个Google地图标记和路线

问题描述:

我想将多个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() {} 

我想在您链接到答案的关键点是,每个路线都需要自己的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