2024年9月26日: PostgreSQL 17 发布!
支持的版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:开发版
不支持的版本:11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1

9.11. 几何函数和运算符 #

几何类型pointboxlseglinepathpolygoncircle有一套丰富的原生支持函数和运算符,如表 9.36表 9.37表 9.38所示。

表 9.36. 几何运算符

运算符

描述

示例

geometric_type + pointgeometric_type

将第二个point的坐标添加到第一个参数的每个点的坐标,从而执行平移。适用于pointboxpathcircle

box '(1,1),(0,0)' + point '(2,0)'(3,1),(2,0)

path + pathpath

连接两个开放路径(如果任一路径是闭合的,则返回NULL)。

path '[(0,0),(1,1)]' + path '[(2,2),(3,3),(4,4)]'[(0,0),(1,1),(2,2),(3,3),(4,4)]

geometric_type - pointgeometric_type

从第一个参数的每个点的坐标中减去第二个point的坐标,从而执行平移。适用于pointboxpathcircle

box '(1,1),(0,0)' - point '(2,0)'(-1,1),(-2,0)

geometric_type * pointgeometric_type

将第一个参数的每个点乘以第二个point(将点视为由实部和虚部表示的复数,并执行标准复数乘法)。如果将第二个point解释为向量,则这等效于按向量的长度缩放对象的大小和与原点的距离,并将其围绕原点逆时针旋转向量与x轴的夹角。适用于pointbox[a] pathcircle

path '((0,0),(1,0),(1,1))' * point '(3.0,0)'((0,0),(3,0),(3,3))

path '((0,0),(1,0),(1,1))' * point(cosd(45), sind(45))((0,0),​(0.7071067811865475,0.7071067811865475),​(0,1.414213562373095))

geometric_type / pointgeometric_type

将第一个参数的每个点除以第二个point(将点视为由实部和虚部表示的复数,并执行标准复数除法)。如果将第二个point解释为向量,则这等效于按向量的长度缩小对象的大小和与原点的距离,并将其围绕原点顺时针旋转向量与x轴的夹角。适用于pointbox[a] pathcircle

path '((0,0),(1,0),(1,1))' / point '(2.0,0)'((0,0),(0.5,0),(0.5,0.5))

path '((0,0),(1,0),(1,1))' / point(cosd(45), sind(45))((0,0),​(0.7071067811865476,-0.7071067811865476),​(1.4142135623730951,0))

@-@ geometric_typedouble precision

计算总长度。适用于lsegpath

@-@ path '[(0,0),(1,0),(1,1)]'2

@@ geometric_typepoint

计算中心点。适用于boxlsegpolygoncircle

@@ box '(2,2),(0,0)'(1,1)

# geometric_typeinteger

返回点的数量。适用于pathpolygon

# path '((1,0),(0,1),(-1,0))'3

geometric_type # geometric_typepoint

计算交点,如果不存在则返回NULL。适用于lsegline

lseg '[(0,0),(1,1)]' # lseg '[(1,0),(0,1)]'(0.5,0.5)

box # boxbox

计算两个box的交集,如果不存在则返回NULL。

box '(2,2),(-1,-1)' # box '(1,1),(-2,-2)'(1,1),(-1,-1)

geometric_type ## geometric_typepoint

计算第二个对象上最接近第一个对象的点。适用于以下类型对:(point, box)、(point, lseg)、(point, line)、(lseg, box)、(lseg, lseg)、(line, lseg)。

point '(0,0)' ## lseg '[(2,0),(0,2)]'(1,1)

geometric_type <-> geometric_typedouble precision

计算对象之间的距离。适用于所有七种几何类型,适用于point与其他几何类型的所有组合,以及以下其他类型对:(box, lseg)、(lseg, line)、(polygon, circle)(以及交换律情况)。

circle '<(0,0),1>' <-> circle '<(5,0),1>'3

geometric_type @> geometric_typeboolean

第一个对象是否包含第二个对象?适用于以下类型对:(box, point)、(box, box)、(path, point)、(polygon, point)、(polygon, polygon)、(circle, point)、(circle, circle)。

circle '<(0,0),2>' @> point '(1,1)'t

geometric_type <@ geometric_typeboolean

第一个对象是否包含在第二个对象中或在第二个对象上?适用于以下类型对:(point, box)、(point, lseg)、(point, line)、(point, path)、(point, polygon)、(point, circle)、(box, box)、(lseg, box)、(lseg, line)、(polygon, polygon)、(circle, circle)。

point '(1,1)' <@ circle '<(0,0),2>'t

geometric_type && geometric_typeboolean

这些对象是否重叠?(一个公共点使这成为真)。适用于boxpolygoncircle

box '(1,1),(0,0)' && box '(2,2),(0,0)'t

几何类型 << 几何类型布尔型

第一个对象是否严格位于第二个对象的左侧?适用于 多边形

circle '<(0,0),1>' << circle '<(5,0),1>'t

几何类型 >> 几何类型布尔型

第一个对象是否严格位于第二个对象的右侧?适用于 多边形

circle '<(5,0),1>' >> circle '<(0,0),1>'t

几何类型 &< 几何类型布尔型

第一个对象是否不延伸到第二个对象的右侧?适用于 多边形

box '(1,1),(0,0)' &< box '(2,2),(0,0)'t

几何类型 &> 几何类型布尔型

第一个对象是否不延伸到第二个对象的左侧?适用于 多边形

box '(3,3),(0,0)' &> box '(2,2),(0,0)'t

几何类型 <<| 几何类型布尔型

第一个对象是否严格位于第二个对象的下方?适用于 多边形

box '(3,3),(0,0)' <<| box '(5,5),(3,4)'t

几何类型 |>> 几何类型布尔型

第一个对象是否严格位于第二个对象的上面?适用于 多边形

box '(5,5),(3,4)' |>> box '(3,3),(0,0)'t

几何类型 &<| 几何类型布尔型

第一个对象是否不延伸到第二个对象的上面?适用于 多边形

box '(1,1),(0,0)' &<| box '(2,2),(0,0)'t

几何类型 |&> 几何类型布尔型

第一个对象是否不延伸到第二个对象的下面?适用于 多边形

box '(3,3),(0,0)' |&> box '(2,2),(0,0)'t

<^ 布尔型

第一个对象是否位于第二个对象的下方(允许边缘接触)?

box '((1,1),(0,0))' <^ box '((2,2),(1,1))'t

>^ 布尔型

第一个对象是否位于第二个对象的上面(允许边缘接触)?

box '((2,2),(1,1))' >^ box '((1,1),(0,0))'t

几何类型 ?# 几何类型布尔型

这些对象是否相交?适用于以下类型的组合:(, )、(线段, )、(线段, 线段)、(线段, 线)、(线, )、(线, 线)、(路径, 路径)。

lseg '[(-1,0),(1,0)]' ?# box '(2,2),(-2,-2)'t

?- 线布尔型

?- 线段布尔型

线是否水平?

?- lseg '[(-1,0),(1,0)]'t

?- 布尔型

点是否水平对齐(即具有相同的 y 坐标)?

point '(1,0)' ?- point '(0,0)'t

?| 线布尔型

?| 线段布尔型

线是否垂直?

?| lseg '[(-1,0),(1,0)]'f

?| 布尔型

点是否垂直对齐(即具有相同的 x 坐标)?

point '(0,1)' ?| point '(0,0)'t

线 ?-| 线布尔型

线段 ?-| 线段布尔型

线是否垂直?

lseg '[(0,0),(0,1)]' ?-| lseg '[(0,0),(1,0)]'t

线 ?|| 线布尔型

线段 ?|| 线段布尔型

线是否平行?

lseg '[(-1,0),(1,0)]' ?|| lseg '[(-1,2),(1,2)]'t

几何类型 ~= 几何类型布尔型

这些对象是否相同?适用于 多边形

polygon '((0,0),(1,1))' ~= polygon '((1,1),(0,0))'t

[a] 使用这些运算符“旋转”盒只会移动其角点:盒仍然被认为具有平行于轴的边。因此,盒的大小不会被保留,因为真正的旋转会这样做。


注意

请注意,“相同”运算符 ~= 表示 多边形 类型的通常相等概念。一些几何类型也具有 = 运算符,但 = 仅比较相等的面积。在这些类型中,其他标量比较运算符(<= 等)在可用时也比较面积。

注意

PostgreSQL 14 之前,点严格位于下方/上方的比较运算符 <<| |>> 分别称为 <^>^。这些名称仍然可用,但已弃用,最终将被删除。

表 9.37. 几何函数

函数

描述

示例

area ( 几何类型 ) → 双精度浮点数

计算面积。适用于 路径路径 输入必须是闭合的,否则返回 NULL。此外,如果 路径 自相交,则结果可能没有意义。

area(box '(2,2),(0,0)')4

center ( 几何类型 ) →

计算中心点。适用于

center(box '(1,2),(0,0)')(0.5,1)

diagonal ( ) → 线段

将盒的对角线提取为线段(与 lseg(box) 相同)。

diagonal(box '(1,2),(0,0)')[(1,2),(0,0)]

diameter ( ) → 双精度浮点数

计算圆的直径。

diameter(circle '<(0,0),2>')4

height ( ) → 双精度浮点数

计算盒的垂直大小。

height(box '(1,2),(0,0)')2

isclosed ( 路径 ) → 布尔型

路径是否闭合?

isclosed(path '((0,0),(1,1),(2,0))')t

isopen ( 路径 ) → 布尔型

路径是否开放?

isopen(path '[(0,0),(1,1),(2,0)]')t

length ( 几何类型 ) → 双精度浮点数

计算总长度。适用于lsegpath

length(path '((-1,0),(1,0))')4

npoints ( 几何类型 ) → 整数

返回点的数量。适用于pathpolygon

npoints(path '[(0,0),(1,1),(2,0)]')3

pclose ( 路径 ) → 路径

将路径转换为闭合形式。

pclose(path '[(0,0),(1,1),(2,0)]')((0,0),(1,1),(2,0))

popen ( 路径 ) → 路径

将路径转换为开放形式。

popen(path '((0,0),(1,1),(2,0))')[(0,0),(1,1),(2,0)]

radius ( ) → 双精度浮点数

计算圆的半径。

radius(circle '<(0,0),2>')2

slope ( , ) → 双精度浮点数

计算穿过这两个点的线的斜率。

slope(point '(0,0)', point '(2,1)')0.5

width ( ) → 双精度浮点数

计算盒的水平大小。

width(box '(1,2),(0,0)')1


表 9.38. 几何类型转换函数

函数

描述

示例

box ( ) →

计算内接于圆的盒。

box(circle '<(0,0),2>')(1.414213562373095,1.414213562373095),​(-1.414213562373095,-1.414213562373095)

box ( ) →

将点转换为空盒。

box(point '(1,0)')(1,0),(1,0)

box ( point, point ) → box

将任意两个角点转换为box。

box(point '(0,1)', point '(1,0)')(1,1),(0,0)

box ( polygon ) → box

计算多边形的边界框。

box(polygon '((0,0),(1,1),(2,0))')(2,1),(0,0)

bound_box ( box, box ) → box

计算两个box的边界框。

bound_box(box '(1,1),(0,0)', box '(4,4),(3,3)')(4,4),(0,0)

circle ( box ) → circle

计算包含box的最小圆。

circle(box '(1,1),(0,0)')<(0.5,0.5),0.7071067811865476>

circle ( point, double precision ) → circle

根据圆心和半径构造圆。

circle(point '(0,0)', 2.0)<(0,0),2>

circle ( polygon ) → circle

将多边形转换为圆。圆的中心是多边形各点位置的平均值,半径是多边形各点到该中心的平均距离。

circle(polygon '((0,0),(1,3),(2,0))')<(1,1),1.6094757082487299>

line ( point, point ) → line

将两个点转换为穿过它们的直线。

line(point '(-1,0)', point '(1,0)'){0,-1,0}

lseg ( box ) → lseg

提取box的对角线作为线段。

lseg(box '(1,0),(-1,0)')[(1,0),(-1,0)]

lseg ( point, point ) → lseg

根据两个端点构造线段。

lseg(point '(-1,0)', point '(1,0)')[(-1,0),(1,0)]

path ( polygon ) → path

将多边形转换为具有相同点列表的闭合路径。

path(polygon '((0,0),(1,1),(2,0))')((0,0),(1,1),(2,0))

point ( double precision, double precision ) → point

根据坐标构造点。

point(23.4, -44.5)(23.4,-44.5)

point ( box ) → point

计算box的中心。

point(box '(1,0),(-1,0)')(0,0)

point ( circle ) → point

计算圆的中心。

point(circle '<(0,0),2>')(0,0)

point ( lseg ) → point

计算线段的中心。

point(lseg '[(-1,0),(1,0)]')(0,0)

point ( polygon ) → point

计算多边形的中心(多边形各点位置的平均值)。

point(polygon '((0,0),(1,1),(2,0))')(1,0.3333333333333333)

polygon ( box ) → polygon

将box转换为一个4点多边形。

polygon(box '(1,1),(0,0)')((0,0),(0,1),(1,1),(1,0))

polygon ( circle ) → polygon

将圆转换为一个12点多边形。

polygon(circle '<(0,0),2>')((-2,0),​(-1.7320508075688774,0.9999999999999999),​(-1.0000000000000002,1.7320508075688772),​(-1.2246063538223773e-16,2),​(0.9999999999999996,1.7320508075688774),​(1.732050807568877,1.0000000000000007),​(2,2.4492127076447545e-16),​(1.7320508075688776,-0.9999999999999994),​(1.0000000000000009,-1.7320508075688767),​(3.673819061467132e-16,-2),​(-0.9999999999999987,-1.732050807568878),​(-1.7320508075688767,-1.0000000000000009))

polygon ( integer, circle ) → polygon

将圆转换为一个n点多边形。

polygon(4, circle '<(3,0),1>')((2,0),​(3,1),​(4,1.2246063538223773e-16),​(3,-1))

polygon ( path ) → polygon

将闭合路径转换为具有相同点列表的多边形。

polygon(path '((0,0),(1,1),(2,0))')((0,0),(1,1),(2,0))


可以像访问索引为0和1的数组一样访问point的两个组成部分。例如,如果t.p是一个point列,则SELECT p[0] FROM t检索X坐标,而UPDATE t SET p[1] = ...更改Y坐标。同样,类型为boxlseg的值可以被视为两个point值的数组。

提交更正

如果您在文档中发现任何不正确的内容,与您对特定功能的体验不符,或者需要进一步说明,请使用此表单报告文档问题。