【问题标题】:Spatial Clustering - associate cluster attribute (id) to the geometry that is part of the cluster空间聚类 - 将聚类属性 (id) 与属于聚类的几何图形相关联
【发布时间】:2017-04-01 20:51:59
【问题描述】:

我在将一组几何图形与其自身属性相关联时遇到了一些问题。

数据

我有一张带有一组几何图形的表格,

buildings {
gid integer,
geom geometry(Multipoligon,4326)
}

我已经在“buildings”表上运行了具有特定阈值的函数ST_ClusterWithin。 从那个聚类分析中,我得到了一个名为“clusters”的表,

clusters {
cid Integer,
geom geometry(GeometryCollection,4326)
}

问题

我很想将所有几何及其自己的集群信息提取到一个表中。

clustered_building {
gid Integer
cid Integer
geom geometry(Multipoligon,4326)
}

 gid |    cid     |       geom            |   
-----+------------+-----------------------+
  1  |     1      | multypoligon(...)     |
  2  |     1      | multypoligon(...)     |
  3  |     1      | multypoligon(...)     |
  4  |     2      | multypoligon(...)     |
  5  |     3      | multypoligon(...)     |
  6  |     3      | multypoligon(...)     |

我做了什么(但不起作用)

我一直在尝试使用两个函数 ST_GeometryN / ST_NumGeometries 解析每个 MultyGeometry 并使用源自 ST_Geometry 手册页的标准示例之一的查询提取集群的信息。

INSERT INTO  clustered_building (cid, c_item , geom)
SELECT sel.cid, n, ST_GeometryN(sel.geom, n) as singlegeom
FROM ( SELECT cid, geom, ST_NumGeometries(geom) as num
       FROM clusters") AS sel
       CROSS JOIN generate_series(1,sel.num) n
WHERE n <= ST_NumGeometries(sel.geom);

查询,如果我强制使用一系列 10 则需要几秒钟。

CROSS JOIN generate_series(1,10)

但是当我要求根据每个 GeometryCollection 中的项目数生成一个系列时它卡住了。 而且,这个查询不允许我将单个几何体与他自己的特征链接到构建表中,因为我失去了“gid”

有人可以帮助我吗? 谢谢

斯特凡诺

【问题讨论】:

    标签: sql cluster-analysis postgis


    【解决方案1】:

    我没有你的数据,但使用一些虚拟值,其中 ids 1、2 和 3 相交以及 4 和 5,你可以执行以下操作:

    WITH 
      temp (id, geom) AS 
        (VALUES (1, ST_Buffer(ST_Makepoint(0, 0), 2)),
        (2, ST_Buffer(ST_MakePoint(1, 1), 2)),
        (3, ST_Buffer(ST_MakePoint(2, 2), 2)), 
        (4, ST_Buffer(ST_MakePoint(9, 9), 2)), 
        (5, ST_Buffer(ST_MakePoint(10, 10), 2))),
      clusters(geom) as 
        (SELECT 
            ST_Makevalid(
              ST_CollectionExtract(
                  unnest(ST_ClusterIntersecting(geom)), 3)) 
          FROM temp
        )
     SELECT array_agg(temp.id), cl.geom 
       FROM clusters cl, temp 
      WHERE ST_Intersects(cl.geom, temp.geom) 
    GROUP BY cl.geom;
    

    如果你把最终的 cl.geom 包装成 ST_AsText,你会看到类似这样的东西:

    {1,2,3} | MULTIPOLYGON(((2.81905966523328 0.180940334766718,2.66293922460509 -0.111140466039203,2.4142135623731 -0.414213562373094,2.11114046603921 -0.662939224605089,1.81905966523328 -0.819059665233282,1.84775906502257 -0.765366864730179,1.96157056080646 -0.390180644032256,2 0,2 3.08780778723872e-16,2 0,2.39018064403226 0.0384294391935396,2.76536686473018 0.152240934977427,2.81905966523328 0.180940334766718))......

    {4,5} | MULTIPOLYGON(((10.8190596652333 8.18094033476672,10.6629392246051 7.8888595339608,10.4142135623731 7.58578643762691,10.1111404660392 7.33706077539491,9.76536686473018 7.15224093497743,9.39018064403226 7.03842943919354,9 7,8.60981935596775 7.03842943919354,8.23463313526982 7.15224093497743,7.8888595339608 7.33706077539491,7.58578643762691 7.5857864376269,7.33706077539491 7.88885953396079,7.15224093497743 8.23463313526982

    您可以在其中看到第一个多面体下方的 ids 1、2、3 和另一个 4,5。

    总体思路是对数据进行聚类,然后将返回的聚类与原始数据相交,使用array_agg 将 id 分组在一起,这样返回的 Multipolygons 现在包含原始 id。使用 ST_CollectionExtract 和 3 作为第二个参数,与 unnest 结合使用,将 ST_ClusterIntersecting 返回的几何集合拆分回行,将每个连续集群作为(多)多边形返回。 ST_MakeValid 是因为有时当您将几何图形与其他相关几何图形(例如原始多边形与集群多边形)相交时,您会得到奇怪的舍入效果和关于非节点交叉点的 GEOS 错误等。

    我最近在 gis.stackexchange 上回复了 similar question,您可能会觉得有用。

    【讨论】:

    • 感谢您的明确答复。我现在将在我的数据集上尝试。我不知道在真实几何和集群几何之间运行 ST_Intersect 的可能性。这种方式应该可以工作!! :) 伟大的。再次感谢您!
    猜你喜欢
    • 2018-02-02
    • 1970-01-01
    • 1970-01-01
    • 2018-10-10
    • 1970-01-01
    • 2015-08-21
    • 2016-08-07
    • 2012-07-22
    相关资源
    最近更新 更多