文字
分享

9.11. 几何函数和操作符

有许多内置函数和操作符支持几何类型pointboxlseglinepathpolygon, andcircle, 在Table 9-30, Table 9-31和Table 9-32中展示。

Caution

请注意"相同"same as""操作符~=表示pointboxpolygoncircle类型在一般意义上相同。 这些类型有些还有一个=操作符,不过它只是比较相同的面积。 其它的标量比较操作符(<=等)也是为这些类型比较面积。

Table 9-30. 几何操作符

操作符 描述 示例
+ 平移 box '((0,0),(1,1))' + point '(2.0,0)'
- 平移 box '((0,0),(1,1))' - point '(2.0,0)'
* 缩放/旋转 box '((0,0),(1,1))' * point '(2.0,0)'
/ 缩放/旋转 box '((0,0),(2,2))' / point '(2.0,0)'
# 交点或交面 '((1,-1),(-1,1))' # '((1,1),(-1,-1))'
# 路径或多边形顶点数 # '((1,0),(0,1),(-1,0))'
@-@ 长度或周长 @-@ path '((0,0),(1,0))'
@@ 中心 @@ circle '((0,0),10)'
## 离第一个操作数和第二个操作数的最近点 point '(0,0)' ## lseg '((2,0),(0,2))'
<-> 间距 circle '((0,0),1)' <-> circle '((5,0),1)'
&& 重叠?(有一个共同点为真。) box '((0,0),(1,1))' && box '((0,0),(2,2))'
<< 严格在左? circle '((0,0),1)' << circle '((5,0),1)'
>> 严格在右? circle '((5,0),1)' >> circle '((0,0),1)'
&< 没有延展到右边? box '((0,0),(1,1))' &< box '((0,0),(2,2))'
&> 没有延展到左边? box '((0,0),(3,3))' &> box '((0,0),(2,2))'
<<| 严格在下? box '((0,0),(3,3))' <<| box '((3,4),(5,5))'
|>> 严格在上? box '((3,4),(5,5))' |>> box '((0,0),(3,3))'
&<| 没有延展到上面? box '((0,0),(1,1))' &<| box '((0,0),(2,2))'
|&> 没有延展到下面? box '((0,0),(3,3))' |&> box '((0,0),(2,2))'
<^ 在下面(允许接触)? circle '((0,0),1)' <^ circle '((0,5),1)'
>^ 在上面(允许接触)? circle '((0,5),1)' >^ circle '((0,0),1)'
?# 相交? lseg '((-1,0),(1,0))' ?# box '((-2,-2),(2,2))'
?- 水平? ?- lseg '((-1,0),(1,0))'
?- 水平对齐? point '(1,0)' ?- point '(0,0)'
?| 竖直? ?| lseg '((-1,0),(1,0))'
?| 竖直对齐? point '(0,1)' ?| point '(0,0)'
?-| 垂直? lseg '((0,0),(0,1))' ?-| lseg '((0,0),(1,0))'
?|| 平行? lseg '((-1,0),(1,0))' ?|| lseg '((-1,2),(1,2))'
@> 包含? circle '((0,0),2)' @> point '(1,1)'
<@ 包含或在...上? point '(1,1)' <@ circle '((0,0),2)'
~= 与...相同? polygon '((0,0),(1,1))' ~= polygon '((1,1),(0,0))'

Note: PostgreSQL8.2 之前,包含操作符@><@被分别称为~@。 我们反对使用这两个旧名字(当前仍然可以使用),它们将来会被废除。

Table 9-31. 几何函数

函数 返回类型 描述 示例
area(object) double precision 面积 area(box '((0,0),(1,1))')
center(object) point 中心 center(box '((0,0),(1,2))')
diameter(circle) double precision 圆直径 diameter(circle '((0,0),2.0)')
height(box) double precision 矩形的竖直高度 height(box '((0,0),(1,1))')
isclosed(path) boolean 闭合路径? isclosed(path '((0,0),(1,1),(2,0))')
isopen(path) boolean 开路径? isopen(path '[(0,0),(1,1),(2,0)]')
length(object) double precision 长度 length(path '((-1,0),(1,0))')
npoints(path) int 点数 npoints(path '[(0,0),(1,1),(2,0)]')
npoints(polygon) int 点数 npoints(polygon '((1,1),(0,0))')
pclose(path) path 将路径转换为闭合 pclose(path '[(0,0),(1,1),(2,0)]')
popen(path) path 把路径转换为开放 popen(path '((0,0),(1,1),(2,0))')
radius(circle) double precision 圆半径 radius(circle '((0,0),2.0)')
width(box) double precision 矩形的水平宽度 width(box '((0,0),(1,1))')

Table 9-32. 几何类型转换函数

函数 返回类型 描述 示例
box(circle) box 将圆转换成矩形 box(circle '((0,0),2.0)')
box(pointpoint) box 将点转换成矩形 box(point '(0,0)', point '(1,1)')
box(polygon) box 将多边形转换成矩形 box(polygon '((0,0),(1,1),(2,0))')
circle(box) circle 将矩形转换成圆 circle(box '((0,0),(1,1))')
circle(pointdouble precision) circle 将圆心和半径转换成圆 circle(point '(0,0)', 2.0)
circle(polygon) circle 将多边形转换成圆 circle(polygon '((0,0),(1,1),(2,0))')
lseg(box) lseg 将矩形对角线转化成线段 lseg(box '((-1,0),(1,0))')
lseg(pointpoint) lseg 将点转换成线段 lseg(point '(-1,0)', point '(1,0)')
path(polygon) point 将多边形转换成路径 path(polygon '((0,0),(1,1),(2,0))')
point(double precisiondouble precision) point 构建一个点 point(23.4, -44.5)
point(box) point 矩形的中心 point(box '((-1,0),(1,0))')
point(circle) point 圆心 point(circle '((0,0),2.0)')
point(lseg) point 线段的中心 point(lseg '((-1,0),(1,0))')
point(polygon) point 多边形的中心 point(polygon '((0,0),(1,1),(2,0))')
polygon(box) polygon 将矩形转换成4个点多边形 polygon(box '((0,0),(1,1))')
polygon(circle) polygon 将圆转换成 12个点多边形 polygon(circle '((0,0),2.0)')
polygon(nptscircle) polygon 将圆转换成npts个点的多边形 polygon(12, circle '((0,0),2.0)')
polygon(path) polygon 将路径转换成多边形 polygon(path '((0,0),(1,1),(2,0))')

我们可以把一个 point 的两个组成部分当作索引分别为 0 和 1 的 数组元素进行访问。比如,如果t.p是一个point字段, 那么 SELECT p[0] FROM t 检索 X 座标而 UPDATE t SET p[1] = ... 改变 Y 座标。 同样,boxlseg的值可以当作两个point的数组值看待

area函数可以用于boxcirclepath类型。 area函数操作path数据类型的时候, 只有在path的点没有交叉的情况下才可用。 而下面的视觉等效path'((0,0),(0,1),(1,1),(1,2),(2,2),(2,1),(1,1),(1,0),(0,0))'::PATH 就可以。如果交叉和不交叉的path概念让你胡涂,那么把上面两个path都画在纸上,你就明白了。