【问题标题】:Thin out many ST_Points减少许多 ST_Points
【发布时间】:2011-01-10 20:50:22
【问题描述】:

我在带有 postgis 的 postgres-db 中有许多 (1.000.000) ST_Points 扩大。当我在地图上显示它们时,浏览器变得非常繁忙。 为此,我想编写一个 sql 语句,将高密度过滤到一个点。
当用户缩小 100 个 ST_Points 时,postgres 应该只返回一个。 但前提是这些点靠得很近。
我用这个语句试了一下:

select a.id, count(*)
from points as a, points as b
where st_dwithin(a.location, b.location, 0.001)
and a.id != b.id
group by a.id

我会称之为瘦身但没有找到任何东西 - 可能是因为我 不是以英语为母语的人。 有人有什么建议吗?

【问题讨论】:

    标签: sql geospatial postgis


    【解决方案1】:

    我同意 tcarobruce 的观点,即集群是您正在寻找的术语。但它在 postgis 中可用。

    基本上可以通过减少X和Y中的小数位数并对其进行分组来实现聚类;

    select 
      count(*),
      round(cast (ST_X(geom) as numeric),3)
      round(cast (ST_Y(geom) as numeric),3)
    from mytable 
    group by 
    round(cast (ST_X(geom) as numeric),3), 
    round(cast (ST_Y(geom) as numeric),3)
    

    这将生成一个包含坐标和该坐标处实点数的表格。在这个特定的示例中,它会保留 3 位小数,即 0.001,就像在您的初始语句中一样。

    【讨论】:

    • 这个舍入有一个函数:例如 ST_SnapToGrid(geometry, 0.001)。您也可以以更复杂的方式定义网格,请参阅文档。
    【解决方案2】:

    您可以使用ST_ClusterDBSCAN 将附近的点聚集在一起

    然后保留所有单点,例如:

    1. 为每个集群选择一个随机点

    1. 选择每个点簇的质心。

    我使用eps 300 将 300 米内的点聚集在一起。

    create table buildings_grouped as
    SELECT geom, ST_ClusterDBSCAN(geom, eps := 300, minpoints := 2) over () AS cid
    FROM buildings
    

    1:

    create table buildings_grouped_keep_random as
    select geom, cid from buildings_grouped
    where cid is null
    union
    select * from 
    (SELECT DISTINCT ON (cid) *
    FROM buildings_grouped
    ORDER BY cid, random()) sub
    

    2:

    create table buildings_grouped_keep_centroid as
    select geom, cid from buildings_grouped
    where cid is null
    union
    select st_centroid(st_union(geom)) geom, cid
    from buildings_grouped
    where cid is not null
    group by cid
    

    【讨论】:

      【解决方案3】:

      您正在寻找的术语是“集群”。

      client-side 库可以执行此操作,commercial services 可以在服务器端执行此操作。

      但这不是 PostGIS 本身所做的事情。 (有一个ticket。)

      您可能必须编写自己的解决方案,并提前预计算您的集群。

      【讨论】:

        【解决方案4】:

        ST_ClusterDBSCAN- 和 KMeans- 基于集群的工作,但它非常慢!对于大数据集。所以它实际上是不可用的。 ST_SnapToGrid 和 ST_RemoveRepeatedPoints 等 PostGIS 函数更快,在某些情况下可以提供帮助。但我认为最好的方法是使用像sample filter 这样的 PDAL 细化过滤器。我建议将它与 PG 点云一起使用。

        编辑: ST_SnapToGrid 非常快速且有用。以下是优化三角剖分的示例查询:

            WITH step1 AS 
            (
                SELECT geometry, ST_DIMENSION(geometry) AS dim FROM table
            )
            , step2 AS 
            (
                SELECT ST_SIMPLIFYVW(geometry, :tolerance) AS geometry FROM step1 WHERE dim > 0
                UNION ALL
                (WITH q1 AS
                (
                    SELECT (ST_DUMP(geometry)).geom AS geometry FROM step1 WHERE dim = 0
                )
                SELECT ST_COLLECT(DISTINCT(ST_SNAPTOGRID(geometry, :tolerance))) FROM q1)
            )
            , step3 AS 
            (
                SELECT ST_COLLECT(geometry) AS geometry FROM step2
            )
            SELECT ST_DELAUNAYTRIANGLES(geometry, :tolerance, 0)::BYTEA AS geometry
            FROM step3 
            OFFSET :offset LIMIT :limit;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-01-03
          • 1970-01-01
          • 2017-01-28
          • 1970-01-01
          • 2019-05-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多