您可以使用像
piccolo2d这样的2D绘图框架来渲染地图.
对于路由,您需要构建一个描述地图上的道路/方式,它们如何加入以及所表示的距离的
graph.在地图上选择了起点和终点后,诸如
A star之类的算法将帮助您找到点之间的最短路径.
更多细节:
OSM XML转储由三类实体组成(比这更复杂:参见official docs的完整细节):
>节点:表示地图上的单个点,由经度和纬度定义.这些要么代表着显着的特征(种类繁多,但是,例如:商店,古代纪念碑,路径上的大门等)或者是一种方式的一部分.
>方式:在地图上表示多边形.它们由有序的节点列表(由id引用)构成,可以表示线性事物,例如道路和路径(与路由问题相关),但也可以表示有界区域,例如田地或森林边界,城市区域的形状,湖泊,河流等
>关系:我不会在这里讨论,但你可以在官方文档中找到更多相关信息.
上述三种节点类型中的每一种都将以“标签”的形式具有与它们相关联的附加数据,“标签”是指定由节点/方式表示的实体类型的键值(字符串)对.可以找到一般列表here和路由here的列表.从OSM网站获取的示例代表一条小型本地道路(在本例中为德国):
...
...
在两种方式相交的情况下(例如,当两条道路交叉时),它们将在交叉点共享一个共同的节点.
要过滤到生成路由图所需的数据,您需要:
>阅读感兴趣区域的XML,至少读取节点和方式.
>过滤掉,只根据他们的标签留下您想要的方式(例如k =“高速公路”等).
>过滤掉所有节点,但剩余相关方式引用的节点.
只隔离了所需的信息,然后需要从OSM格式转换为更适合路由的格式.虽然所描述的OSM图可以用于路由,但是将地图表示为每条路的起点和终点的一组节点以及路和表示交叉点之间的路径的一组边的任何交叉点更有效. ,以及他们的长度.
例如,您可能希望转换以下内容(使用交叉方式a-b,c-d,e-f):
更喜欢的东西:
只有末端节点和交叉节点保留的位置.在此表示中,您将在路由图(ax,cx,xe,ed,xy,ey,yf,yb)中从3个方向转换为8个边缘,每个边缘具有通过沿着节点中的节点步进计算的相关距离.方式,你去的地方累积距离:(例如斧头:200米,眼睛:350米等).请注意,您需要计算经度/纬度空间中相邻点之间的距离,您可以在其中找到公式here.
您可以使用自己的数据结构或使用第三方图形库(如JGraphT或Jung)来表示此数据.从这里开始,路由是(粗略地,并且为了简单起见,假设您剩余的节点集合具有足够的细粒度来表示所有需要的开始/结束点)选择代表旅程开始的节点,表示结束的节点并使用诸如A-star(如上所述)的算法来计算最短路径.
唯一的问题是,据我所知,我提到的两个图书馆都没有实现A-star.但是你可以通过以较低的速度运行Dijkstra的最短路径(存在于两个库中)来获得正确的结果 – 然后当你对这些概念更有信心时自己实现A-star.
为了使所有这些变得更有趣:不是使用距离,而是可以根据估计的旅行时间(考虑到道路上的平均速度)进行路线选择.或者你可以根据路线的需要修改距离:例如对于骑自行车,减少交通量较少的道路上的距离,以选择更长但更安全的路线.也可以徒步旅行,减少通过特别风景区或靠近古迹或酒吧等地标的路径的距离.
鉴于OSM数据存在合适的现有路由服务(例如从Cloudmade开始),您想要做这样的事情的主要原因是为了使用您自己的自定义距离度量…