首页 文章

Google Directions API(业务/工作级别)的每个请求限制超过23个航点

提问于
浏览
24

我想使用谷歌方向API为一家公司开发路线规划软件,该公司在冬季处理除雪机,在夏季进行景观美化 . 客户要求之一是他能够计算至少30个(最好是更多)航点的航线 . 根据文档(引用如下),即使Google Maps API for Work客户每个请求仅限于23个航点 .

使用Google Directions API受限于每天2,500个路线请求的查询限制 . 单个路线请求可在请求中包含最多8个中间路点 . Google Maps API for Work客户每天最多可查询100,000个路线请求,每个请求最多允许23个路标 .

有没有人意识到一种解决方法 - 任何方式 - 解决这个问题?

此外 - 是否可以使用免费API的变通方法?我听说首要账户相当昂贵 .

谢谢!!渣

5 回答

  • 0

    你是对的,首映价格相当昂贵起价为10,000美元,上次我在电话上与谷歌代表交谈 .

    我找到了一种解决方法,以某种方式绕过了8个航路点的限制 . 我能够让它发挥作用 .

    我这样做是通过接收我的航点并将它们分成不同的路线,但将它们作为相同的路线绘制在一起 .

    例如,如果需要30个航路点,我将绘制4条线,但颜色相同等等 . 因此,基本上您将航点切入不同的路线,每次调用方向渲染器,就好像它是一条不同的路线 . 关键是在第一条路线之后,下一条路线必须从前一条路线的最后一条航路点开始(这可确保路线相互连接)

    它可以工作,但你需要编写比你有一个高级帐户更多的代码,并且你在这个例子中要求更多的方向 .

    我已经搜索并考虑了其他方法来做到这一点,没有一个优秀的帐户,并失败了 .

    虽然,在与谷歌交谈时,他们确实表示他们打算为有不同需求/需求的客户创建分层付款结构 . 例如,如果客户只需要更多的路径而不是更多的方向请求 .

    希望这有帮助,因为它在实践应用程序中对我有用 .

  • 15
    function initMap() {
        var service = new google.maps.DirectionsService;
        var map = new google.maps.Map(document.getElementById('map'));
    
        // list of points
        var stations = [
            {lat: 48.9812840, lng: 21.2171920, name: 'Station 1'},
            {lat: 48.9832841, lng: 21.2176398, name: 'Station 2'},
            {lat: 48.9856443, lng: 21.2209088, name: 'Station 3'},
            {lat: 48.9861461, lng: 21.2261563, name: 'Station 4'},
            {lat: 48.9874682, lng: 21.2294855, name: 'Station 5'},
            {lat: 48.9909244, lng: 21.2295512, name: 'Station 6'},
            {lat: 48.9928871, lng: 21.2292352, name: 'Station 7'},
            {lat: 48.9921334, lng: 21.2246742, name: 'Station 8'},
            {lat: 48.9943196, lng: 21.2234792, name: 'Station 9'},
            {lat: 48.9966345, lng: 21.2221262, name: 'Station 10'},
            {lat: 48.9981191, lng: 21.2271386, name: 'Station 11'},
            {lat: 49.0009168, lng: 21.2359527, name: 'Station 12'},
            {lat: 49.0017950, lng: 21.2392890, name: 'Station 13'},
            {lat: 48.9991912, lng: 21.2398272, name: 'Station 14'},
            {lat: 48.9959850, lng: 21.2418410, name: 'Station 15'},
            {lat: 48.9931772, lng: 21.2453901, name: 'Station 16'},
            {lat: 48.9963512, lng: 21.2525850, name: 'Station 17'},
            {lat: 48.9985134, lng: 21.2508423, name: 'Station 18'},
            {lat: 49.0085000, lng: 21.2508000, name: 'Station 19'},
            {lat: 49.0093000, lng: 21.2528000, name: 'Station 20'},
            {lat: 49.0103000, lng: 21.2560000, name: 'Station 21'},
            {lat: 49.0112000, lng: 21.2590000, name: 'Station 22'},
            {lat: 49.0124000, lng: 21.2620000, name: 'Station 23'},
            {lat: 49.0135000, lng: 21.2650000, name: 'Station 24'},
            {lat: 49.0149000, lng: 21.2680000, name: 'Station 25'},
            {lat: 49.0171000, lng: 21.2710000, name: 'Station 26'},
            {lat: 49.0198000, lng: 21.2740000, name: 'Station 27'},
            {lat: 49.0305000, lng: 21.3000000, name: 'Station 28'},
        ];
        
        // Zoom and center map automatically by stations (each station will be in visible map area)
        var lngs = stations.map(function(station) { return station.lng; });
        var lats = stations.map(function(station) { return station.lat; });
        map.fitBounds({
            west: Math.min.apply(null, lngs),
            east: Math.max.apply(null, lngs),
            north: Math.min.apply(null, lats),
            south: Math.max.apply(null, lats),
        });
        
        // Show stations on the map as markers
        for (var i = 0; i < stations.length; i++) {
            if (!stations[i].name)
                continue;
            new google.maps.Marker({
                position: stations[i],
                map: map,
                title: stations[i].name
            });
        }
    
        // Divide route to several parts because max stations limit is 25 (23 waypoints + 1 origin + 1 destination)
        for (var i = 0, parts = [], max = 8 - 1; i < stations.length; i = i + max)
            parts.push(stations.slice(i, i + max + 1));
    
        // Callback function to process service results
        var service_callback = function(response, status) {
            if (status != 'OK') {
                console.log('Directions request failed due to ' + status);
                return;
            }
            var renderer = new google.maps.DirectionsRenderer;
            renderer.setMap(map);
            renderer.setOptions({ suppressMarkers: true, preserveViewport: true });
            renderer.setDirections(response);
        };
            
        // Send requests to service to get route (for stations count <= 25 only one request will be sent)
        for (var i = 0; i < parts.length; i++) {
            // Waypoints does not include first station (origin) and last station (destination)
            var waypoints = [];
            for (var j = 1; j < parts[i].length - 1; j++)
                waypoints.push({location: parts[i][j], stopover: false});
            // Service options
            var service_options = {
                origin: parts[i][0],
                destination: parts[i][parts[i].length - 1],
                waypoints: waypoints,
                travelMode: 'WALKING'
            };
            // Send request
            service.route(service_options, service_callback);
        }
      }
    
    html, body {
        height: 100%;
        margin: 0;
        padding: 0;
    }
    #map {
        height: 100%;     
        width: 100%;
        height: 100%;
    }
    
    <div id="map"></div>
    
    <!-- without API KEY set variable "max" to 8 -->
    <script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap"></script>
    
    <!-- with API KEY set variable "max" to 25 -->
    <!-- <script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap&key=YOUR_API_KEY"></script>-->
    

    使用以下代码,您可以根据需要使用尽可能多的航点,并且永远不会收到错误 MAX_WAYPOINTS_EXCEEDED . 不要忘记将"YOUR_API_KEY"替换为您的API KEY或从谷歌API URL中删除 &key=YOUR_API_KEY 并将变量"max"设置为8(使用API KEY时max = 25,不使用API KEY时max = 8) .

    <style>
    html, body { height: 100%; margin: 0; padding: 0; }
    #map { height: 100%; width: 100%; height: 100%; }
    </style>
    <div id="map"></div>
    <script>
      function initMap() {
        var service = new google.maps.DirectionsService;
        var map = new google.maps.Map(document.getElementById('map'));
    
        // list of points
        var stations = [
            {lat: 48.9812840, lng: 21.2171920, name: 'Station 1'},
            {lat: 48.9832841, lng: 21.2176398, name: 'Station 2'},
            {lat: 48.9856443, lng: 21.2209088, name: 'Station 3'},
            {lat: 48.9861461, lng: 21.2261563, name: 'Station 4'},
            {lat: 48.9874682, lng: 21.2294855, name: 'Station 5'},
            {lat: 48.9909244, lng: 21.2295512, name: 'Station 6'},
            {lat: 48.9928871, lng: 21.2292352, name: 'Station 7'},
            {lat: 48.9921334, lng: 21.2246742, name: 'Station 8'},
            {lat: 48.9943196, lng: 21.2234792, name: 'Station 9'},
            {lat: 48.9966345, lng: 21.2221262, name: 'Station 10'},
            {lat: 48.9981191, lng: 21.2271386, name: 'Station 11'},
            {lat: 49.0009168, lng: 21.2359527, name: 'Station 12'},
            {lat: 49.0017950, lng: 21.2392890, name: 'Station 13'},
            {lat: 48.9991912, lng: 21.2398272, name: 'Station 14'},
            {lat: 48.9959850, lng: 21.2418410, name: 'Station 15'},
            {lat: 48.9931772, lng: 21.2453901, name: 'Station 16'},
            {lat: 48.9963512, lng: 21.2525850, name: 'Station 17'},
            {lat: 48.9985134, lng: 21.2508423, name: 'Station 18'},
            {lat: 49.0085000, lng: 21.2508000, name: 'Station 19'},
            {lat: 49.0093000, lng: 21.2528000, name: 'Station 20'},
            {lat: 49.0103000, lng: 21.2560000, name: 'Station 21'},
            {lat: 49.0112000, lng: 21.2590000, name: 'Station 22'},
            {lat: 49.0124000, lng: 21.2620000, name: 'Station 23'},
            {lat: 49.0135000, lng: 21.2650000, name: 'Station 24'},
            {lat: 49.0149000, lng: 21.2680000, name: 'Station 25'},
            {lat: 49.0171000, lng: 21.2710000, name: 'Station 26'},
            {lat: 49.0198000, lng: 21.2740000, name: 'Station 27'},
            {lat: 49.0305000, lng: 21.3000000, name: 'Station 28'},
            // ... as many other stations as you need
        ];
    
        // Zoom and center map automatically by stations (each station will be in visible map area)
        var lngs = stations.map(function(station) { return station.lng; });
        var lats = stations.map(function(station) { return station.lat; });
        map.fitBounds({
            west: Math.min.apply(null, lngs),
            east: Math.max.apply(null, lngs),
            north: Math.min.apply(null, lats),
            south: Math.max.apply(null, lats),
        });
    
        // Show stations on the map as markers
        for (var i = 0; i < stations.length; i++) {
            new google.maps.Marker({
                position: stations[i],
                map: map,
                title: stations[i].name
            });
        }
    
        // Divide route to several parts because max stations limit is 25 (23 waypoints + 1 origin + 1 destination)
        for (var i = 0, parts = [], max = 25 - 1; i < stations.length; i = i + max)
            parts.push(stations.slice(i, i + max + 1));
    
        // Service callback to process service results
        var service_callback = function(response, status) {
            if (status != 'OK') {
                console.log('Directions request failed due to ' + status);
                return;
            }
            var renderer = new google.maps.DirectionsRenderer;
            renderer.setMap(map);
            renderer.setOptions({ suppressMarkers: true, preserveViewport: true });
            renderer.setDirections(response);
        };
    
        // Send requests to service to get route (for stations count <= 25 only one request will be sent)
        for (var i = 0; i < parts.length; i++) {
            // Waypoints does not include first station (origin) and last station (destination)
            var waypoints = [];
            for (var j = 1; j < parts[i].length - 1; j++)
                waypoints.push({location: parts[i][j], stopover: false});
            // Service options
            var service_options = {
                origin: parts[i][0],
                destination: parts[i][parts[i].length - 1],
                waypoints: waypoints,
                travelMode: 'WALKING'
            };
            // Send request
            service.route(service_options, service_callback);
        }
      }
    </script>
    <script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"></script>
    

    You can see screen here.

    fiddle with show/hide line buttons

  • 10

    这是一个使用超过8个航点的黑客 . 请检查我的解决方案 .

    Drawing roadmap with more than 8 waypoints using Google directions API

  • -2

    这个解决方案很简单 .

    根据距离阈值将航点保持在阵列中并继续添加它们 . 一旦达到数组中8个值的限制,将航点阵列的第一个位置(原点)分配给新的航点阵列....将最后一个航点指定为新航点作为第二个元素...现在替换旧的航点数组与这个新的并继续 .

    Watever你做的航点永远不会超过8个值,它将跟踪绘制出来的路线(除非旅程太长)

    var addWaypoint = function(point) {
        if($scope.waypoints.length > 8){
            var temp = [];
            temp.push($scope.waypoints[0]); //Start Point
            temp.push($scope.waypoints[7]); //Last point
            temp.push(point); //New point
            $scope.waypoints = temp; //Replace the old object with this new one
        }
        else 
            $scope.waypoints.push(point);
    }
    
  • 0

    C#中的以下代码计算您将使用Google Directions API调用的次数以及每次迭代的路点数 . 您可以修改Modmin以更改上次迭代时所需的最小航点 .

    例如,如果您有totalWaypoints.Count = 97:

    97 Mod 23 = 5,在这种情况下我想要一个大于5的Modmin,所以我将用较低的waypointsByIteration再次计算;

    97 Mod 22 = 9,(9> Modmin),OK;

    迭代=((97-(97%22))/(22))1 = 5;

    在最后一次迭代中,waypointsByIteration将是残差 .

    var iterations = 1;//Number of iterations
            var waypointsByIteration = 23;//Number of waypoints by iteration
            var modMin = 5;//Minimum of Waypoints in the last iteration
            var residue = 0;//Residue of the division (totalWaypoints % waypointsByIteration)
    
            if (totalWaypoints.Count <= waypointsByIteration)
            {
                waypointsByIteration = totalWaypoints.Count;
            }
            else
            {
                while (totalWaypoints.Count % waypointsByIteration < modMin)
                {
                    waypointsByIteration--;
                }
    
                //Calculate number of waypoints by iteracoes
                iterations = ((totalWaypoints.Count - (totalWaypoints.Count % waypointsByIteration)) / (waypointsByIteration)) + 1;
            }
    
            residue = totalWaypoints % waypointsByIteration;
    
            for(i=0;i<iterations;i++)
            {
                //If it is the last index, the waypointsByIteration will be the residue
                if(i == iteration - 1)
                {
                    waypointsByIteration = residue;
                }
            }
    

相关问题