Display multiple Google Map markers and directions on one map

I would like to display multiple Google Map routes on a single Google map. Data is taken from an XML file with multiple markers. Each marker has a start point and an end point (in the form of latitude and longitude values). These tokens are then added to the map, and a call to the Google Maps Directions Service is made to route between the start and end points of each token.

The problem I am facing is that only one route is drawn (if I refresh the page, it seems to just select one of the markers at random and draw directions between the two markers). Other markers are not displayed at all.

I have a console.logged for loop to verify that it is running for each token in XML (it is). I assume this is related to these two lines, but this assumption ...

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

I read this question - Using the Google Maps 3 API to get multiple routes on a map , but I don’t really understand the answer / know how appropriate this is my situation. Thanks.

  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
source share
1 answer

I think the key point in the answer you linked is that each route needs its own DirectionsRenderer object. And he doesn't mention it, but it seems likely that each route should also have its own DirectionsService object. You share one of these objects among all your routes. I suspect that these shared objects are overwritten for each route.

Here's an update that should fix this by creating new objects for each route:

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

I also took the liberty of correcting and simplifying a few things:

  • Moved the marker loop body to a separate addMarkerPair function for better readability.
  • Added get function inside addMarkerPair as a shortcut for pair.getAttribute .
  • Used + instead of parseInt . Or one will do the same; I like + for its brevity.
  • Add some missing var declarations.
  • Instead of global variables, the required calcRoute parameters are calcRoute as function parameters.
  • Used $.get instead of downloadUrl . There is no need for your own function when jQuery is already there.

In addition, as another alternative to XML parsing, you can use jQuery to access XML elements. But I stuck with the code closer to how you do it.

+4
source

All Articles