mysql - 如何从 .osm 文件在数据库中构建 'roads' 图形

标签 mysql postgresql xml-parsing openstreetmap

要求的结果:

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

背景:

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

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

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

问题是这个序列非常不可靠,它只在小型数据集上“马马虎虎”地工作,比如数千个节点,而不是数百万个。

问题:

对于由数百万个节点和边组成的数据库,道路提取(即根据特定标签过滤器生成边)非常慢。

可能的解决方案:

这次我要做什么:

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

问题:

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

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

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

我应该考虑关系吗?

如果是,我应该怎么做?

最佳答案

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

当您向节点表中插入新行时,此字段设置为 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;

关于mysql - 如何从 .osm 文件在数据库中构建 'roads' 图形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5790227/

相关文章:

php - 使用 Like 和 Left Join 进行搜索

mysql - Sequelize 说 instanceMethod 未定义

sql - 在postgresql中将日期转换为整数

mysql - Mysql根据条件INSERT INTO

java - 通过 Spring data.sql 文件生成示例数据库数据

python - 如何删除引用某个对象的所有嵌套对象?

java - 当我需要 DocumentBuilder 时使用 SAX 解析器

XmlPullParser - 如何跳到匹配的END_TAG?

java - 在 XstreamAliasing 中使用冒号时出现异常

php - 使用示例代码我发现可以计算纬度/经度 10 英里以内的位置