如何修建“道路”来自 .osm 文件的数据库中的图表

发布于 2024-11-03 13:00:48 字数 986 浏览 1 评论 0原文

所需结果

具有两个表“边”和“节点”的数据库,可用于生成表示特定区域(例如城市)内所有可行驶道路(高速公路)的图表。数据集是从 .osm 文件解析的。

背景:

我将第二次尝试创建一个包含两个表的数据库 - 节点和边,可用于对其进行不同的最短路径计算。

首先,我尝试手动将不同的数据提取到数据库中(php脚本):

  • 将.osm文件中的所有节点解析到“nodes”表中,
  • 将所有边解析到“edges”表中(即解析方式并生成边(由起始节点和目标节点组成),同时将标签添加到边缘;
  • 所有具有黑名单标签(不是高速公路)的边缘;
  • 从边缘表中删除 。

问题是这个序列非常不可靠,并且它仅适用于小型数据集,例如数千个节点,而不是数百万个

问题

数以百万计的节点和边,道路提取(基于特定标签过滤器生成边)非常慢

可能的解决方案:

这次我要做的:

  • 设置PostgreSQL rdbms;
  • 使用OSM现成的脚本解析.osm文件以获得完整的节点、路径和关系表;
  • 从ways表中提取带有特定标签(例如“highway”)的所有边到一个新的“edges”表中;
  • 将edges表中存在的所有节点提取到新的graph_nodes表中;
  • 之后我可能可以从“edges”和“graph_nodes”表生成“道路”图。

问题:

如何正确地将 .osm 文件解析到数据库中以获得“边缘”和“节点”表?

如何仅将 .osm 中的可行驶道路提取到数据库中?

如何快速完成(我的意思是为数百万个节点和边表运行脚本数小时,而不是数周)?

我应该考虑关系吗?

如果是,我该怎么做?

Required result:

A database with two tables, 'edges' and 'nodes', which can be used to generate a graph which represents all drivable roads (highways) in a certain area (e.g. city). The dataset is parsed from an .osm file.

Background:

I'm going for my second try of creating a database with two tables - nodes and edges which can be used to do different shortest path calculations on it.

First I tried to manually extract different data into the database (php scripts):

  • parse all the nodes from the .osm file into 'nodes' table
  • parse all the edges into the 'edges' table (that is parse the ways and generate edges (consisting of a starting node and a destination node) from those, adding the tags to the edges simultaneously;
  • delete all the edges that have blacklisted tags (that are not highways) from the edges table;
  • delete all nodes that are not present in the edges table from the nodes table.

The problem is that this sequence is very unreliable and it works 'so-so' only on small datasets, like thousands of nodes, but not millions.

Problem:

With a database consisting of millions of nodes and edges, road-extracting (i.g. generating edges based on a certain tags filter) is extremely slow.

Possible solution:

What I'm going to do this time:

  • set up PostgreSQL rdbms;
  • parse the .osm file with OSM ready-made scripts to get full nodes, ways and relations tables;
  • extract all edges with certain tags (e.g. 'highway') into a new 'edges' table from the ways table;
  • extract all nodes that are present in the edges table into a new graph_nodes table;
  • after that I probably could generate a 'roads' graph from 'edges' and 'graph_nodes' tables.

Question:

How do I correctly parse an .osm file into a database to have 'edges' and 'nodes' tables as a result?

How can I extract only drivable roads from .osm into a database?

How do I do it fast (I mean hours of scripts running for millions of nodes and edges tables, not weeks)?

Should I take relations into account?

If yes, how should I do that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蔚蓝源自深海 2024-11-10 13:00:48

正如我在评论中提到的,实际上没有必要插入列入黑名单的边缘。另外,我想到了另一个问题。为什么仍然需要从节点表中删除节点?您可以在节点表中添加一个特殊的标志字段(我们称之为已使用)。

当您向节点表插入新行时,该字段将设置为 false。您还可以实现一个触发器来插入边缘表,对于每个插入的行,节点表中的相应行被标记为已使用。

完成后,您可以删除所有未使用的节点。也就是说,我想现在您使用的是这样的东西:

delete from nodes where id not in (select start_node from edges);
delete from nodes where id not in (select end_node from edges);

并且我建议您执行以下操作:

delete from nodes where used = false;

As I mentioned in my comment, where is really no need to insert the edges that are blacklisted. Also, another problem comes to my mind. Why do you need to delete nodes from the nodes table anyway? You can add a special flag field (let's call it used) in the nodes table.

When you insert a new row to the nodes table, this field is set to false. Also you can implement a trigger for insert in edges table, that for every inserted row the appropriate rows in the nodes table are marked as used.

After you are done with that, you can just delete all the unused nodes. That is, I suppose right now you use something like this:

delete from nodes where id not in (select start_node from edges);
delete from nodes where id not in (select end_node from edges);

And I suggest you do the following:

delete from nodes where used = false;
别想她 2024-11-10 13:00:48

您可以使用渗透来执行该任务。然后你只需要提供一个边界框......
有关多个示例和进一步说明,请检查:此链接
(查看“示例用法”一章)

You can use osmosis to perform the task. Then you just have to provide a bounding box...
For multiple examples and further explanation check:this link
(Check the chapter "Example Usage")

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文