Google地图方向渲染备用路线如何选择所需路径

时间:2016-09-01 07:04:45

标签: javascript google-maps google-maps-api-3

我正在撰写谷歌地图指示我正在关注谷歌的导航应用程序。

我能够通过DirectionsService获得所有可能的替代路线,并且可以为折线提供不同的颜色,我希望用户能够选择他想要的路径,只需点击多边形线,一些人怎么没找到任何东西此

我的代码:

directionsService.route(request, function(response, status) {
  var points = [];
  if (status == google.maps.DirectionsStatus.OK) {
    try {
      var polycolour = "";
      var Opacity = 0;
      //var PolyLine = '';
      for (var i = 0, len = response.routes.length; i < len; i++) {
        if (i == 0) {
          polycolour = "Blue";
          Opacity = 5;
        }
        else {
          polycolour = "grey";
          Opacity = 2;
        }
        directionsDisplay = new google.maps.DirectionsRenderer({
          map: map,
          directions: response,
          routeIndex: i,
          draggable : true,
          polylineOptions: {
            strokeColor: polycolour,
            strokeWeight: Opacity
          }
        });

        var infowindow2 = new google.maps.InfoWindow();
        //var step = 10;
        //alert(angular.toJson(response.routes[0].legs[0].steps[i]));

        infowindow2.setContent(""+((response.routes[i].legs[0].distance.value)/1000)+" KM");
        infowindow2.setPosition(response.routes[i].legs[0].steps[8].end_location);
        infowindow2.open(map);

      }
      //directionsDisplay.setMap(map);
      google.maps.event.addListener(directionsDisplay, 'click', function(){
        alert("helo");
      });
      //for (var k = 0, len = response.routes.length; k < len; k++) {
        //var myRoute = response.routes[k].legs[0];
        //for (var i = 0; i < myRoute.steps.length; i++) {
          //for (var j = 0; j < myRoute.steps[i].lat_lngs.length; j++) {
            // points.push(myRoute.steps[i].lat_lngs[j]);
          //}
        //}

        //var routLine = new google.maps.Polyline(
        //{
          //path: points,
          //strokeColor: "Red",
          //strokeOpacity: 0.5,
          // strokeWeight: 10
        // }
        // );
      // }
      // routLine.setMap(map)

      // Add a listener for the rightclick event on the routLine
      //google.maps.event.addListener(routLine, 'click', function(e){
      //try {
        //alert(angular.toJson(e));
      //}
      //catch (err)
      //{
        //  alert(err);
      //}
   // });

   //alert(angular.toJson(response.routes[0].legs[0].steps));
   //google.maps.event.addListener(PolyLine, 'routeindex_changed', function() {
     //alert("Bingo");
     //computeTotalDistance(directionsDisplay.getRouteIndex());
   //});
   //alert(response.routes.length);
   //directionsDisplay.setDirections(response);
   }
   catch (err)
   {
     alert(err);
   }
 }
});

1 个答案:

答案 0 :(得分:4)

首先,您需要告诉您要求其他路线的请求,例如

// for example
var request = {
  origin: start,
  destination: end,
  provideRouteAlternatives: true,               
  travelMode: google.maps.TravelMode[DRIVING]
};

然后你有多个response.routes对象(注意,有时你只得到1条路线)。

directionsService.route(request, function(response, status) {
  if (status == google.maps.DirectionsStatus.OK) {
    for(var i in  response.routes ) {
      // ...
    }
  }
}

现在您可以使用response.routes [i]作为方向渲染的来源 或者你自己制作折线。使用response.routes [i] .overview_path作为路径

var line = new google.maps.Polyline({
  path: response.routes[i].overview_path,
  strokeColor: "#ff0000",  // you might want different colors per suggestion
  strokeOpacity: 0.7,
  strokeWeight: 3
});
line.setMap(map);

这是一个有效的例子。 只需更改您的API密钥。

根据您的要求,点击路线会突出显示

更新:我喜欢这样。

生成灰线和彩色线条。但突出显示仅显示地图上的1条建议。

大的灰线很好点击。因此它获取点击事件而不是彩色线。

这也是避免Z-index问题的最简单方法。

我存储了我在infoWindow上显示的数据(持续时间,距离)

<!DOCTYPE html>
<html>
<head>
    <title>Google Map Direction Render Alternate Route How To Select Desired Path</title>
    <meta name="viewport" content="initial-scale=1.0">
    <meta charset="utf-8">
    <style>
        html, body {
            height: 100%;
            margin: 0;
            padding: 0;
        }
        #map {
            height: 90%;
        }
    </style>
</head>
<body>
    <form id="form">
        <input id="from" placeholder="From" value="Brussel" />
        <input id="to" placeholder="To" value="Antwerpen" />
        <input type="submit" value="GO"  />
    </form>

    <div id="map"></div>
    <div id="info">
        <a href="http://stackoverflow.com/questions/39264760/google-map-direction-render-alternate-route-how-to-select-desired-path/39268344#39268344">Stackoverflow</a>
    </div>
    <script type="text/javascript" src="https://maps.google.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry"></script>
    <script>
        var map;
        var directionsService;
        var polylines = [];
        var shadows = [];
        var data = [];
        var infowindow;
        function initMap() {
            map = new google.maps.Map(document.getElementById('map'), {
                center: {lat: 50.84659376378408, lng: 4.3531406857355215},
                zoom: 12,
                mapTypeId: 'terrain'
            });
            google.maps.event.addDomListener(document.getElementById('form'), 'submit', function(e) {
                calcRoute(
                    document.getElementById('from').value,
                    document.getElementById('to').value
                );
                // prevent the form from really submitting
                e.preventDefault();
                return false;
            });
            directionsService = new google.maps.DirectionsService();
            // get the bounds of the polyline
            // http://stackoverflow.com/questions/3284808/getting-the-bounds-of-a-polyine-in-google-maps-api-v3
            google.maps.Polyline.prototype.getBounds = function(startBounds) {
                if(startBounds) {
                    var bounds = startBounds;
                }
                else {
                    var bounds = new google.maps.LatLngBounds();
                }
                this.getPath().forEach(function(item, index) {
                    bounds.extend(new google.maps.LatLng(item.lat(), item.lng()));
                });
                return bounds;
            };
        }
        // this function calculates multiple suggested routes.
        // We will draw 3 (broad stroke) suggested routs in grey.  These are broad to click on them easier.
        // We duplicate these routes with a thin, colored line; only route 0 is shown.
        function calcRoute(start, end) {
            var request = {
                origin: start,
                destination: end,
                provideRouteAlternatives: true,
                unitSystem: google.maps.UnitSystem.METRIC,
                travelMode: google.maps.TravelMode['DRIVING']
            };
            directionsService.route(request, function(response, status) {
                // clear former polylines
                for(var j in  polylines ) {
                    polylines[j].setMap(null);
                    shadows[j].setMap(null);
                }
                polylines = [];
                shadows = [];
                data = [];
                if (status == google.maps.DirectionsStatus.OK) {
                    var bounds = new google.maps.LatLngBounds();
                    for(var i in response.routes) {
                        // let's make the first suggestion highlighted;
                        var hide = (i==0 ? false : true);
                        var shadow = drawPolylineShadow(response.routes[i].overview_path, '#666666');
                        var line = drawPolyline(response.routes[i].overview_path, '#0000ff', hide);
                        polylines.push(line);
                        shadows.push(shadow);
                        // let's add some data for the infoWindow
                        data.push({
                            distance: response.routes[i].legs[0].distance,
                            duration: response.routes[i].legs[0].duration,
                            end_address: response.routes[i].legs[0].end_address,
                            start_address: response.routes[i].legs[0].start_address,
                            end_location: response.routes[i].legs[0].end_location,
                            start_location: response.routes[i].legs[0].start_location
                        });
                        bounds = line.getBounds(bounds);
                        google.maps.event.addListener(shadow, 'click', function(e) {
                            // detect which route was clicked on
                            var index = shadows.indexOf(this);
                            highlightRoute(index, e);
                        });

                    }
                    map.fitBounds(bounds);
                }
            });
        }
        // this makes one of the colored routes visible.
        function highlightRoute(index, e) {
            for(var j in  polylines ) {
                if(j==index) {
                    //var color = '#0000ff';
                    polylines[j].setMap(map);
                    // feel free to customise this string
                    var contentString =
                        '<span>'+ data[j].distance.text +'</span><br/>'+
                        '<span>'+ data[j].duration.text +'</span><br/>'+
                        '<span>route: '+ j +'</span><br/>'+
                        //'From: <span>'+ data[j].start_address +'</span><br/>'+
                        //'To: <span>'+ data[j].end_address +'</span><br/>'+
                        '';
                    if(e) {
                       var position = new google.maps.LatLng(e.latLng.lat(), e.latLng.lng());
                        // it may be needed to close the previous infoWindow
                        if(infowindow) {
                            infowindow.close();
                            infowindow = null;
                        }
                        infowindow = new google.maps.InfoWindow({
                            content: contentString,
                            position: position,
                            map: map
                        });
                        //infowindow.open(map, polylines[j]);
                    }
                }
                else {
                    polylines[j].setMap(null);
                }
            }
        }
        // returns a polyline.
        // if hide is set to true, the line is not put on the map
        function drawPolyline(path, color, hide) {
            var line = new google.maps.Polyline({
                path: path,
                strokeColor: color,
                strokeOpacity: 0.9,
                strokeWeight: 3
            });
            if(! hide) {
                line.setMap(map);
            }
            return line;
        }
        function drawPolylineShadow(path, color, hide) {
            var line = new google.maps.Polyline({
                path: path,
                strokeColor: color,
                strokeOpacity: 0.4,
                strokeWeight: 7
            });
            if(! hide) {
                line.setMap(map);
            }
            return line;
        }
        google.maps.event.addDomListener(window, 'load', initMap);
    </script>
</body>
</html> 

早期的代码。这会改变polyLine的颜色

<!DOCTYPE html>
<html>
<head>
    <title>Suggested routes</title>
    <meta name="viewport" content="initial-scale=1.0">
    <meta charset="utf-8">
    <style>
        html, body {
            height: 100%;
            margin: 0;
            padding: 0;
        }
        #map {
            height: 90%;
        }
    </style>
</head>
<body>
    <form id="form">
        <input id="from" placeholder="From" value="Brussel" />
        <input id="to" placeholder="To" value="Antwerpen" />
        <input type="submit" value="GO"  />
    </form>
    <div id="map"></div>
    <script type="text/javascript" src="https://maps.google.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry"></script>
    <script>
        var map;
        var directionsService;
        var polylines = [];

        function initMap() {
            map = new google.maps.Map(document.getElementById('map'), {
                center: {lat: 50.84659376378408, lng: 4.3531406857355215},
                zoom: 12,
                mapTypeId: 'terrain'
            });
            google.maps.event.addDomListener(document.getElementById('form'), 'submit', function(e) {
                calcRoute(
                    document.getElementById('from').value,
                    document.getElementById('to').value
                );
                // prevent the form from really submitting
                e.preventDefault();
                return false;
            });
            directionsService = new google.maps.DirectionsService();
            // get the bounds of the polyline
            // http://stackoverflow.com/questions/3284808/getting-the-bounds-of-a-polyine-in-google-maps-api-v3
            google.maps.Polyline.prototype.getBounds = function(startBounds) {
                if(startBounds) {
                    var bounds = startBounds;
                }
                else {
                    var bounds = new google.maps.LatLngBounds();
                }

                this.getPath().forEach(function(item, index) {
                    bounds.extend(new google.maps.LatLng(item.lat(), item.lng()));
                });
                return bounds;
            };
        }

        function calcRoute(start, end) {
            var request = {
                origin: start,
                destination: end,
                provideRouteAlternatives: true,
                unitSystem: google.maps.UnitSystem.METRIC,
                travelMode: google.maps.TravelMode['DRIVING']
            };
            directionsService.route(request, function(response, status) {
                // clear former polylines
                for(var j in  polylines ) {
                    polylines[j].setMap(null);
                }
                polylines = [];
                if (status == google.maps.DirectionsStatus.OK) {
                    var bounds = new google.maps.LatLngBounds();
                    // draw the lines in reverse orde, so the first one is on top (z-index)
                    for(var i=response.routes.length - 1; i>=0; i-- ) {
                        // let's make the first suggestion highlighted;
                        if(i==0) {
                            var color = '#0000ff';

                        }
                        else {
                            var color = '#999999';
                        }
                        var line = drawPolyline(response.routes[i].overview_path, color);
                        polylines.push(line);
                        bounds = line.getBounds(bounds);
                        google.maps.event.addListener(line, 'click', function() {
                            // detect which route was clicked on
                            var index = polylines.indexOf(this);
                            highlightRoute(index);
                        });
                    }
                    map.fitBounds(bounds);
                }
            });
        }

        function highlightRoute(index) {
            for(var j in  polylines ) {
                if(j==index) {
                    var color = '#0000ff';
                }
                else {
                    var color = '#999999';
                }
                polylines[j].setOptions({strokeColor: color});
            }
        }

        function drawPolyline(path, color) {
            var line = new google.maps.Polyline({
                path: path,
                strokeColor: color,
                strokeOpacity: 0.7,
                strokeWeight: 3
            });
            line.setMap(map);
            return line;
        }
        google.maps.event.addDomListener(window, 'load', initMap);
    </script>
</body>
</html>