简体   繁体   中英

Issue with infoWindows with multiple markers and directionsDisplay variables in Google Maps API v3

I'm trying to display how distance and how minutes are between two markers in Google Maps API v3 and use these information to override the default infoWindow text that appears when the directionsService is fired, I think there is a asyncronous problem with calcRoute() and the infoWindows . This is an example code that reproduces the error.

<html>
<head>
    <meta charset='utf-8'>
    <script src="http://maps.google.com/maps/api/js?sensor=true" type="text/javascript"></script>
    <script>
        var directionsDisplay = new google.maps.DirectionsRenderer({ 'map': map }); 
        var directionsService = new google.maps.DirectionsService();
        var map;
        function initMap(locations){
            function calcRoute(latdest, lngdest) {
                var start = new google.maps.LatLng(-23.571064, -46.645424);
                var end = new google.maps.LatLng(latdest, lngdest)
                var request = {origin:start,destination:end,travelMode: google.maps.TravelMode.DRIVING};
                directionsService.route(request, function(result, status){
                    if (status == google.maps.DirectionsStatus.OK){
                        directionsDisplay.setDirections(result);
                    }
                });
            }
            map = new google.maps.Map(document.getElementById('mapcanvas'), {zoom: 10,center: new google.maps.LatLng(-23.571064, -46.645424),mapTypeId: google.maps.MapTypeId.ROADMAP
            });
            directionsDisplay.setMap(map);

            var infowindow = new google.maps.InfoWindow();

            var marker, i;
            var image = null;
            for (i = 0; i < locations.length; i++) {
              marker = new google.maps.Marker({
                position: new google.maps.LatLng(locations[i][1], locations[i][2]),
                map: map
              });

              google.maps.event.addListener(marker, 'click', (function(marker, i) {
                return function() {
                    calcRoute(locations[i][1], locations[i][2]);
                    infowindow.setContent(directionsDisplay.directions.routes[0].legs[0].distance.text+" - "+directionsDisplay.directions.routes[0].legs[0].duration.text);
                    infowindow.open(map, marker);
                }
              })(marker, i));
            }
        }
    </script>
</head>
<body onload='initMap([["Vila Noemia", -23.670237, -46.467286],["Osasco", -23.535465, -46.794234],["Guarulhos", -23.458911, -46.526912]]);'>
    <div id="mapcanvas" style="width:100%;height:100%;">
    </div>
</body>

Please note that if you click one marker, and then another, the second marker will show the desired result but that information belongs to the first marker... How can I force the order of execution to avoid the async?

Thanks in advance...

You want to open the infowindow in the DirectionsService callback function where the data is available.

(you may also want to suppress the existing markers from the directions service)

InfoWindow click listener:

    google.maps.event.addListener(marker, 'click', (function (marker, i) {
        return function () {
            calcRoute(locations[i][1], locations[i][2]);
            infowindow.open(map, marker);
        }
    })(marker, i));

Updated calcRoute function:

function calcRoute(latdest, lngdest) {
    var start = new google.maps.LatLng(-23.571064, -46.645424);
    var end = new google.maps.LatLng(latdest, lngdest)
    var request = {
        origin: start,
        destination: end,
        travelMode: google.maps.TravelMode.DRIVING
    };
    directionsService.route(request, function (result, status) {
        if (status == google.maps.DirectionsStatus.OK) {
            directionsDisplay.setDirections(result);
            infowindow.setContent(directionsDisplay.directions.routes[0].legs[0].distance.text + " - " + directionsDisplay.directions.routes[0].legs[0].duration.text);
        }
    });
}

proof of concept fiddle

code snippet:

 var directionsDisplay = new google.maps.DirectionsRenderer({ map: map, suppressMarkers: true }); var directionsService = new google.maps.DirectionsService(); var map; var infowindow = new google.maps.InfoWindow(); function initMap(locations) { function calcRoute(latdest, lngdest) { var start = new google.maps.LatLng(-23.571064, -46.645424); var end = new google.maps.LatLng(latdest, lngdest) var request = { origin: start, destination: end, travelMode: google.maps.TravelMode.DRIVING }; directionsService.route(request, function(result, status) { if (status == google.maps.DirectionsStatus.OK) { directionsDisplay.setDirections(result); infowindow.setContent(directionsDisplay.directions.routes[0].legs[0].distance.text + " - " + directionsDisplay.directions.routes[0].legs[0].duration.text); } }); } map = new google.maps.Map(document.getElementById('mapcanvas'), { zoom: 10, center: new google.maps.LatLng(-23.571064, -46.645424), mapTypeId: google.maps.MapTypeId.ROADMAP }); directionsDisplay.setMap(map); var marker, i; var image = null; for (i = 0; i < locations.length; i++) { marker = new google.maps.Marker({ position: new google.maps.LatLng(locations[i][1], locations[i][2]), map: map }); google.maps.event.addListener(marker, 'click', (function(marker, i) { return function() { calcRoute(locations[i][1], locations[i][2]); infowindow.open(map, marker); } })(marker, i)); } } google.maps.event.addDomListener(window, 'load', function() { initMap([ ["Vila Noemia", -23.670237, -46.467286], ["Osasco", -23.535465, -46.794234], ["Guarulhos", -23.458911, -46.526912] ]); }); 
 html, body, #map_canvas { height: 500px; width: 500px; margin: 0px; padding: 0px } 
 <script src="https://maps.googleapis.com/maps/api/js"></script> <div id="mapcanvas" style="width:100%;height:100%;"></div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM