地图路由,谷歌地图?

时间:2008-08-05 20:24:43

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

我一直对地图路由感兴趣,但我从来没有找到任何好的入门(甚至高级!)级别的教程。有人有任何指针,提示等吗?

更新:我主要是在寻找有关如何实现地图系统的指针(数据结构,算法等)。

9 个答案:

答案 0 :(得分:14)

看看open street map project,看一下如何使用用户提供和许可的数据在一个真正免费的软件项目中处理这类事情并获得wiki containing stuff you might find interesting

几年前,那些家伙们参与其中非常轻松,回答了很多问题,所以我没有理由说他们仍然不是很好。

答案 1 :(得分:4)

Google地图路线寻找功能的工程师之一Barry Brumitt写了一篇关于这个主题的帖子,可能会引起人们的兴趣:

The road to better path-finding 11/06/2007 03:47:00 PM

答案 2 :(得分:4)

通过地图路由,您的意思是找到沿街道网络的最短路径?

Dijkstra最短路径算法是最为人所知的。维基百科有一个不错的介绍:http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm

这里有一个Java小程序,您可以在其中看到它:http://www.dgp.toronto.edu/people/JamesStewart/270/9798s/Laffra/DijkstraApplet.html和Google,您可以使用几乎任何语言来获取源代码。

用于生成驾驶路线的任何实际实施都将包括街道网络上的相当多的数据,其描述与遍历链路和节点相关的成本 - 道路网络层级,平均速度,交叉点优先级,交通信号链接,禁止转弯等。

答案 3 :(得分:4)

A *实际上更接近生产映射算法。与Dijikstra的原始算法相比,它需要的探索要少得多。

答案 4 :(得分:2)

我还没有找到一个很好的路由教程,但有很多代码需要阅读:

有使用Openstreetmap数据的GPL路由应用程序,例如: Gosmore适用于Windows(+移动)和Linux。有许多有趣的[应用程序使用相同的数据,但gosmore有一些很酷的用途 e.g. interface with websites

路由的最大问题是数据不好,而且你从来没有得到足够好的数据。因此,如果您想尝试将测试保持在本地,这样您就可以更好地控制数据。

答案 5 :(得分:2)

而不是向每个地图服务提供商学习API(如Gmaps,Ymaps api),这很有用Mapstraction

“Mapstraction是一个为各种javascript映射API提供通用API的库”

我建议您转到该网址并学习一般API。还有很多How-Tos。

答案 6 :(得分:2)

从概念的角度来看,想象一下将一块石头扔进池塘并观察涟漪。路线将代表池塘和石头的起始位置。

当然,当距离n增加时,算法必须搜索一定比例的n ^ 2个路径。您将从该点开始,并检查所有可用路径。然后以递归方式调用这些路径末尾的点,依此类推。

您可以通过不在路径上进行双重支持来提高性能,方法是不重新检查路径(如果路径已经被覆盖)并放弃路径花费太长时间。

另一种方法是使用蚂蚁信息素方法,其中蚂蚁从起点随机爬行并留下气味踪迹,从而构建越过给定路径的更多蚂蚁。如果您从起点和终点发送(足够)蚂蚁,那么最终气味最强的路径将是最短的。这是因为假定蚂蚁以统一的速度行走,在给定时间段内最短路径将被访问过更多次。

EDIT @ Spikie

作为对如何实施池塘算法的进一步解释 - 强调了所需的潜在数据结构:

您需要将地图存储为网络。这只是它们之间的一组nodesedges。一组nodes构成route。边连接两个节点(可能都是同一个节点),并且有一个关联的cost,例如distancetime来遍历边缘。边缘可以是双向的或单向的。可能最简单的是只有单向的并且加倍节点之间的双向行程(即从A到B的一个边缘和从B到A的不同边缘)。

举例来说,想象三个火车站以等边三角形排列向上。在它们之间还有另外三个站点。边缘将所有相邻的工作站连接在一起,最终的图表将在较大的三角形内部有一个倒三角形。

标记节点从左下角开始,从左到右依次为A,B,C,D,E,F(顶部为F)。

假设可以在任一方向上遍历边缘。每条边的成本为1公里。

好的,所以我们希望从左下角A到最高站F.有许多可能的路线,包括那些自身加倍的路线,例如ABCEBDEF。

我们有一个常规说法NextNode,它接受​​nodecost并为其可以前往的每个节点调用自己。

显然,如果我们让这个例程运行,它最终会发现所有路径,包括长度可能无限的路径(例如ABABABAB等)。我们通过检查cost来阻止这种情况发生。每当我们访问之前未访问过的节点时,我们都将成本和我们来自的节点放在该节点上。如果在我们检查现有成本之前已经访问过一个节点,并且如果我们更便宜,那么我们更新节点并继续(递归)。如果我们更贵,那么我们跳过节点。如果跳过所有节点,则退出例程。

如果我们点击目标节点,那么我们也会退出例程。

这样可以检查所有可行的路线,但最重要的是只检查成本最低的路线。在流程结束时,每个节点到达该节点的成本最低,包括我们的目标节点。

为了获得路线,我们从目标节点向后工作。由于我们存储了我们来自的节点以及成本,我们只是向后跳跃建立路线。对于我们的例子,我们最终会得到类似的东西:

节点A - (总计)成本0 - 来自节点无 节点B - 成本1 - 来自节点A
节点C - 成本2 - 来自节点B
节点D - 成本1 - 来自节点A
节点E - 成本2 - 来自节点D /成本2 - 来自节点B(这是一个例外,因为成本相等)
节点F - 成本2 - 来自节点D

所以最短的路线是ADF。

答案 7 :(得分:1)

关于每次遍历的成本,我想到了另一种想法,但会增加计算所需的时间和处理能力。

示例:根据GoogleMaps的说法,我可以采用3种方法(我住的地方)从A点到B点。 Garmin单元在Quickest路由计算中提供这3个路径中的每一个。在多次遍历这些路线并进行平均后(显然会有错误,取决于一天中的时间,咖啡因的量等),我觉得算法可以考虑到道路上的弯道数量,以获得高精度,例如 1英里的直道将比1英里的道路快速弯道。 这不是一个实际的建议,但肯定是我用来改善我日常通勤的结果集。

答案 8 :(得分:1)

根据我在这个领域工作的经验,A *能很好地完成工作。它(如上所述)比Dijkstra的算法更快,但对于一个普通的程序员来说,它仍然足够简单,可以实现和理解。

构建路线网络是最难的部分,但可以分解为一系列简单的步骤:获得所有道路;按顺序排列点;在不同的道路上将相同点组成交叉点(节点);在节点连接的两个方向上添加弧(或仅在单向道路的一个方向上)。

A *算法本身是well documented on Wikipedia。优化的关键位置是从打开列表中选择最佳节点,您需要一个高性能优先级队列。如果您使用的是C ++,则可以使用STL priority_queue适配器。

自定义算法以在有利于速度,距离或其他标准的网络的不同部分(例如,行人,汽车,公共交通等)上进行路由是非常容易的。您可以通过编写过滤器来控制哪些路段可用,构建网络以及为每个路径分配了哪个权重。