目录
前言
一、ST_Union()简介
1、方法说明
2、参数介绍
二、ST_Collect()简介
1、方法说明
2、参数介绍
3、两者区别
三、实际案例实践
1、不重叠融合
2、空间重叠融合
总结
众所周知,熟悉GIS桌面软件的同学一定都知道,想要对空间中的两个或者多个地理数据进行融合,可以使用融合的工具。常见的桌面软件,比如ArcGIS或者QGIS、SuperMap等均有成熟的工具。以QGIS为例,可以使用工具包中的合并工具,如下所示:
在日常的工作当中,可以采用这些工具进行数据的融合。只是这些数据操作通常需要人工进行干预,而且数据不能实时进行。比如有时候,我们已经将这些数据保存到了空间数据库PostGIS中,而用户可能会随机抽取一些空间数据进行动态的融合。
应对上面的场景,我们就可以采用SQL查询的方式来满足。比如在实际需求中,需要将某几个城市的空间数据进行融合形成新的数据以供查询分析。而在进行数据融合的时候,通常我们可以选用PostGIS中的ST_Union()和ST_Collect()这两个函数。
这两个函数乍一看几乎是一样的,其实两者还是有一些区别的,但是通过官网的介绍又不是特别清楚。因此本文采用实例的方式进行讲解,将ST_Union()和ST_Collect()这两个函数进行空间融合实战,我们通过实际的两个面的函数操作和实际场景融合,来看看两个函数的具体使用。
在PostGIS中,对于st_union函数的定义有以下的几个入参,我们来看一下定义:
st_union函数的定义如下:
CREATE OR REPLACE FUNCTION "public"."st_union"("geom1" "public"."geometry", "geom2" "public"."geometry")
RETURNS "public"."geometry" AS '$libdir/postgis-3', 'ST_Union'
LANGUAGE c IMMUTABLE STRICT
COST 10000
与Java的方法重载类似,st_union方法有5个重载。
序号 | 方法 |
1 | st_union(geometry, geometry) |
2 | st_union(geometry, geometry, float8) |
3 | st_union(_geometry) |
4 | st_union(geometry) |
5 | st_union(geometry, float8) |
在上面的方法介绍中,geometry表示一个空间对象,float8的参数表示数据精度。注意,使用st_union函数进行运算之后,得到的结果是合并输入几何体,合并几何体以生成没有重叠的结果几何体。输出可以是原子几何图形、多重几何图形或几何图形集合。请一定注意这里合并的描述。
首先来看在PostGIS数据库中对于st_collect()函数的定义。
st_collect函数的定义SQL如下:
CREATE OR REPLACE FUNCTION "public"."st_collect"("geom1" "public"."geometry", "geom2" "public"."geometry")
RETURNS "public"."geometry" AS '$libdir/postgis-3', 'LWGEOM_collect'
LANGUAGE c IMMUTABLE
COST 50
序号 | 函数 | 说明 |
1 | geometry ST_Collect(geometry g1, geometry g2); | 接受两个输入几何 |
2 | geometry ST_Collect(geometry[] g1_array); | 接受几何图形数组 |
3 | geometry ST_Collect(geometry set g1field); | 接受几何图形行集的聚合函数 |
将几何图形收集(聚合)到几何图形集合中。结果是一个多*或一个GeometryCollection,这取决于输入几何的类型是相同的还是不同的(同构或异类)。输入几何图形在集合中保持不变。这里特别要注意的描述是聚合,与上面的函数相比,合并和聚合是两个概念。
如果单纯的从文字上讲,合并和聚合是一个近义词,表示两者的概念是差不多的。实际上两者的区别比较大,尤其是在空间运算中。可以用这句话来概括:ST_Collect将几何图形聚合到一个集合中,而不会以任何方式更改它们。ST_UNION以几何形式合并重叠的几何图形,并在交点处拆分线串。融合边界时,它可能会返回单个几何图形。
简单来理解就是,使用st_collect进行运算,不会改变数据;而用st_union进行空间运算,会改变原有的数据。下面就进行实际的讲解。
在这里将采用面数据进行讲解,这里选择的面数据又分两种。第一种情况是空间不重叠融合,第二种是空间重叠融合,通过实际的例子来看一下在不同的空间关系中,两个函数的融合结果是什么样的。
空间不重叠融合中,我们采用保存在PostGIS数据库中的城市信息进行实例开展,对长株潭三个城市进行融合。
biz_city的表数据如下所示:
st_union融合sql:
select st_asgeojson(st_union(geom)) from biz_city where city_name in ('长沙市','株洲市','湘潭市');
查询结果如下:
来看QGIS的结果:
通过上图可以看出,使用st_union之后,三个城市已经完全融合,从而形成了一个全新的数据。下面再来看看st_collect函数的运行效果。
select st_asgeojson(st_collect(geom)) from biz_city where city_name in ('长沙市','株洲市','湘潭市');
来看一下在QGIS中的展示结果:
从总体来看,虽然长株潭三个城市同样合成了,但是三个城市的边界还是存在的,并没有进行融合。而在geojson的type中明确了两个的区别。
结论:在空间不重叠的情况下,使用st_union和st_collect的合并结果虽然不大,但是对于数据是否改变来说,影响还是很大的。
首先我们准备两份空间上重叠的数据,我们可以采用一下的模拟数据进行展示。
A B 图作为测试图形,用来验证这些函数的使用
-- A 图
select ST_GeomFromGeoJSON('{"type":"Polygon","coordinates":[[[120.52757263183594,31.495432803134843],[120.59211730957031,31.31199502365151],[120.89012145996094,31.35950051982242],[120.74729919466666,31.483245492650792],[120.52757263183594,31.495432803134843]]]}')
-- B 图
select ST_GeomFromGeoJSON('{"type":"Polygon","coordinates":[[[120.74386596679688,31.487235582017444],[120.84548950195312,31.269747790889888],[121.01783752441405,31.378261512889125],[120.91827392578125,31.487821121636433],[120.74386596679688,31.487235582017444]]]}')
将上述两个空间数据转成geojson,在QGIS中展示如下,首先是A图
下面是B图:
将两者空间叠加后,可以看到空间关系:
st_union融合语句:
-- ST_Union在几何形状重叠的地方对其进行几何合并,并在相交处拆分线串。溶解边界时,它可能会返回单个几何。
select ST_Union (
ST_GeomFromGeoJSON('{"type":"Polygon","coordinates":[[[120.52757263183594,31.495432803134843],[120.59211730957031,31.31199502365151],[120.89012145996094,31.35950051982242],[120.52757263183594,31.495432803134843]]]}'),
ST_GeomFromGeoJSON('{"type":"Polygon","coordinates":[[[120.74386596679688,31.487235582017444],[120.84548950195312,31.269747790889888],[121.01783752441405,31.378261512889125],[120.91827392578125,31.487821121636433],[120.74386596679688,31.487235582017444]]]}')
)
st_collect融合语句:
-- ST_Collect将几何形状聚合到一个集合中,而无需进行任何更改。
select ST_Collect (
ST_GeomFromGeoJSON('{"type":"Polygon","coordinates":[[[120.52757263183594,31.495432803134843],[120.59211730957031,31.31199502365151],[120.89012145996094,31.35950051982242],[120.74729919466666,31.483245492650792],[120.52757263183594,31.495432803134843]]]}'),
ST_GeomFromGeoJSON('{"type":"Polygon","coordinates":[[[120.74386596679688,31.487235582017444],[120.84548950195312,31.269747790889888],[121.01783752441405,31.378261512889125],[120.91827392578125,31.487821121636433],[120.74386596679688,31.487235582017444]]]}')
)
通过实验,同样可以得到上面的结论,使用st_collect对于原来的空间数据没有什么改变,而st_untion对数据的改变很大。
所以,到了这里一定要深深的理解合并和聚合的区别。在实际项目过程中,根据需要进行合理的选择。
以上就是本文的主要内容,本文采用实例的方式进行讲解,将ST_Union()和ST_Collect()这两个函数进行空间融合实战,我们通过实际的两个面的函数操作和实际场景融合,希望通过实战的方式让你了解两者的区别,在具体使用空间函数的时候给予充分的评估和参考。行文仓促,不免有错误,欢迎朋友进行批评指正交流。
本文部分参考博文,原文地址:postgis函数知识积累