PostgreSQL 中文参考文档
🌐 英文原版 官方 ↗

9.11. 几何函数与操作符 #

几何类型 point、 box、 lseg、 line、 path、 polygon 和 circle 拥有大量的原生支持函数和操作符, 展示在 Table 9.36、 Table 9.37 和 Table 9.38 中。

Table 9.36. 几何操作符

操作符

说明

示例

geometric_type + point → geometric_type

把第二个 point 的坐标加到第一个参数的每个点的坐标上, 从而执行平移。 可用于 point、 box、 path、 circle。

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

path + path → path

连接两条开放路径 (如果任一路径是封闭的, 则返回 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 - point → geometric_type

从第一个参数的每个点的坐标中减去第二个 point 的坐标, 从而执行平移。 可用于 point、 box、 path、 circle。

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

geometric_type * point → geometric_type

把第一个参数的每个点乘以第二个 point (把点视为由实部和虚部表示的复数, 并执行标准的复数乘法)。 如果把第二个 point 解释为一个向量, 这等同于按向量的长度缩放对象的尺寸以及它到原点的距离, 并按向量相对 x 轴的角度把它绕原点逆时针旋转。 可用于 point、 box、[a] path, circle.

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 / point → geometric_type

把第一个参数的每个点除以第二个 point (把点视为由实部和虚部表示的复数, 并执行标准的复数除法)。 如果把第二个 point 解释为一个向量, 这等同于按向量的长度把对象的尺寸以及它到原点的距离缩小, 并按向量相对 x 轴的角度把它绕原点顺时针旋转。 可用于 point、 box、[a] path、 circle。

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_type → double precision

计算总长度。 可用于 lseg、 path。

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

@@ geometric_type → point

计算中心点。 可用于 box、 lseg、 polygon、 circle。

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

# geometric_type → integer

返回点的数量。 可用于 path、 polygon。

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

geometric_type # geometric_type → point

计算交点, 如果没有则返回 NULL。 可用于 lseg、 line。

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

box # box → box

计算两个盒子的交集, 如果没有则返回 NULL。

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

geometric_type ## geometric_type → point

计算第二个对象上距第一个对象最近的点。 可用于以下这些类型对: (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_type → double precision

计算对象之间的距离。 可用于全部七种几何类型、 point 与另一种几何类型的所有组合, 以及以下这些额外的类型对: (box, lseg)、 (lseg, line)、 (polygon, circle) (以及交换后的情形)。

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

geometric_type @> geometric_type → boolean

第一个对象是否包含第二个? 可用于以下这些类型对: (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_type → boolean

第一个对象是否被包含在第二个之内或之上? 可用于以下这些类型对: (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_type → boolean

这些对象是否重叠? (有一个公共点就为真。) 可用于 box、 polygon、 circle。

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

geometric_type << geometric_type → boolean

第一个对象是否严格位于第二个的左边? 可用于 point、 box、 polygon、 circle。

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

geometric_type >> geometric_type → boolean

第一个对象是否严格位于第二个的右边? 可用于 point、 box、 polygon、 circle。

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

geometric_type &< geometric_type → boolean

第一个对象是否没有延伸到第二个对象的右边? 可用于 box、 polygon、 circle。

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

geometric_type &> geometric_type → boolean

第一个对象是否没有延伸到第二个对象的左边? 可用于 box、 polygon、 circle。

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

geometric_type <<| geometric_type → boolean

第一个对象是否严格位于第二个的下方? 可用于 point、 box、 polygon、 circle。

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

geometric_type |>> geometric_type → boolean

第一个对象是否严格位于第二个的上方? 可用于 point、 box、 polygon、 circle。

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

geometric_type &<| geometric_type → boolean

第一个对象是否没有延伸到第二个的上方? 可用于 box、 polygon、 circle。

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

geometric_type |&> geometric_type → boolean

第一个对象是否没有延伸到第二个的下方? 可用于 box、 polygon、 circle。

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

box <^ box → boolean

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

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

box >^ box → boolean

第一个对象是否位于第二个的上方 (允许边界相触)?

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

geometric_type ?# geometric_type → boolean

这些对象是否相交? 可用于以下这些类型对: (box, box)、 (lseg, box)、 (lseg, lseg)、 (lseg, line)、 (line, box)、 (line, line)、 (path, path)。

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

?- line → boolean

?- lseg → boolean

该直线是否水平?

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

point ?- point → boolean

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

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

?| line → boolean

?| lseg → boolean

该直线是否竖直?

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

point ?| point → boolean

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

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

line ?-| line → boolean

lseg ?-| lseg → boolean

两条直线是否垂直?

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

line ?|| line → boolean

lseg ?|| lseg → boolean

两条直线是否平行?

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

geometric_type ~= geometric_type → boolean

这些对象是否相同? 可用于 point、 box、 polygon、 circle。

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

[a] “旋转”一个 盒子只会移动它的角点: 盒子仍然被视为具有平行于坐标轴的边。 因此盒子的尺寸不会被保留, 而真正的旋转会保留它。


Caution

注意, “相同”操作符 ~= 代表 point、 box、 polygon 和 circle 类型惯常的相等概念。 某些几何类型还有一个 = 操作符, 但 = 只比较 面积是否相等。 在这些类型可用的其他标量比较操作符 (<= 等)中, 比较的同样是面积。

Note

在 PostgreSQL 14 之前, 点严格位于下方/上方的比较操作符 point <<| point 和 point |>> point 分别被叫做 <^ 和 >^。 这些名字仍然可用, 但已被弃用, 并且最终会被移除。

Table 9.37. 几何函数

函数

说明

示例

area ( geometric_type ) → double precision

计算面积。 可用于 box、 path、 circle。 path 输入必须是封闭的, 否则返回 NULL。 此外, 如果该 path 是自相交的, 结果可能是没有意义的。

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

center ( geometric_type ) → point

计算中心点。 可用于 box、 circle。

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

diagonal ( box ) → lseg

把盒子的对角线提取为一条线段 (与 lseg(box) 相同)。

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

diameter ( circle ) → double precision

计算圆的直径。

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

height ( box ) → double precision

计算盒子的垂直尺寸。

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

isclosed ( path ) → boolean

该路径是否闭合?

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

isopen ( path ) → boolean

该路径是否开放?

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

length ( geometric_type ) → double precision

计算总长度。 可用于 lseg、 path。

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

npoints ( geometric_type ) → integer

返回点的数量。 可用于 path、 polygon。

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

pclose ( path ) → path

把路径转换为封闭形式。

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

popen ( path ) → path

把路径转换为开放形式。

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

radius ( circle ) → double precision

计算圆的半径。

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

slope ( point, point ) → double precision

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

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

width ( box ) → double precision

计算盒子的水平尺寸。

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


Table 9.38. 几何类型转换函数

函数

说明

示例

box ( circle ) → box

计算内接于圆的盒子。

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

box ( point ) → box

把点转换为空盒子。

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

box ( point, point ) → 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

计算两个盒子的边界框。

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

circle ( box ) → circle

计算包围盒子的最小圆。

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

把盒子的对角线提取为一条线段。

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

计算盒子的中心。

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

把盒子转换为一个 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 坐标。 以同样的方式, 一个 box 或 lseg 类型的值可以被视为由两个 point 值组成的数组。