POSTGIS - 可以合并网络线,以便每个结果代表一个连接集?

Posted

技术标签:

【中文标题】POSTGIS - 可以合并网络线,以便每个结果代表一个连接集?【英文标题】:POSTGIS - Possible to merge network lines, such that each result represents one connected set? 【发布时间】:2014-09-05 19:10:07 【问题描述】:

本质上,如果我们有一个代表许多小子盆地的流线网络,有没有办法将每个子集相互合并,这样生成的输出对于每个小子盆地都有一个多线特征?我们希望将每个段与仅存在于每个组的下游终端段上的值相关联。

很好奇是否有一种解决方案可以像 Arc 中的溶解一样不使用任何属性,但不是全部溶解,它只会将那些接触/流动的内容组合在一起。

如果每个组有一个标识属性值,我已经看到一些发布的解决方案,但如果我们有这个,我们也可以在 Arc 中完成。

到目前为止,我提出的最佳解决方案(我们有 to_node 和 from_node 值)是循环遍历,将每个段跟踪到其最终相关的终端下游段。这肯定需要一些时间,我觉得肯定有更好的方法。

任何帮助将不胜感激。也许我忽略了一些简单的事情。提前致谢!

这是当前正在运行的内容。请注意,线集称为“lines_4326”,我使用一个名为“PARENT”的字段来跟踪终端 to_node 值,而“line_ends”是一个表,仅包含终端段的 to_node 值(如集合中没有 from_node 值 = 该列表中的值)。

CREATE OR REPLACE FUNCTION "TRACE_DOWN"() RETURNS void AS $$ DECLARE

count_left 整数;

开始

更新行_4326 SET "PARENT" = to_node;选择计数(gid)从 lines_4326 WHERE "PARENT" NOT IN (SELECT to_node from line_ends) INTO count_left;

WHILE count_left > 0 循环

UPDATE lines_4326 SET "PARENT" = b.to_node FROM lines_4326 b WHERE lines_4326."PARENT" = b.from_node;

SELECT COUNT(gid) FROM lines_4326 WHERE "PARENT" NOT IN (SELECT to_node FROM lines_4326 WHERE "IS_END" = '1') INTO count_left;

结束循环;

结束; $$ LANGUAGE 'plpgsql' 易失性

【问题讨论】:

你有一些你已经尝试过的代码可以展示给我们吗? ST_Union 不是在做所有的工作吗?? 从问题中很难判断,但您可以使用WITH RECURSIVE 查询代替循环,测试一条线段的末端是否触及另一条线段。这将填充您的to_node ID。 @MikeT。我想知道同样的事情,但问题似乎比代码示例简单? @MikeT。幸运的是,由于几何网络的初始创建,我已经填充了往返节点。我在上面复制的代码示例只是为了使用这些现有值来跟踪每个“下游”段。这给了我一个在 Arc 中溶解的价值。对于 1M+ 功能来说,它只是相当耗时。我发布了这个问题,希望有一个简单的解决方案可以一次获取相关网络中的所有功能并在它们上贴上标签,而无需以这种方式进行跟踪。感谢您有兴趣帮助我找到解决方案 :) 【参考方案1】:

嘿, 我知道这是一篇旧帖子,但......也许它会帮助别人

所以,在寻找类似 ZFlyGuy 问题的解决方案时,我发现了这个(这里:https://georezo.net/forum/viewtopic.php?id=71450)

select (st_dump(st_linemerge(st_union(the_geom)))).geom from lines;

这对我来说是解决方案的一部分

也许我们也会提供帮助,但我还没有阅读:https://github.com/Oslandia/presentations/raw/master/pgconf_eu_2012/pgconfeu2012_vincent_picavet_postgis_topology.pdf

【讨论】:

【参考方案2】:

您想将ST_Union 与ST_Dump 结合使用。 ST_Dump 会将 ST_Union 的结果分解为单个(多)线串。

Select (ST_Dump(ST_Union(line))).geom from Lines_4326;

假设你的线段叫做线。

因为ST_Dump是一个集合返回函数,它返回一行和一个几何,所以你需要使用语法(ST_Dump(geomcoll)).geom来获取组成几何。 ST_Union 相当于 Arc 世界中的 Dissolve,不需要任何属性即可工作。它将返回几何集合、多几何或单个几何,具体取决于输入,但在您的情况下,它将返回由(多)线串组成的几何集合。

要在某些工具(例如 QGIS)中查看输出,您需要为每个不同的几何图形设置一个 id 字段,这可以通过使用 row_number() over() 来完成,例如,

Select row_number() over() as id, (ST_Dump(ST_Union(line))).geom from Lines_4326;

编辑 在 OP 对这种方法的效率发表评论后,请注意 Paul Ramsey(Postgis 的创建者)的 this blog article 关于级联联合和索引的有效使用,因为联合正在建成。

【讨论】:

我知道答案似乎很简单,所以我想知道我误解了这个问题吗?您要求的内容与您的代码示例不太相符,这就是我问的原因。 嗨,约翰。很可能就这么简单..但是当我有几百万行时这会有效吗?我没有作为联盟基础的属性,也无法找到一种方法来以一种通用方式标记不同网络中的所有特征,从而给我一个属性。如果我理解正确,您的方法会将所有行合并,然后转储会将它们分解为单独的相关家族?再次感谢。 我已经用几年前读过的一篇关于这个确切主题的博客文章更新了答案,并指出索引用于智能地将几何组合在一起。最终,没有什么可以替代尝试并查看性能如何。 你找到答案了吗?

以上是关于POSTGIS - 可以合并网络线,以便每个结果代表一个连接集?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 PostGIS 添加到 PostgreSQL pgAdmin?

如何将 Spark/Scala RDD 合并/加入到 List 中,以便 RDD 中的每个值与每个 List 项一起获得一个新行

如何合并来自多行的值,以便它们可以一起处理 - Spark scala

PostGIS查询总是带回所有结果

我想创建一个用于地理处理的桌面基础应用程序并将结果存储在 PostgreSQL(postgis)中!

如何合并每个线程结果 - java