遇到了一个需求,要对数据库里比较近的点进行空间和属性的聚类合并,以便在显示时避免很多点堆在一起的问题。属性聚类比较简单,这里主要讲一下在空间聚类的一些经验。
目录
PostGIS主要有四个关于聚类的函数
- ST_ClusterKMeans 窗口函数,返回聚类id,基于K-means 聚类算法
- ST_ClusterIntersecting 对空间相交的几何体归为一类,返回的是聚类后的多边形集合,聚合函数
- ST_ClusterDBSCAN 类似于ST_ClusterKMeans,使用的是DBSCAN 算法
我在实验时主要用的是ST_ClusterDBSCAN函数。
ST_ClusterDBSCAN的使用方法
integer ST_ClusterDBSCAN(geometry winset geom, float8 eps, integer minpoints)
ST_ClusterDBSCAN有三个参数:
- geom 是需要做聚类对应的空间字段
- eps 是聚类时半径。官方文档并没有写明这个半径的单位,这一点在使用时一定要注意。经测试发现,这个半径的单位用的是第一个参数geom的坐标系的单位。如果你需要半径的单位为m,第一个参数一定要转换为m为单位的平面坐标系,如SRID3857。如果以度为单位,第一个参数geom一定要转换成以度分秒为单位的坐标系。
- minpoints 每个集群的最小数量
具体使用
-- st_transform是将空间字段转换到投影坐标系下,以米为单位计算聚类半径
select shape, ST_ClusterDBSCAN((st_transform(shape,3857)),eps := 200.0, minpoints := 1) over () AS cid from dt_yzebdb
-- 空间加属性聚类
select shape, ST_ClusterDBSCAN((st_transform(shape,3857)),eps := 200.0, minpoints := 1) over (partition by id_of_insured,policy_no,year,species_code) AS cid from dt_yzebdb