赞
踩
以PostGIS2.4版本说明,当前PostGIS已经提供了4种空间聚类的方法,列表如下:
ST_ClusterKMeans -- 该函数是窗口函数,主要是用K-means(K均值聚类)算法进行聚类,算法原理比较简单,容易实现,主要适用于点样本数据,如果是多边形则用多边形的中心点计算,只有一个参数K簇,就是事先明确了要把这一堆样本数据聚成K个类,然后去计算一个目标函数达到最优解,因此K值对结果影响比较大,不太好选取,而且该算法而且适合凸的数据集,这也算法容易收敛;
ST_ClusterDBSCAN -- 该函数也是窗口函数,主要利用DBSCAN算法对输入的地理要空间素进行聚类,该算法基于密度进行聚类,直觉上更加符合认知,主要是通过地理要素分布的紧密程度决定,同一类别的样本之间是紧密相连的,不同样本是分离的。该算法相对复杂,比较常用,聚类效果较好,详细原理这里不做介绍,Spark,python,r语言等提供的很多机器学习包都提供了该算法的实现,曾经也写过简单的python实现,有兴趣可查阅相关资料了解,能够直接用就行。该聚类方法用处比较大,有较多应用场景,比如可以应用于点抽稀,聚合展示,热力图,在数据量较大时实现在不同尺度下降低数据量的渲染等等
ST_ClusterIntersecting -- 该函数是一个聚合函数,方法比较好理解,顾名思义就是把相交关联关系的地理要素作为一个类簇。具体的函数声明和用法,看官网的例子介绍很容易看懂,也可以拿数据进行测试实验,不是很常用,不做重点;
ST_ClusterWithin -- 该函数也是一个聚合函数,也很好理解,顾名思义通过一个距离参数,将距离之内的地理要素聚成一个类别,距离之外的就是非同类。详细可参考官网,也不做重点;
ST_ClusterDBSCAN是一个窗口函数,基于DBSCAN算法,返回每一个输入的2D图形所在“簇”的id。
定义:integer ST_ClusterDBSCAN(geometry winset geom, float8 eps, integer minpoints);
参数说明:
geom:输入的2d图形对象。
eps:输入图形之间的距离如果小于eps规定的距离,他们就被化为同一“簇”。
minpoints:每个“簇”中图形最小数量。
使用说明:
- # 查询buildings的面图层中,建筑之间距离小于20米(0.0002是度,约20米)分类,且每一类中数量不少于2。
- gis_cluster=# SELECT gid,name, ST_ClusterDBSCAN(geom, eps:= 0.0002, minpoints := 2)
- over () AS cid FROM buildings;
-
- gid | name | cid
- -----+--------------+-----
- 1 | |
- 2 | | 2
- 3 | | 2
- 4 | | 2
- 5 | 大洋百货 |
- 6 | 商茂世纪广场 | 0
- 7 | 华威大厦 | 2
- 8 | 天安保险大厦 | 2
- 9 | | 2
- 10 | |
- 11 | 江苏交通大厦 | 2
- 12 | 阳光大厦 |
- 13 | | 0
- 14 | | 2
- 15 | | 2
- 16 | | 2
- 17 | | 2
- 18 | | 1
- 19 | | 1
- 20 | | 2
- 21 | | 2
- 22 | | 2
- 23 | | 2
- 24 | | 2
- 25 | | 2
- 26 | | 2
- 27 | | 2
- -- More --
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
-1的是不属于任何“cluster”的图形,也就是查询中cid是null的数据,其他的数据都有自己的所属“cluster”的id值,即cid值。
另外,和kmeans的区别
ST_ClusterIntersecting是一个聚合函数,返回一个GeometryCollections数组,每个数组中的geom都是直接或间接能相交的图形。
定义:geometry[] ST_ClusterIntersecting(geometry set g);
参数说明:
g:一组几何图形。
使用说明:
- gis_cluster=# select st_astext(unnest(ST_ClusterIntersecting(geom))) from buildings2;
-
- st_astext
- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- GEOMETRYCOLLECTION(POLYGON((118.77376608689 32.0424742122357,118.774542742962 32.0416518705121,118.773994515147 32.0411036426964,118.773172173423 32.0418802987687,118.77376608689 32.0424742122357)),POLYGON((118.774222943403 32.0429310687489,118.775898083951 32.0413320709528,118.775456455989 32.0407838431371,118.774542742962 32.0416518705121,118.77376608689 32.0424742122357,118.774222943403 32.0429310687489)),POLYGON((118.775898083951 32.0413320709528,118.777055453785 32.0402813009728,118.776629054372 32.0397635302578,118.775456455989 32.0407838431371,118.775898083951 32.0413320709528)))
- GEOMETRYCOLLECTION(POLYGON((118.771192461866 32.0393066737446,118.772684859809 32.0389259599839,118.772258460397 32.0379208756551,118.770705148252 32.0383320465169,118.771192461866 32.0393066737446)),POLYGON((118.772258460397 32.0379208756551,118.772684859809 32.0389259599839,118.774375228908 32.0384234178194,118.773964058046 32.0375097047933,118.772258460397 32.0379208756551)))
- GEOMETRYCOLLECTION(POLYGON((118.776766111326 32.0381188468106,118.778045309563 32.0377076759488,118.778167137966 32.0373117336375,118.777695052903 32.0366721345192,118.776080826556 32.0371746766835,118.776766111326 32.0381188468106)),POLYGON((118.778700137232 32.0380274755081,118.779857507065 32.0373878763897,118.779461564754 32.0368853342252,118.778730594333 32.0369614769774,118.778167137966 32.0373117336375,118.778045309563 32.0377076759488,118.778700137232 32.0380274755081)))
- (3 行记录)
已有数据被划分成了三类
聚合函数只返回了图形的集合出来,没带上记录的标记,该方法最好也能将记录的id返回比较好用。
ST_ClusterKMeans:均值中心聚类,窗口函数,对每个输入的图形,根据图形之间的二维distance进行均值中心聚类,返回聚类的id。distance指的是图形之间的centroids。
定义:integer ST_ClusterKMeans(geometry winset geom, integer number_of_clusters);
参数说明:
geom:输入的二维图形。
number_of_clusters:聚类的数量。
使用示例:
- #均值中心聚类,聚成3类
- gis_cluster=# SELECT gid,ST_ClusterKMeans(geom,3) over () AS cid,geom FROM buildings;
使用也比较简单,也好理解。
ST_ClusterWithin:聚合函数,对输入的图形,指定一个笛卡尔距离(距离单位是图形srid对应的单位),图形之间的距离在指定的距离内,则归并为一类。最后返回聚类后的图形数组。
定义:geometry[] ST_ClusterWithin(geometry set g, float8 distance);
使用简介:
- create table buildings6(
- id serial primary key,
- cid int,
- geom geometry(Polygon,4326)
- );
-
- do language plpgsql $$
- DECLARE
- rec record;
- num int;
- i int;
- BEGIN
- truncate table buildings6;
- --距离设置为约50米,改成0.0003就是约30米
- for rec in with a as (select unnest(ST_ClusterWithin(geom, 0.0005)) geom from buildings) select row_number() over() as id,a.geom from a loop
- num:=ST_NumGeometries(rec.geom);
- for i in 1..num loop
- insert into buildings6(cid,geom) select rec.id,ST_GeometryN(rec.geom, i);
- end loop;
- end loop;
- end;
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
聚类效果还是比较明显的。几个聚类函数比较常用,尤其在选址等应用上,不过具体的业务比简单的应用复杂多,笔者抛砖引玉,希望读者能有好的案例出现
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。