谷歌地图方向服务航路点超过 50 个
Posted
技术标签:
【中文标题】谷歌地图方向服务航路点超过 50 个【英文标题】:Google map direction services waypoints more than 50 【发布时间】:2014-03-29 02:29:47 【问题描述】:Documentation 表示航点限制为 8 个点。但我必须从 50 多个航点中找到最佳航点订单列表。该怎么做?
我可以使用 Start + Destination + 8 Waypoints 找到航点顺序,但我需要超过 50 个航点的帮助
【问题讨论】:
目前,在 2016 年,文档说 Directions API Web 服务中的最大航点数为 23。 【参考方案1】: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 或从 google API URL 中删除 &key=YOUR_API_KEY 并将变量“max”设置为 8(使用 API KEY 时 max = 25,不使用时 max = 8使用 API KEY)。
<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>
【讨论】:
这不起作用,因为您“将路线划分为几个部分”,但这些部分是 25 个完全任意点的块。无法保证您随机分成 25 个一组的点甚至彼此接近。事实上,如果您可以确定point[i]
与 point[i+1]
接近,则根本不需要优化路线。
在我的情况下不需要点优化。在我的情况下,点是已知的,我只需要连接它(点是公共交通车站,它们通常一排排地从一个到另一个)。这取决于目的。在许多情况下,它是合适的解决方案,但我同意这不适用于 100% 的情况。通过在这个答案和这个 ***.com/a/43458012/3826175 中投票,包括积极的 cmets,它帮助了许多用户。在谷歌增加限制之前没有其他更好的方法。
问题要求“找到最佳航点顺序”,这个答案不会。
我认为可能有一个解决方案。在我的情况下,点通常是一排排的(因为公交车站点已经优化)所以我的解决方案运行良好。如果点是随机的,您应该首先按距离对其进行排序 - 例如使用 hasrsine 算法***.com/a/365853/3826175 或者当所有点都在半径几公里内(可以假设地球是平的)时,可以使用更简单+更快的算法。当点按距离(非随机)排序时,当将点传递给我的解决方案时,很有可能获得正确的结果,该解决方案将路线拆分为部分。
按距离排序到什么?到你的参考点?然后你在你周围的一个球体/圆中按半径对它们进行排序,经过仅仅 1 公里的距离排序,这些点将彼此相距 0 到 2 半径(2 公里),具体取决于它们与你所在的方向。如果您按到前一个最近点的距离对每个点进行排序,那么您就有一个 O(n^2) 算法可以进行随机游走,那么最好只进行随机游走。旅行商问题不能这样解决。众所周知,解决问题的复杂性正是航路点如此有限的原因【参考方案2】:
我创建了一个解决方法,但使用起来有点贵(就 API 调用而言)。
我没有使用开始、结束和航路点 LatLngs 创建单个呼叫,而是将航路点分成对进行呼叫。
例子:
问题:路线并获得 100 点的路线
解决办法:
呼叫 1:点 1 和点 2 呼叫 2:第 2 点和第 3 点调用 3: 第 3 点和第 4 点
...等等。
使用此解决方案,您将永远不必担心 8 个航点的限制,因为您每次只进行 2 点查询。此解决方案的缺点是您将创建大量呼叫,如果使用不当,它会占用您每天 2500 次免费呼叫。
【讨论】:
是的,你是对的。此过程将使用所有可用的免费通话限制。就我而言,每天将有19K-20K
积分。所以这个解决方案对我没有帮助。
优化路线怎么样?有什么用吗?
您好,Google 通常会根据您传递的参数进行自己的路线优化。【参考方案3】:
很遗憾,这是不可能的。
如果您有企业帐户,您最多可以添加大约 25 个航点。企业帐户非常昂贵。
如果您需要使用超过 25 个航点,则需要寻找其他供应商。
【讨论】:
【参考方案4】:我找到了这个解决方法。
它似乎完全符合您的需要。看看:http://lemonharpy.wordpress.com/2011/12/15/working-around-8-waypoint-limit-in-google-maps-directions-api/
【讨论】:
这对我的情况没有帮助,因为这并不能提供准确的航点顺序,以便为驾驶员方向提供最佳帮助【参考方案5】:HERE Maps (https://developer.here.com/blog/delivery-made-easy-with-the-here-waypoint-sequence-api) 提供多达 120 个航点的航点优化。看看他们,他们的价格也很合理
【讨论】:
您的链接已损坏。 固定到更新的链接。谢谢你让我注意到罗宾。请支持我的回答,因为我无法删除您的反对票。 :) 投反对票的不是我 ;) 我点击链接了解为什么有人会投反对票。您还可以通过使用 HERE API 提供有关航点的简短代码示例来提高答案的质量。 (然后我会自己投票)以上是关于谷歌地图方向服务航路点超过 50 个的主要内容,如果未能解决你的问题,请参考以下文章