当前位置: 首页 > news >正文

SQL语句--postgis语句(矢量数据的定义与操作)

postersql相对于其它数据库有一个明显的优势,就是它拥有postgis这个地理空间的数据库模块,是每一位gis学者必不可少的工具。

postgis常见的数据类型描述

box2d 矩阵框类型:由矩阵框左下角、右上角坐标组成。例如:box2d(0 0,5 5)
box3d 长方体类型:由长方体左前下角,右后下角组成。例如,box3d(0 0 0 ,5 5 5 )
bytea 相当于BLOB类型,表示一个可变长的二进度值
geometry 用几何平面系表示几何要素类型
geometry[] 几何数据类型数组:有多个几何类型组成的数组
geometry set 几何数据类型的集合
geography 使用大地(椭球)坐标系表示的几何要素的类型
geomval 一种复合数据类型,由.geom字段引入的几何图形对象和val组成,val是表示栅格标注栏中 特定几何位置的像素值的双精度值
addbanding 一种复合类型,用于输入到ST_AddBand函数,用于定义栅格波段的初始化值和属性
reclassarg 一个复合类型,用于输入到ST_Reclass 函数,用于定义重分类的行为参数
summarystats 一种复合类型,用于承载ST_SummaryStats,ST_SummaryStatsAgg两函数的返回值
unionarg 一种复合类型,用于输入到ST_Union函数,用于定义联合操作的相关参数

数据定义与插入

基本语句的语法不变这里只写几个例子供参考
建立名为landuse的土地利用数据表,属性包括id号(landuse_id),名称(name),几何列(the_geom),面积(area),周长(perimeter)等。其中ID号为主键,不能为空且值是唯一的。

CREATE TABLE landuse
(
landuse_id INT4 NOT NULL,
name varchar(20),
the_geom geometry,
area float8,
perimeter float8,
constraint landuse_pkey primary key (landuse_id)
);

postgis中的默认索引方法是B树,如果要建立R树等空间索引,需要指明索引方法。

create index geo_idx on landuse using rtree (the_geom);

将一条新的土地利用数据记录(id:12,名称:Timber-forest;几何列:WKB描述:01010000001DDB93F460BB4241A84E5AC86F455441;面积:47806700;周长:34246.2)插入到landuse表中

insert into landuse(landuse_id,name,the_geom,area,perimater)
value ('12','Timeber-forest','01010000001DDB93F460BB4241A84E5AC86F455441','4.78067e+007','3.12162e+004');

将landuse表中ID号小于15的记录存入表landuse_new中

insert into landuse_new(landuse_id,name,the_geom,area,perimater)
select *from landuse
where landuse_id<15;

表的管理函数

部分PostGIS管理函数
AddGeometryColumn(varchar,varchar,int4,varchar,int4) 添加几何字段(对应ALERT)
DropGeometryColumn(varchar,varchar,varchar) 删除几何字段(对应ALERT)
DropGeometryTable(varchar,varchar) 删除一个空间表(对应DROP TABLE)
Populate_Geometry_Columns() 确保集合列遵循一定的规则(对应ALERT)
Probe_Geometry_Columns() 扫描数据库几何字段,若GEOMETRY_COLUMNS表中尚无其元数据信息,则在该中添加
Find_SRID(varchar,varchar,varchar) 返回某空间表某空间列的空间参考系ID
updateGeometrySRID(varchar,varchar,int4) 更新某空间表某空间列的空间参考系ID
update_Geometry_Stats(varchar,varchar) 更新空间表的统计信息

下面以AddGeometryColumn函数为例进一步介绍其使用方法。其参数为:表的模式名,表名,列名,空间参考,数据几何类型,几何对象数据类型的维数。

在landuse表中添加一个新的几何字段geom,其空间查询语句如下:

SELECT AddGeometryColumn('public','landuse','geom','-1','POLYGON',2)

几何构造函数

下面以ST_GeomFromText(text,[])和ST_LineFromWKB(bytea,[])函数为例进一步介绍使用方法。ST_GeomFromText的第一个参数为文本类型,是某个几何对象的WKT描述;ST_LineFromWKB第一个参数为长二进制类型,是某个几何对象的WKB描述。
构造名为aline的LINESTRING(1 2,3 4)几何对象。空间查询语句如下:

select st_lineFromWKB(ST_AsBinary(ST_GeomFromText('LINESTRING(1 2,3 4)')) )AS aline;

其中,ST_AsBinary的作用是将Geometry类型转换为WKB类型的函数
函数拆解与执行顺序(从内到外)
​​ST_GeomFromText(‘LINESTRING(1 2,3 4)’)​​
​​作用​​: 将 WKT(Well-Known Text)格式的字符串转换为 PostGIS 的几何对象。
​​输入​​: ‘LINESTRING(1 2,3 4)’(文本表示的线段,由点 (1,2) 和 (3,4) 组成)
​​输出​​: PostGIS 的 LINESTRING 几何对象。
​​ST_AsBinary(…)​​
​​作用​​: 将 PostGIS 几何对象转换为 WKB(Well-Known Binary)格式。
​​输入​​: 上一步生成的 LINESTRING 几何对象。
​​输出​​: 二进制表示的几何数据(如 \x010200000002000000000000000000f03f000000000000004000000000000008400000000000001040)。
​​ST_LineFromWKB(…)​​
​​作用​​: 将 WKB 格式的二进制数据转换回 PostGIS 的线几何对象。
​​输入​​: 上一步生成的 WKB 数据。
​​输出​​: 与原始输入等价的 LINESTRING 几何对象。
​​AS aline​​
​​作用​​: 将结果列命名为 aline。

几何访问函数

用ST_IsSimple 函数判断下面两个几何对象是否为简单对象,空间查询语句如下:

-- ✅ 正确语法:分别检查两个几何体的简单性
SELECT ST_IsSimple(ST_GeomFromText('LINESTRING(1 1,2 2,1 3,1 2,2 1)')) AS smpl_line,ST_IsSimple(ST_GeomFromText('POLYGON((0 0,0 1,1 1,1 0,0 0))')) AS smpl_plygn;

几何体分析
1. 线几何体 LINESTRING(1 1,2 2,1 3,1 2,2 1)
​​坐标序列​​:点依次为 (1,1) → (2,2) → (1,3) → (1,2) → (2,1)
​​自相交检查​​:
线段 (1,1)-(2,2) 与 (1,2)-(2,1) 在点 (1.5,1.5) 处相交。
线段 (1,3)-(1,2) 是垂直线段,与其他线段无交叉。
​​结果​​:存在自相交 → ​​非简单几何体​​ (smpl_line = false)
2. 多边形 POLYGON((0 0,0 1,1 1,1 0,0 0))
​​坐标序列​​:点依次为 (0,0) → (0,1) → (1,1) → (1,0) → (0,0)
​​闭合性检查​​:首尾点相同,闭合正确。
​​边交叉检查​​:
边 (0,1)-(1,1) 和 (1,0)-(0,0) 在点 (0.5,0.5) 处交叉(因为顶点顺序错误)。
正确的简单多边形顶点顺序应为顺时针或逆时针,此处顺序导致边交叉。
​​结果​​:边交叉 → ​​非简单几何体​​ (smpl_plygn = false)

几何输出函数

我们以POLYGON((0 0,0 1,1 1,1 0,0 0))为例,分别按二进制、EWKT、SVG格式输出,其空间查询语句和输出结果分别如下。

SELECT ST_AsBinary(
ST_GeomFromText('POLYGON((0 0,0 1,1 1,1 0,0 0))',4326)
);
SELECT ST_AsEWKT(
ST_GeomFromText('POLYGON((0 0,0 1,1 1,1 0,0 0))',4326)
);
SELECT ST_AsSVG(
ST_GeomFromText('POLYGON((0 0,0 1,1 1,1 0,0 0))',4326)
);

几何编辑数据

PostGIS提供的编辑函数种类较多,组合起来基本上能处理几何对象编辑的各类问题。在此我们对ST_Force_Collection、ST_ForceRHR、ST_Affine的函数进行简单的介绍。
使用ST_Force_Collection函数将原先的Geometry数据类型转换为GeometryCollection.


SELECT ST_AsEWKT(ST_Force_Collection(ST_GeomFromText('POLYGON Z ((0 0 2,0 5 2,5 0 2,0 0 2),(1 1 2,3 1 2,1 3 2,1 1 2))'))
) AS result;

分步解析
1. ​​ST_GeomFromText()​​
​​作用​​:将 WKT 字符串转换为 PostGIS 几何对象。
​​输入​​:‘POLYGON Z ((…))’(明确标注三维坐标)。
​​输出​​:三维多边形对象,包含外环和内环。
2. ​​ST_Force_Collection()​​
​​作用​​:将几何对象强制转换为 GEOMETRYCOLLECTION 类型。
​​输入​​:上一步生成的多边形对象。
​​输出​​:GEOMETRYCOLLECTION Z,包含原始多边形的所有环(外环+内环)。
3. ​​ST_AsEWKT()​​
​​作用​​:将几何对象转换为 EWKT(Extended Well-Known Text)格式。
​​输出​​:包含坐标和维度信息的字符串。

将上述例子中用到的多边形POLYGON((0 0 2,0 5 2,5 0 2,0 0 2),(1 1 2,3 1 2,1 3 2,1 1 2))用ST_ForceRHR函数进行强制转换,使其点坐标排列顺序复合RHR法则

SELECT ST_AsEWKT(ST_ForceRHR('POLYGON((0 0 2,0 5 2,5 0 2,0 0 2),(1 1 2,3 1 2,1 3 2,1 1 2))')
);

对三维坐标空间中的几何几何对象进行仿射变换的函数ST_Affine,它有13个函数。可简单记为ST_Affine(geom,a,b,c,d,e,f,g,h,i,xoff,yoff,zoff)
将一条线沿Z轴方向旋转180度,对应的空间查询语句如下:

SELECT ST_AsEWKT(ST_Affine(the_geom,cos(pi()), -sin(pi()), 0,sin(pi()), cos(pi()), 0,0, 0, 1,0, 0, 0)
) AS using_assine
FROM (SELECT ST_GeomFromEWKT('LINESTRING Z (1 2 3,1 4 3)') AS the_geom
) AS HAHA;

​​参数作用​​:
参数 值(计算后) 对应矩阵元素 几何意义
a cos(π) = -1 第1行第1列 X轴缩放/旋转
b -sin(π) = 0 第1行第2列 XY剪切
c 0 第1行第3列 XZ剪切
d sin(π) = 0 第2行第1列 YX剪切
e cos(π) = -1 第2行第2列 Y轴缩放/旋转
f 0 第2行第3列 YZ剪切
g 0 第3行第1列 ZX剪切
h 0 第3行第2列 ZY剪切
i 1 第3行第3列 Z轴缩放
xoff 0 X轴平移 无平移
yoff 0 Y轴平移 无平移
zoff 0 Z轴平移 无平移

运算符

空间关系 运算符 示例 含义
Intersects && Geol && Geo2 若Geol的边界框与Geo2边界框相交,则返回True
Intersects(n维) &&& Geol &&& Geo2 在n维坐标空间中,若Geol的边界框与Geo2边界框相交,则返回True
Equal ~ Geol ~ Geo2 若Geol的边界框等于Geo2的边界框,则返回True
Equal ~≈ Geol ~≈ Geo2 若Geol的边界框近似等于Geo2的边界框,则返回True
Within @ Geol @ Geo2 若Geol的边界框在Geo2边界框内,则返回True
Contains ~ Geol ~ Geo2 若Geol的边界框包含Geo2的边界框,则返回True
Left/Right &< Geol &< Geo2 若Geol的边界框在Geo2边界框左侧,或交替排列,则返回True
Below/Above &< Geol &< Geo2 若Geol的边界框在Geo2边界框下方,或交替排列,则返回True
Right/Left &> Geol &> Geo2 若Geol的边界框在Geo2边界框右侧,或交替排列,则返回True
Above/Below &> Geol
Left << Geol << Geo2 若Geol的边界框严格在Geo2边界框左侧,则返回True
Right >> Geol >> Geo2 若Geol的边界框严格在Geo2边界框右侧,则返回True
Below << Geol << Geo2 若Geol的边界框严格在Geo2边界框下方,则返回True
Above >> Geol >> Geo2 若Geol的边界框严格在Geo2边界框上方,则返回True

<-> GeoA <-> GeoB 返回GeoA和GeoB之间的2D距离
|=| GeoA|=|GeoB 返回A和B轨迹在其最近的接近点处的距离
<#> GeoA<#>GeoB 返回A和B边界框之间的2D距离
<<>> GeoA<<>>GeoB 返回A和B边界框质心之间的n-D距离
<<#>> GeoA<<#>> GeoB 返回A和B边界框之间的n-D距离

-- 创建两个临时表(tbla和tblb),并判断几何边界框是否重叠
WITH tbla AS (VALUES (1, ST_GeomFromText('LINESTRING(0 0, 2 2)')) ),  -- 临时表tblatblb AS (VALUES (2, ST_GeomFromText('LINESTRING(1 1, 3 3)')) )   -- 临时表tblb-- 主查询:判断几何体边界框是否相交
SELECT tbla.column1 AS id_a,tblb.column1 AS id_b,(tbla.column2 && tblb.column2) AS overlaps  -- 使用 && 操作符
FROM tbla, tblb;

关键解析

1. ​​临时表定义(CTE)​​

​​tbla​​:
列结构:(id, geometry)
几何数据:线 LINESTRING(0 0, 2 2)(从 (0,0) 到 (2,2))
​​tblb​​:
列结构:(id, geometry)
几何数据:线 LINESTRING(1 1, 3 3)(从 (1,1) 到 (3,3))
2. ​​&& 操作符的作用​​
​​功能​​: 检查两个几何体的边界框(MBR, Minimum Bounding Rectangle)是否相交。
​​本示例结果​​:
tbla.column2 的边界框:矩形对角点 (0,0) 和 (2,2)
tblb.column2 的边界框:矩形对角点 (1,1) 和 (3,3)
​​相交判断​​: 是 → overlaps = true
功能描述​​ ​​函数名称​​
判断几何对象A是否被B包含 ST_Contains(geometry A, geometry B)
判断几何对象A是否覆盖B ST_Covers(geometry A, geometry B)
判断几何对象A是否被B覆盖 ST_CoveredBy(geometry A, geometry B)
判断两个几何对象是否相交 ST_Intersects(geometry, geometry)
判断两个几何对象是否相等 ST_Equals(geometry, geometry)
判断两个几何对象是否相离(无交集) ST_Disjoint(geometry, geometry)
判断两个几何对象是否互相穿过 ST_Crosses(geometry, geometry)
判断两个几何对象是否重叠 ST_Overlaps(geometry, geometry)
判断两个几何对象是否接触(边界重合) ST_Touches(geometry, geometry)
获取两个几何对象的九交矩阵表示 ST_Relate(geometry, geometry)
判断是否符合给定的九交矩阵关系 ST_Relate(geometry, geometry, pattern)

判断两个多边形对象POLYGON((1 1,2 1,2 3,1 1))、POLYGON((3 0,3 2,4 0,3 0))间是否相交,空间查询语句如下:

SELECT ST_Intersects(ST_GeomFromText('POLYGON((1 1,2 1,2 3,1 1))'),
ST_GeomFromText('POLYGON((3 0,3 2,4 0,3 0))')
);

测量函数

求两点(0 0)和(1 1)间的方位角,空间查询语句如下:

SELECT ST_Azimuth(
ST_GeomFromText('POINT(0 0)'),ST_GeomFromText('POINT(1 1)'));

计算两点在GRS_1980地球椭球体下的曲面距离,空间查询语句如下:

SELECT st_distance_spheroid(
st_centroid(the_geom),st_geomfromtext('POINT(-118 38)'),
'SPHEROID["GRS_1980",6378137,298.257222101]')FROM landuse;

其中,SPHEROID[“GRS_1980”,6378137,298.257222101]地球参数

几何处理函数

从这边开始,只提供例子,具体函数可以去https://postgis.net/docs/查看
获取土地利用数据表landuse中ID号为12的几何对象的质心。空间查询语句如下:

SELECT ST_Centroid(the_geom)
FROM  landuse
WHERE landuse_id=12

为土地利用数据表landuse中ID号为12的几何对象建立距离为3的缓冲区。空间查询语句如下:

SELECT ST_Buffer(the_geom,3)
FROM landuse
WHERE landuse_id=12

线性参考

下面举例说明ST_Line_Interpolate_Point函数的使用方法。该函数带有两个参数,他的第一个参数必须是一个折线类型的数据;第二个参数是0~1间的值,它表示某点在整个折现上所处的位置
已知点在30%处,语句如下:

SELECT ST_AsEWKT(ST_Line_Interpolate_Point(the_line,0.30))
from
(select st_geomfromewkt('linestring(25 30,80 100,150 210)')as the_line)As HOHO;

其它函数

估计土地利用数据表landuse的边界范围,以及the_geom字段占用的内存大小的空间查询语句分别为

SELECT ST_Estimated_Extent('public','landuse','the_geom')
SELECT SUM(ST_Mem_Size(the_geom))FROM landuse

通过以上几个小结的阐述,不难看出,开源数据库PostGIS针对矢量数据提供了种类繁多、功能强大的操作函数。他们能满足GIS应用对空间数据库管理系统的基本要求。

相关文章:

  • 生成式 AI 的工作原理
  • 数学实验(Matlab语言环境和线性代数实验)
  • PyTorch_张量转换为numpy数组
  • 用可视化学习逆置法
  • 基于LangChain 实现 Advanced RAG-后检索优化(上)-Reranker
  • 如何提升个人的思维能力?
  • 人工智能:如何快速筛选出excel中某列存在跳号的单元格位置?
  • C++ 中的继承
  • scikit-learn在监督学习算法的应用
  • WEB前端小练习——记事本
  • 多端定制系统开发:打造高效全平台覆盖的APP解决方案
  • 004 树与二叉树:从原理到实战
  • 「Mac畅玩AIGC与多模态16」开发篇12 - 多节点串联与输出合并的工作流示例
  • C++调试(叁):编译qBreakpad并使用其生成Dump文件
  • 解决Maven项目中报错“java不支持版本6即更高的版本 7”
  • 代码随想录算法训练营Day43
  • 单片机嵌入式CAN库
  • Linux第20节 --- inode和文件系统
  • 【2025软考高级架构师】——未来信息综合技术(11)
  • C++笔记-多态(包含虚函数,纯虚函数和虚函数表等)
  • 长三角铁路今日预计发送旅客398万人次,客流持续保持高位运行
  • 人民日报今日谈:以青春之我,赴时代之约
  • 五大白酒去年净利超1500亿元:贵州茅台862亿领跑,洋河营收净利齐降
  • 魔都眼|买买买,老铺黄金新店开业被挤爆:有人排队5小时
  • 中国金茂向滨江集团提供11.21亿元诚意金借款,拟合作开发3月获取的地块
  • 购车补贴、“谷子”消费、特色产品,这些活动亮相五五购物节