基于线路连通性的PostGIS递归查询


9

我在查询时遇到困难。我有一个线串网络,每个线串在n_type列中都有一个值。这可能是少数选项之一。我想生成一个新表,该表将具有相同类型并形成连续线的所有线串分组。

之前:

在此处输入图片说明

后:

在此处输入图片说明

这是我到目前为止所得到的。它返回结果,但它们没有任何意义-类型不匹配,并且返回太多功能。

另请注意,我将“连续”定义为距其邻居5英尺以内且相交的角度小于30度的任何直线。

WITH RECURSIVE all_links (i, pk_uid, n_type, geom) AS (
    SELECT  1 AS i,
            pk_uid,
            n_type,
            geom
    FROM    network
    WHERE   n_type != 'none'

    UNION ALL

    SELECT  a.i + 1,
            b.pk_uid,
            b.n_type,
            b.geom
    FROM    network b, all_links a
    WHERE   b.n_type = a.n_type
    AND     b.geom <#> a.geom <= 5  --lines are continuous if within 5 feet of neighbor
    AND     ABS( DEGREES( 3*pi() - st_azimuth(st_startpoint(a.geom),st_endpoint(a.geom)) + st_azimuth(st_startpoint(b.geom),st_endpoint(b.geom)))::int % 360 - 180) <= 30 )  --only take links within 30 degrees of the same angle

SELECT i, n_type, ST_Union(the_geom) FROM all_links GROUP BY i, n_type

我以为递归查询是可行的方法,但是我很高兴在此方面被证明是错误的。递归有点难以理解。

编辑:我还应该补充一点,我已经尝试使用ST_Union和ST_Linemerge进行聚合,然后转储结果。这种方法有效,但不能解决> 30度的相交问题,也不能满足5英尺的连接公差。


无需深入研究,有两个观察。您将需要在select子句中合并a.geom和b.geom。您可能应该确保不要尝试与a.pk_uid != b.pk_uid
MickyT

@MickyT谢谢。我应该提到,我可以在最后一个SELECT子句中进行并集,但是暂时只选择了*,这样我就可以看到所有结果。我将修改我的代码片段以显示最终的外观。
spencerrecneps

递归查询很难理解。大声笑和+1
John Powell

快速浏览表明您的基本/锚查询可能存在问题。您需要为每条线(A,B,C等)选择起点,然后在递归部分中建立起点。可能需要在锚查询中添加某种排序(可能在x或y方向上,如果不查看数据就很难知道)。我将对此进行细分,并确保在继续递归部分之前先获得明智的起点。我最近使用递归查询来找到时间序列中的条纹,一旦我正确地确定了锚点,其余的就很容易了
John Powell

@dbaston。很好,但是您也可以使用递归查询来完成此操作,但并不是每个人都已经安装了该查询。
约翰·鲍威尔,

Answers:


1

正如JohnBarça所说,您的解决方案至少缺少对线路组件的预订购。

我会说,递归查询非常非常难以理解。

您必须尝试在新的数据库函数中复制ST_Linemerge行为。我将首先尝试查看ST_Linemerge实现的源并进行复制,将其更改为产生30度角抽动。

要从聚合中丢弃角度不小于30度的线段,必须在聚合环内进行比较。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.