使用PostGIS识别道路交叉口


17

我正在尝试确定道路相交的位置,并在此相交处定点,并列出构成该相交处的道路数量。

在此处输入图片说明

我想知道是否有使用ST_NumPoints的方法来实现此目的,但是我不太清楚应该怎么做。我所做的是使用以下代码创建线相交的点表:

CREATE TABLE test_points as
SELECT      
    ST_Intersection(a.geom, b.geom),
    a.gid
FROM
    roads as a,
    roads as b
WHERE
    ST_Touches(a.geom, b.geom);

如果我在道路样本上运行此代码,则会得到以下点网格(道路仅供参考):

在此处输入图片说明

如果检查这些点之一,就会发现有很多点彼此叠放:

在此处输入图片说明

这里的GID是道路ID,但我不明白为什么会有很多点。我可以理解中央道路交叉路口被计算出的4个点,但是这里列出了12个点。有没有更好的方法在PostGIS中执行此计算?

Answers:


21

如果您分组,则应该仅获得唯一积分。

CREATE TABLE test_points as
SELECT      
    ST_Intersection(a.geom, b.geom),
    Count(Distinct a.gid)
FROM
    roads as a,
    roads as b
WHERE
    ST_Touches(a.geom, b.geom)
    AND a.gid != b.gid
GROUP BY
    ST_Intersection(a.geom, b.geom)
;

请注意,按几何分组会导致按几何的bbox分组,而不是按几何本身分组。处理分数时没关系。好吧,差不多。Bboxes的精度低于该点本身,这在理论上可能导致将不相同的两个点组合在一起。
NicklasAvén2012年

谢谢@NicklasAvén。Bbox比较有多精确?我希望它足以满足此用例。
昏暗

1
谢谢@underdark。您知道我如何计算相交的行数吗?我尝试了COUNT()诸如COUNT(ST_Touches(..))和的一些组合,COUNT(ST_Intersection(..))但这似乎不起作用,因为所有值都是如此12
djq 2012年

@underdark,是的,这已经足够了,这就是为什么我写了“理论上”。该框位于float4中,点的坐标为双精度。因此,对于ST_Point(1.000001,1.0)和ST_Point(1.000002,1.0),该框将看起来相同(至少在我的系统上,我刚刚尝试过。它将to点组合在一起)。在开发人员列表上讨论框和实际几何图形之间的区别已经有一段时间了。
NicklasAvén2012年

参见@AlexOs建议的修改方式gis.stackexchange.com/a/151277/3195
Martin F

6

这比您预期的要复杂一些。那是因为没有比对更好的分析关系的好方法了。您不能在函数中放入三行并询问它们是否相交。

但是,至少一种方法可能是先找到路口,然后检查每个路口有多少条道路在接触(都可以在同一查询中完成)。

如果您的道路相互之间完美连接,并且没有道路通过交叉路口,那么您可以执行以下操作(未经测试):
使用被遗忘的组子句进行编辑(仍然未经测试):

SELECT distinct_crosspoints.geom as crossing, array_agg(roads.gid), count(*) FROM
  (SELECT DISTINCT (geom) geom FROM 
    (SELECT ST_Intersection(a.geom, b.geom) geom 
     FROM roads a, roads b 
     WHERE ST_Intersects(a.geom, b.geom)
    ) all_crosspoints
   ) distinct_crosspoints
   ,roads 
 WHERE ST_Intersects(distinct_crosspoints.geom, roads.geom)
 GROUP BY distinct_crosspoints.geom;

如果道路连接不正确和/或某些道路通过交叉路口,则情况会更加复杂。

HTH

尼克拉斯


嗨@Nicklas,我无法运行它。两个内部子句可以正常工作;我应该用distinct_crosspoints ,roads表名(roads_test)替换吗?我确实尝试过,但是随后得到一个关于geom模棱两可的错误。
djq 2012年

1
@celenius,对不起,我忘记了group子句。我还看到,您不需要在其他方面加区别。您可以直接将其放在交叉路口上。请注意,根据下划线答案下的讨论,“与众不同”具有与group by相同的行为。
NicklasAvén2012年

我向Nicklas答案添加了distinct_crosspoints.geom,以使查询运行。现在为我工作。
弗兰克,

1
 CREATE TABLE test_points as
    SELECT      
        ST_Intersection(a.geom, b.geom),
        Count(Distinct a.gid)
    FROM
        roads as a,
        roads as b
    WHERE
        ST_Touches(a.geom, b.geom)
        AND a.gid < b.gid   /* !!! Changed "!=" for "<"  */
    GROUP BY
        ST_Intersection(a.geom, b.geom)
    ;

如果线A(id 1)与线B(id 2)交叉,则这是我们需要的交点。但是线B在同一点也越过线A。但是我们不需要两次。这就是为什么我用a.gid < b.gid 而不是a.gid != b.gid

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.