Postgresql 中文操作指南

9.11. Geometric Functions and Operators #

几何类型_point_、boxlseglinepath、_polygon_和_circle_有一组原生支持函数和运算符,显示在 Table 9.36Table 9.37Table 9.38中。

Table 9.36. Geometric Operators

Operator

Description

Example(s)

geometric_type + pointgeometric_type 将另一个 point 的坐标加到第一个参数的各个点,从而进行转换。可用于 pointboxpathcirclebox '(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 的坐标,从而执行平移。可用于 pointboxpathcirclebox '(1,1),(0,0)' - point '(2,0)'(-1,1),(-2,0)

geometric_type * pointgeometric_type 将第一个参数的每个点乘以第二个 point (将点视为由实部和虚部表示的复数,并且执行标准复数乘法)。如果将第二个 point 解释为一个向量,则这相当于将该对象的尺寸和与原点的距离按向量的长度按比例缩放,并按向量与 x 轴的角度将其逆时针旋转。可用于 pointbox 、 [id="a",role="bare"]#ftn.FUNCTIONS-GEOMETRY-ROTATION-FN [id="a"] pathcirclepath '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 、 [id="a",role="bare"]functions-geometry.html#ftn.FUNCTIONS-GEOMETRY-ROTATION-FN [id="a"] pathcirclepath '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。可用于 lseglinelseg '[(0,0),(1,1)]' # lseg '[(1,0),(0,1)]'(0.5,0.5)

box # boxbox 计算两个框的交集,如果不存在则为 NULL。 box '(2,2),(-1,-1)' # box '(1,1),(-2,-2)'(1,1),(-1,-1)

geometric_type # geometric_typepoint 计算最接近第二个对象上的第一个对象的点。可用于以下类型的对:( pointbox )、( pointlseg )、( pointline )、( lsegbox )、( lseglseg )、( linelseg )。 point '(0,0)' # lseg '[(2,0),(0,2)]'(1,1)

geometric_type <→ geometric_typedouble precision 计算对象之间的距离。所有七种几何类型,对于 point 与另一种几何类型的任何组合,并且对于以下额外的类型对:( boxlseg )、( lsegline )、( polygoncircle )(和换向器的情况)。 circle '<(0,0),1>' <→ circle '<(5,0),1>'3

geometric_type @> geometric_typeboolean 第一个对象包含第二个对象吗? 可用于以下类型的对:( boxpoint )、( boxbox )、( pathpoint )、( polygonpoint )、( polygonpolygon )、( circlepoint )、( circlecircle )。 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 这些对象是否重叠?(有一个共同点则为真)适用于 boxpolygoncirclebox '(1,1),(0,0)' && box '(2,2),(0,0)'t

geometric_type << geometric_typeboolean 第一个对象是否严格位于第二个对象的左边?适用于 pointboxpolygoncirclecircle '<(0,0),1>' << circle '<(5,0),1>'t

geometric_type >> geometric_typeboolean 第一个对象在第二个对象右侧吗?适用于 pointboxpolygoncirclecircle '<(5,0),1>' >> circle '<(0,0),1>'t

geometric_type &< geometric_typeboolean 第一个对象延伸不到第二个对象的右侧?适用于 boxpolygoncirclebox '(1,1),(0,0)' &< box '(2,2),(0,0)'t

geometric_type &> geometric_typeboolean 第一个对象延伸不到第二个对象的左侧?适用于 boxpolygoncirclebox '(3,3),(0,0)' &> box '(2,2),(0,0)'t

geometric_type _<<

_ geometric_typeboolean 第一个对象在第二个对象的正下方吗?适用于 pointboxpolygoncircle 。_box '(3,3),(0,0)' <<

box '(5,5),(3,4)'_ → t

geometric_type _

>>_ geometric_typeboolean 第一个对象在第二个对象的正上方吗?适用于 pointboxpolygoncircle 。_box '(5,5),(3,4)'

>> square_box '(3,3),(0,0)'_ → t

geometric_type _&<

_ geometric_typeboolean 第一个对象延伸不到第二个对象的顶部?适用于 boxpolygoncircle 。_box '(1,1),(0,0)' &<

box '(2,2),(0,0)'_ → t

geometric_type _

&>_ geometric_typeboolean 第一个对象延伸不到第二个对象的底部?适用于 boxpolygoncircle 。_box '(3,3),(0,0)'

&> square_box '(2,2),(0,0)'_ → t

box &lt;^ boxboolean 第一个对象在第二个对象的下方(允许边缘相切)? box '1,1),(0,0' &lt;^ box '2,2),(1,1't

box &gt;^ boxboolean 第一个对象在第二个对象的上方(允许边缘相切)? box '2,2),(1,1' &gt;^ box '1,1),(0,0't

geometric_type ? geometric_typeboolean 这些对象重叠吗?适用于以下类型对:( boxbox ), ( lsegbox ), ( lseglseg ), ( lsegline ), ( linebox ), ( lineline ), ( pathpath )。 lseg '[(-1,0),(1,0)]' ? box '(2,2),(-2,-2)'t

?- lineboolean ?- lsegboolean 线段水平吗? ?- lseg '[(-1,0),(1,0)]'t

point ?- pointboolean 点是否水平对齐(即 y 坐标相同)? point '(1,0)' ?- point '(0,0)'t

_?

_ lineboolean

_?

_ lsegboolean 线段垂直吗?_?

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

point _?

_ pointboolean 点是否垂直对齐(即 x 坐标相同)?_point '(0,1)' ?

point '(0,0)'_ → t

line _?-

_ lineboolean lseg _?-

_ lsegboolean 线段垂直吗?_lseg '[(0,0),(0,1)]' ?-

lseg '[(0,0),(1,0)]'_ → t

line _?

_ lineboolean lseg _?

_ lsegboolean 线段平行吗?_lseg '[(-1,0),(1,0)]' ?

lseg '[(-1,2),(1,2)]'_ → t

geometric_type ~= geometric_typeboolean 这些对象相同吗?适用于 pointboxpolygoncirclepolygon '0,0),(1,1' ~= polygon '1,1),(0,0't

[id="a",role="bare"]#FUNCTIONS-GEOMETRY-ROTATION-FN [id="a"] 对于这些运算符来说,“旋转”盒子只会移动它的角点,盒子仍被认为具有平行于轴的边的属性。因此,盒子的尺寸不会被保存,而真正的旋转操作会做到这一点。

[id="a",role="bare"]#FUNCTIONS-GEOMETRY-ROTATION-FN [id="a"] 对于这些运算符来说,“旋转”盒子只会移动它的角点,盒子仍被认为具有平行于轴的边的属性。因此,盒子的尺寸不会被保存,而真正的旋转操作会做到这一点。

Caution

请注意,“与相同”算子 ~= 表示 pointboxpolygoncircle 类型的通常相等概念。一些几何类型也具有 = 算子,但 = 仅用于比较相等的 areas。其他标量比较算子( 等),对于这些类型可用时,同样比较区域。

Note

在 PostgreSQL 14 之前,点严格低于/高于比较运算符 point <<| point,而 point |>> point 分别称为 <^>^。这些名称仍然可用,但已弃用,并且最终将被删除。

Table 9.37. Geometric Functions

Function

Description

Example(s)

area ( geometric_type ) → double precision 计算区域。适用于 boxpathcirclepath 输入必须进行闭合,否则会返回 NULL。另外,如果 path 自相交,则结果可能没有意义。 area(box '(2,2),(0,0)')4

center ( geometric_type ) → point 计算中心点。适用于 boxcirclecenter(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 '&lt;(0,0),2&gt;')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 计算总长度。适用于 lsegpathlength(path '-1,0),(1,0')4

npoints ( geometric_type ) → integer 返回点数。适用于 pathpolygonnpoints(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 '&lt;(0,0),2&gt;')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. Geometric Type Conversion Functions

Function

Description

Example(s)

box ( circle ) → box 计算圆内切入的盒子。 box(circle '&lt;(0,0),2&gt;')(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)

boxpolygon )→ box 计算多边形的包围框。 box(polygon '0,0),(1,1),(2,0')(2,1),(0,0)

bound_boxboxbox )→ box 计算两个矩形的包围框。 bound_box(box '(1,1),(0,0)', box '(4,4),(3,3)')(4,4),(0,0)

circlebox )→ circle 计算包围矩形的最小圆。 circle(box '(1,1),(0,0)')&lt;(0.5,0.5),0.7071067811865476&gt;

circlepointdouble precision )→ circle 根据圆心和半径创建圆。 circle(point '(0,0)', 2.0)&lt;(0,0),2&gt;

circlepolygon )→ circle 将多边形转换为圆。圆的圆心是多边形各点的平均位置,半径是多边形各点至此圆心的平均距离。 circle(polygon '0,0),(1,3),(2,0')&lt;(1,1),1.6094757082487299&gt;

linepointpoint )→ line 将两点转换为通过这两点的直线。 line(point '(-1,0)', point '(1,0)'){0,-1,0}

lsegbox )→ lseg 提取矩形的对角线作为线段。 lseg(box '(1,0),(-1,0)')[(1,0),(-1,0)]

lsegpointpoint )→ lseg 根据两个端点创建线段。 lseg(point '(-1,0)', point '(1,0)')[(-1,0),(1,0)]

pathpolygon )→ path 将多边形转换为闭合路径(具有相同点的列表)。 path(polygon '0,0),(1,1),(2,0')0,0),(1,1),(2,0

pointdouble precisiondouble precision )→ point 根据坐标创建点。 point(23.4, -44.5)(23.4,-44.5)

pointbox )→ point 计算矩形的中心。 point(box '(1,0),(-1,0)')(0,0)

pointcircle )→ point 计算圆的中心。 point(circle '&lt;(0,0),2&gt;')(0,0)

pointlseg )→ point 计算线段的中心。 point(lseg '[(-1,0),(1,0)]')(0,0)

pointpolygon )→ point 计算多边形的中心(多边形各点位置的平均值)。 point(polygon '0,0),(1,1),(2,0')(1,0.3333333333333333)

polygonbox )→ polygon 将矩形转换为 4 点多边形。 polygon(box '(1,1),(0,0)')0,0),(0,1),(1,1),(1,0

polygoncircle )→ polygon 将圆转换为 12 点多边形。 polygon(circle '&lt;(0,0),2&gt;')-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

polygonintegercircle )→ polygon 将圆转换为 n 点多边形。 polygon(4, circle '&lt;(3,0),1&gt;')2,0),​(3,1),​(4,1.2246063538223773e-16),​(3,-1

polygonpath )→ polygon 将闭合路径转换为具有相同点的多边形。 polygon(path '0,0),(1,1),(2,0')0,0),(1,1),(2,0

若要访问 _point_的两部分数值,可将点作为一个索引分别为 0 和 1 的数组来访问。例如,如果 _t.p_是 _point_列,则 _SELECT p[0] FROM t_会检索 X 坐标,_UPDATE t SET p[1] = …​_改变 Y 坐标。同样,类型值为 _box_或 _lseg_的变量,可以作为由两个 _point_值构成的数组来处理。