【问题标题】:An elegant way to find shortest and fastest route in Google Maps API v3?在 Google Maps API v3 中找到最短和最快路线的优雅方法?
【发布时间】:2012-09-13 11:23:45
【问题描述】:

我正在制作出租车费用计算器。业务需求之一是,公司想要最短和最快的路线选择。我知道 Google directionService 默认搜索最快的路线。我将请求参数中的“avoidhighways”选项设置为 true 以获得最短的路线,但我对结果不太满意。

谁有比这更好的解决方案??

【问题讨论】:

  • 上述解决方案繁琐,不能保证有效(避免收费/高速公路等)。最好的解决方案应该是,通过几个中间 od 对请求路线。如果您的中间 od 对设置正确,所有部分的总和将成为路线。你可以自己试试。我确信这些路段的旅行时间/旅行距离之和非常接近整个请求的路线。

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


【解决方案1】:

为了获得从 A 到 B 的最短路线,我建议使用“alternatives=true”参数进行不同的查询,在避免=toll、避免=高速公路之间使用“避免”参数,然后我会比较所有结果选择最短的路线。

 directionsService = new google.maps.DirectionsService;
//avoiding tolls
            directionsService.route({
                origin: {
                    'placeId': originId
                },
                destination: {
                    'placeId': destinationId
                },
                provideRouteAlternatives: true,
                avoidTolls: true,
                travelMode: google.maps.TravelMode.DRIVING
            }, function(response, status) {
                if (status === google.maps.DirectionsStatus.OK) {
                    routesResponses.push(response);
                }
                else {
                    window.alert('Directions request failed due to ' + status);
                }
            });
            //avoiding highways
            directionsService.route({
                origin: {
                    'placeId': originId
                },
                destination: {
                    'placeId': destinationId
                },
                provideRouteAlternatives: true,
                avoidHighways: true,
                travelMode: google.maps.TravelMode.DRIVING
            }, function(response, status) {
                if (status === google.maps.DirectionsStatus.OK) {
                    routesResponses.push(response);
                }
                else {
                    window.alert('Directions request failed due to ' + status);
                }

                //Results analysis and drawing of routes
                var fastest = Number.MAX_VALUE,
                    shortest = Number.MAX_VALUE;

                routesResponses.forEach(function(res) {
                    res.routes.forEach(function(rou, index) {
                        console.log("distance of route " +index+": " , rou.legs[0].distance.value);
                        console.log("duration of route " +index+": " , rou.legs[0].duration.value);
                        if (rou.legs[0].distance.value < shortest) shortest = rou.legs[0].distance.value  ;
                        if (rou.legs[0].duration.value < fastest) fastest = rou.legs[0].duration.value  ;

                    })
                })
                console.log("shortest: ", shortest);
                console.log("fastest: ", fastest);
//painting the routes in green blue and red
                 routesResponses.forEach(function(res) {
                    res.routes.forEach(function(rou, index) {
                        new google.maps.DirectionsRenderer({
                            map:map,
                            directions:res,
                            routeIndex:index,
                            polylineOptions:{
                                strokeColor: rou.legs[0].duration.value == fastest? "red":rou.legs[0].distance.value == shortest?"darkgreen":"blue",
                                strokeOpacity: rou.legs[0].duration.value == fastest? 0.8:rou.legs[0].distance.value == shortest? 0.9: 0.5,
                                strokeWeight: rou.legs[0].duration.value == fastest? 9:rou.legs[0].distance.value == shortest? 8: 3,
                            }
                        })
                    })
                })   
            });
        }

    }

【讨论】:

  • 你能再解释一下吗?
【解决方案2】:

alternatives=true 选项集提供三个选项。然后,您可以在这些路径中搜索最短和最快的返回路线。

【讨论】:

    【解决方案3】:

    http://codepen.io/jasonmayes/pen/DupCH

    var shortestDistance = function() {  
        var directionsDisplay;
        var directionsService = new google.maps.DirectionsService();
        var map;
        var size = 0;
        var currentPosition;
    
        // An array of interesting places we want to potentially visit.
        var interestingPlaces = [
        {'title': 'Regents Park', 'latLng': new google.maps.LatLng(51.530686, -0.154753)},
        {'title': 'Hyde Park', 'latLng': new google.maps.LatLng(51.507293, -0.164022)},
        {'title': 'Green Park', 'latLng': new google.maps.LatLng(51.504088, -0.141706)},
        {'title': 'Regents Park', 'latLng': new google.maps.LatLng(51.479185, -0.159903)}
        ];
    
        // An array to store results from Google routing API.
        var routeResults = [];
    
    
        // Call this upon page load to set everything in motion!
        function initialize(currentLat, currentLng) {
        currentPosition = new google.maps.LatLng(currentLat, currentLng);
        directionsDisplay = new google.maps.DirectionsRenderer();
        var mapOptions = {
            zoom: 13,
            center: currentPosition
        };
        map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
        directionsDisplay.setMap(map);
    
        var marker = new google.maps.Marker({
                position: currentPosition,
                map: map,
                title: 'Currrently location.'
        });
    
        var i = interestingPlaces.length;
            while (i--) {
            interestingPlaces[i].marker = new google.maps.Marker({
            position: interestingPlaces[i].latLng,
            map: map,
            title: interestingPlaces[i].title,
            icon: 'http://maps.google.com/mapfiles/ms/icons/green.png'
            });
        }
    
        findNearestPlace();
        }
    
    
        // Loops through all inteesting places to calculate route between our current position
        // and that place.
        function findNearestPlace() {
        var i = interestingPlaces.length;
        size = interestingPlaces.length;
        routeResults = [];
        while (i--) {
            calcRoute(interestingPlaces[i].latLng, storeResult);
        }
        }
    
    
        // A function to calculate the route between our current position and some desired end point.
        function calcRoute(end, callback) {
        var request = {
            origin: currentPosition,
            destination: end,
            travelMode: google.maps.TravelMode.DRIVING
        };
        directionsService.route(request, function(response, status) {
            if (status == google.maps.DirectionsStatus.OK) {
            callback(response);
            } else {
            size--;
            }
        });
        }
    
    
        // Stores a routing result from the API in our global array for routes.
        function storeResult(data) {
        routeResults.push(data);
        if (routeResults.length === size) {
            findShortest();
        }
        }
    
    
        // Goes through all routes stored and finds which one is the shortest. It then
        // sets the shortest route on the map for the user to see.
        function findShortest() {
        var i = routeResults.length;
        var shortestIndex = 0;
        var shortestLength = routeResults[0].routes[0].legs[0].distance.value;
    
        while (i--) {
            if (routeResults[i].routes[0].legs[0].distance.value < shortestLength) {
            shortestIndex = i;
            shortestLength = routeResults[i].routes[0].legs[0].distance.value;
            }
        }
        directionsDisplay.setDirections(routeResults[shortestIndex]);
        }
    
        // Expose the initialize function publicly as "init".
        return {
        init: initialize
        };
    }();
    
    // Upon page load, lets start the process!
    google.maps.event.addDomListener(window, 'load', shortestDistance.init(51.489554, -0.12969));
    

    免责声明

    这是不是我的笔!!!我只是提到一个有用的资源,可能会有所帮助

    【讨论】:

      【解决方案4】:

      首先很抱歉我的解决方案是在TS中,你可以很容易地将它转换为JS。

      “avoidhighways”属性不是为了获得最快或最短的路线,而是顾名思义,避开高速公路。

      我通过始终使用此属性获取多个路由来制定自己的解决方案:

      directionsService.route({
                  [...]
                  provideRouteAlternatives: true
                  [...]
               }, (response, status) => {
                  if (status === google.maps.DirectionsStatus.OK) {
                      var shortest: google.maps.DirectionsResult = this.shortestRoute(response);
                      this.directionsDisplay.setDirections(shortest);
                      [...]
      

      我创建了这个函数,它只用一条路线返回 DirectionsResult。在这种情况下,它是最短的,但您可以对其进行调整,以便返回适合您需要的任何路线。

          shortestRoute = (routeResults: google.maps.DirectionsResult): google.maps.DirectionsResult => {
              var shortestRoute: google.maps.DirectionsRoute = routeResults.routes[0];
              var shortestLength = shortestRoute.legs[0].distance.value;
              for (var i = 1; i < routeResults.routes.length; i++) {
                  if (routeResults.routes[i].legs[0].distance.value < shortestLength) {
                      shortestRoute = routeResults.routes[i];
                      shortestLength = routeResults.routes[i].legs[0].distance.value;
                  }
              }
              routeResults.routes = [shortestRoute];
              return routeResults;
          }
      

      【讨论】:

        【解决方案5】:

        我从 Soldeplata Saketos 答案中获取代码并对其进行了编辑,因为它不起作用。添加了参数,因此您可以像这样调用它。

        shortestRoute(origin, destination, map); 
        

        虽然我不确定它有多正确,但对我所有人都有效。

        这里:

        function shortestRoute(origin, destination, map) {
        
          directionsService = new google.maps.DirectionsService();
          var routesResponses = [];
          //avoiding tolls
          directionsService.route({
            origin: origin,
            destination: destination,
            provideRouteAlternatives: true,
            avoidTolls: true,
            travelMode: google.maps.TravelMode.DRIVING
          }, function (response, status) {
            if (status === google.maps.DirectionsStatus.OK) {
              routesResponses.push(response);
            } else {
              window.alert('Directions request failed due to ' + status);
            }
          });
          //avoiding highways
          directionsService.route({
            origin: origin,
            destination: destination,
            provideRouteAlternatives: true,
            avoidHighways: true,
            travelMode: google.maps.TravelMode.DRIVING
          }, function (response, status) {
            if (status === google.maps.DirectionsStatus.OK) {
              routesResponses.push(response);
            } else {
              window.alert('Directions request failed due to ' + status);
            }
        
            //Results analysis and drawing of routes
            var fastest = Number.MAX_VALUE,
              shortest = Number.MAX_VALUE;
        
            routesResponses.forEach(function (res) {
              res.routes.forEach(function (rou, index) {
                console.log("distance of route " + index + ": ", rou.legs[0].distance.value);
                console.log("duration of route " + index + ": ", rou.legs[0].duration.value);
                if (rou.legs[0].distance.value < shortest) shortest = rou.legs[0].distance.value;
                if (rou.legs[0].duration.value < fastest) fastest = rou.legs[0].duration.value;
        
              })
            })
            console.log("shortest: ", shortest);
            console.log("fastest: ", fastest);
            //painting the routes in green blue and red
            routesResponses.forEach(function (res) {
              res.routes.forEach(function (rou, index) {
                new google.maps.DirectionsRenderer({
                  map: map,
                  directions: res,
                  routeIndex: index,
                  polylineOptions: {
                    strokeColor: rou.legs[0].duration.value == fastest ? "red" : rou.legs[0].distance.value == shortest ? "darkgreen" : "blue",
                    strokeOpacity: rou.legs[0].duration.value == fastest ? 0.8 : rou.legs[0].distance.value == shortest ? 0.9 : 0.5,
                    strokeWeight: rou.legs[0].duration.value == fastest ? 9 : rou.legs[0].distance.value == shortest ? 8 : 3,
                  }
                });
              });
            });
          });
        }
        

        【讨论】:

          【解决方案6】:
          在请求参数中使用 optimizeWaypoints: true 。见下面的代码sn-p 变种请求 ={ 原点:sStartLatLng, 目的地:sStartLatLng, 航路点:航路点, optimizeWaypoints: true, travelMode:google.maps.DirectionsTravelMode.DRIVING };

          【讨论】:

          • 这不是他想要的。 “optimizeWaypoints”仅当路线设置有路点(通过点)并且您可以将它们的顺序更改为可能的最短路径。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-04-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-11-01
          • 2011-05-02
          相关资源
          最近更新 更多