PostgreSQL数据库提供了点、线、矩形、多边形等几何类型,其他数据库大都没有这些类型,本节将详细讲解这些类型的使用方法。
PostgreSQL主要支持一些二维的几何数据类型。最基本的类型是“point”,它是其他类型的基础。PostgreSQL支持的几何类型见表5-22。
表5-22 PostgreSQL支持的几何类型列表
可以使用下面的格式输入几何类型:
类型名称 '表现形式'
也可以使用类型转换,形式如下:
'表现形式'::类型名称
下面用例子说明如何输入这些几何类型。
点的示例如下:
osdba=# select '1,1'::point; point ------- (1,1) (1 row) osdba=# select '(1,1)'::point; point ------- (1,1) (1 row)
线段的示例如下:
osdba=# select lseg '1,1,2,2'; lseg --------------- [(1,1),(2,2)] (1 row) osdba=# select lseg '(1,1),(2,2)'; lseg --------------- [(1,1),(2,2)] (1 row) osdba=# select lseg '((1,1),(2,2))'; lseg --------------- [(1,1),(2,2)] (1 row) osdba=# select lseg '[(1,1),(2,2)]'; lseg --------------- [(1,1),(2,2)] (1 row) osdba=# select '1,1,2,2'::lseg; lseg --------------- [(1,1),(2,2)] (1 row) osdba=# select '(1,1),(2,2)'::lseg; lseg --------------- [(1,1),(2,2)] (1 row) osdba=# select '((1,1),(2,2))'::lseg; lseg --------------- [(1,1),(2,2)] (1 row) osdba=# select '[(1,1),(2,2)]'::lseg; lseg --------------- [(1,1),(2,2)] (1 row)
矩形的示例如下:
osdba=# select box '1,1,2,2'; box ------------- (2,2),(1,1) (1 row) osdba=# select box '(1,1),(2,2)'; box ------------- (2,2),(1,1) (1 row) osdba=# select box '((1,1),(2,2))'; box ------------- (2,2),(1,1) (1 row)
注意,矩形类型不能使用类似线段类型中的中括号输入方法,示例如下:
osdba=# select box '[(1,1),(2,2)]'; ERROR: invalid input syntax for type box: "[(1,1),(2,2)]" LINE 1: select box '[(1,1),(2,2)]'; ^
路径的示例如下:
osdba=# select path '1,1,2,2,3,3,4,4'; path --------------------------- ((1,1),(2,2),(3,3),(4,4)) (1 row) osdba=# select path '(1,1),(2,2),(3,3),(4,4)'; path --------------------------- ((1,1),(2,2),(3,3),(4,4)) (1 row) osdba=# select path '((1,1),(2,2),(3,3),(4,4))'; path --------------------------- ((1,1),(2,2),(3,3),(4,4)) (1 row) osdba=# select path '[(1,1),(2,2),(3,3),(4,4)]'; path --------------------------- [(1,1),(2,2),(3,3),(4,4)] (1 row) osdba=# select '1,1,2,2,3,3,4,4'::path; path --------------------------- ((1,1),(2,2),(3,3),(4,4)) (1 row) osdba=# select '(1,1),(2,2),(3,3),(4,4)'::path; path --------------------------- ((1,1),(2,2),(3,3),(4,4)) (1 row) osdba=# select '((1,1),(2,2),(3,3),(4,4))'::path; path --------------------------- ((1,1),(2,2),(3,3),(4,4)) (1 row) osdba=# select '[(1,1),(2,2),(3,3),(4,4)]'::path; path --------------------------- [(1,1),(2,2),(3,3),(4,4)] (1 row)
在路径中方括号“[]”表示开放路径,而圆括号“()”表示闭合路径。闭合路径是指最后一个点与第一个点是连接在一起的。
多边形的示例如下:
osdba=# select polygon '1,1,2,2,3,3,4,4'; polygon --------------------------- ((1,1),(2,2),(3,3),(4,4)) (1 row) osdba=# select polygon '(1,1),(2,2),(3,3),(4,4)'; polygon --------------------------- ((1,1),(2,2),(3,3),(4,4)) (1 row) osdba=# select polygon '((1,1),(2,2),(3,3),(4,4))'; polygon --------------------------- ((1,1),(2,2),(3,3),(4,4)) (1 row) osdba=# select polygon '[(1,1),(2,2),(3,3),(4,4)]'; ERROR: invalid input syntax for type polygon: "[(1,1),(2,2),(3,3),(4,4)]" LINE 1: select polygon '[(1,1),(2,2),(3,3),(4,4)]'; ^ osdba=# select '1,1,2,2,3,3,4,4'::polygon; polygon --------------------------- ((1,1),(2,2),(3,3),(4,4)) (1 row) osdba=# select '(1,1),(2,2),(3,3),(4,4)'::polygon; polygon --------------------------- ((1,1),(2,2),(3,3),(4,4)) (1 row) osdba=# select '((1,1),(2,2),(3,3),(4,4))'::polygon; polygon --------------------------- ((1,1),(2,2),(3,3),(4,4)) (1 row)
注意,多边形类型的输入方法中不能使用中括号“[]”:
osdba=# select polygon '[(1,1),(2,2),(3,3),(4,4)]'; ERROR: invalid input syntax for type polygon: "[(1,1),(2,2),(3,3),(4,4)]" LINE 1: select polygon '[(1,1),(2,2),(3,3),(4,4)]'; ^
圆型的示例如下:
osdba=# select circle '1,1,5'; circle ----------- <(1,1),5> (1 row) osdba=# select circle '((1,1),5)'; circle ----------- <(1,1),5> (1 row) osdba=# select circle '<(1,1),5>'; circle ----------- <(1,1),5> (1 row) osdba=# select '1,1,5'::circle; circle ----------- <(1,1),5> (1 row) osdba=# select '((1,1),5)'::circle; circle ----------- <(1,1),5> (1 row) osdba=# select '<(1,1),5>'::circle; circle ----------- <(1,1),5> (1 row)
注意,圆型不能使用下面的输入方式:
osdba=# select circle '(1,1),5'; ERROR: invalid input syntax for type circle: "(1,1),5" LINE 1: select circle '(1,1),5'; ^ osdba=# select '(1,1),5'::circle; ERROR: invalid input syntax for type circle: "(1,1),5" LINE 1: select '(1,1),5'::circle; ^
对于几何类型,PostgreSQL提供了丰富的操作符,具体如下。
·+:平移。
·-:平移。
·*:缩放/旋转。
·/:缩放/旋转。
·#:对于两个线段,计算出交点,而对于两个矩形,计算出相关的矩形。
·#:对于路径或多边形,则计算出顶点数。
·@-@:计算出长度或周长。
·@@:计算中心点。
·##:第一个和第二个操作数的最近点。
·<->:计算间距。
·&&:是否重叠,有一个共同点为真。
·<<:是否严格在左。
·>>:是否严格在右。
·&<:没有延展到右边。
·&>:没有延展到左边。
·<<|:严格在下。
·|>>:严格在上。
·&<|:没有延展到上面。
·|&>:没有延展到下面。
·<^:在下面(允许接触)。
·>^:在上面(允许接触)。
·?#:是否相交。
·?-:是否水平或水平对齐。
·?|:是否竖直或竖直对齐。
·?-|:两个对象是否垂直。
·?||:两个对象是否平行。
·@>:是否包含。
·<@:包含或在其上。
·~=:是否相同。
下面通过示例详细讲解这些运算符。
这4个运算符都是二元运算符,运算符左值的类型可以是“point”“box”“path”“circle”,运算符的右值只能是“point”。下面来看看相关示例。
对于点与点之间,相当于把点看成一个复数,点和点之间的加减乘除相当于两个复数之间的加减乘除,示例如下:
osdba=# select point '(1,2)' + point '(10,20)'; ?column? ---------- (11,22) (1 row) osdba=# select point '(1,2)' - point '(10,20)'; ?column? ---------- (-9,-18) (1 row) osdba=# select point '(1,2)' * point '(10,20)'; ?column? ---------- (-30,40) (1 row) osdba=# select point '(1,2)' / point '(10,20)'; ?column? ---------- (0.1,0) (1 row)
对于矩形与点之间,示例如下:
osdba=# select box '((0,0),(1,1))' + point '(2,2)'; ?column? ------------- (3,3),(2,2) (1 row) osdba=# select box '((0,0),(1,1))' - point '(2,2)'; ?column? ----------------- (-1,-1),(-2,-2) (1 row)
对于路径与点之间,示例如下:
osdba=# select path '(0,0),(1,1),(2,2)' + point '(10,20)'; ?column? --------------------------- ((10,20),(11,21),(12,22)) (1 row) osdba=# select path '(0,0),(1,1),(2,2)' - point '(10,20)'; ?column? ------------------------------- ((-10,-20),(-9,-19),(-8,-18)) (1 row)
对于圆与点之间,示例如下:
osdba=# select circle '((0,0),1)' + point '10,20'; ?column? ------------- <(10,20),1> (1 row) osdba=# select circle '((0,0),1)' - point '10,20'; ?column? --------------- <(-10,-20),1> (1 row)
对于乘法,如果乘数的y值为0,比如“point 'x,0'”,则相当于几何对象缩放x倍,具体示例如下:
osdba=# select point '(1,2)' * point '(2,0)'; ?column? ---------- (2,4) (1 row) osdba=# select point '(1,2)' * point '(3,0)'; ?column? ---------- (3,6) (1 row) osdba=# select circle '((0,0),1)' * point '(3,0)'; ?column? ----------- <(0,0),3> (1 row) osdba=# select circle '((1,1),1)' * point '(3,0)'; ?column? ----------- <(3,3),3> (1 row)
如果乘数为“point '0,1'”,则相当于几何对象逆时针旋转90度,而如果乘数为“point '0,-1'”,则表示顺时针旋转90度,示例如下:
osdba=# select point '(1,2)' * point '(0,1)'; ?column? ---------- (-2,1) (1 row) osdba=# select point '(1,2)' * point '(0,-1)'; ?column? ---------- (2,-1) (1 row) osdba=# select circle '((0,0),1)' * point '(0,1)'; ?column? ----------- <(0,0),1> (1 row) osdba=# select circle '((1,1),1)' * point '(0,1)'; ?column? ------------ <(-1,1),1> (1 row)
运算符“#”有以下几种用法:
·对于两个线段,计算出交点。
·对于两个矩形,计算出相交的矩形。
·对于路径或多边形,则计算出顶点数。
两个线段的示例如下:
osdba=# select lseg '(0,0), (2,2)' # lseg '(0,2), (2,0)'; ?column? ---------- (1,1) (1 row)
如果两个线段没有相交,则返回空:
osdba=# select lseg '(0,0), (1,1)' # lseg '(2,2), (3,3)'; ?column? ---------- (1 row)
两个矩形的示例如下:
osdba=# select box '(0,0), (2,2)' # box '(1,0), (3,1)'; ?column? ------------- (2,1),(1,0) (1 row)
路径或多边形的示例如下:
osdba=# select # path '(1,1), (2,2), (3,3)'; ?column? ---------- 3 (1 row) osdba=# select # polygon '(1,1), (2,2), (3,3)'; ?column? ---------- 3 (1 row)
运算符“@-@”为一元运算符,参数的类型只能为“lseg”“path”。一般用于计算几何对象的长度,下面来看看相关示例。
计算线段长度的示例如下:
osdba=# select @-@ lseg '(0,0), (1,1)'; ?column? ----------------- 1.4142135623731 (1 row)
计算path长度的示例如下:
osdba=# select @-@ path '(0,0), (2,2)'; ?column? ------------------ 5.65685424949238 (1 row) osdba=# select @-@ path '(0,0), (1,1),(2,2)'; ?column? ------------------ 5.65685424949238 (1 row)
注意,开放式路径与闭合路径的长度是不一样的,示例如下:
osdba=# select @-@ path '[(0,0), (1,1),(0,1)]'; ?column? ------------------ 2.41421356237309 (1 row) osdba=# select @-@ path '(0,0), (1,1),(0,1)'; ?column? ------------------ 3.41421356237309 (1 row)
运算符“@@”为一元运算符,用于计算中心点,示例如下:
osdba=# select @@ circle '<(1,1), 2>'; ?column? ---------- (1,1) (1 row) osdba=# select @@ box '(0,0), (1,1)'; ?column? ----------- (0.5,0.5) (1 row) osdba=# select @@ lseg '(0,0), (1,1)'; ?column? ----------- (0.5,0.5) (1 row)
运算符“##”为二元运算符,用于计算两个几何对象上距离最近的点,示例如下:
osdba=# select point '(0,0)' ## lseg '((2,0),(0,2))'; ?column? ---------- (1,1) (1 row) osdba=# select point '(0,0)' ## box '((1,1),(2,2))'; ?column? ---------- (1,1) (1 row) osdba=# select lseg '(1,0),(0,1.5)' ## lseg'((2,0),(0,2))'; ?column? ---------- (0,1.5) (1 row)
运算符“<->”为二元运算符,用于计算两个几何对象之间的间距,示例如下:
osdba=# select lseg '(0,1),(1,0)' <-> lseg'((0,2),(2,0))'; ?column? ------------------- 0.707106781186548 (1 row) osdba=# select circle '((0,0),1)' <-> circle '((3,0),1)'; ?column? ---------- 1 (1 row) osdba=# select circle '((0,0),1)' <-> circle '((2,2),1)'; ?column? ------------------ 0.82842712474619 (1 row)
对于两个矩形来说,它们之间的间距实际上是中心点之间的距离:
osdba=# select box '((0,0),(1,1))' <-> box '((2,0),(4,1))'; ?column? ---------- 2.5 (1 row) osdba=# select box '((0,0),(1,1))' <-> box '((1,1),(2,2))'; ?column? ----------------- 1.4142135623731 (1 row)
运算符“&&”为二元运算符,用于计算两个几何对象之间是否重叠,只要有一个共同点,返回结果即为真,示例如下:
osdba=# select box '((0,0),(1,1))' && box '((1,1),(2,2))'; ?column? ---------- t (1 row) osdba=# select box '((0,0),(1,1))' && box '((2,2),(3,3))'; ?column? ---------- f (1 row) osdba=# select circle '((0,0),1)' && circle '((1,1),1)'; ?column? ---------- t (1 row) osdba=# select circle '((0,0),1)' && circle '((2,2),1)'; ?column? ---------- f (1 row) osdba=# select polygon '(0,0),(2,2),(0,2)' && polygon '(0,1),(1,1),(2,0)'; ?column? ---------- t (1 row)
判断左右位置的运算符有4个,具体如下。
·<<:是否严格在左。
·>>:是否严格在右。
·&<:没有延展到右边。
·&>:没有延展到左边。
判断上下位置的运算符有6个,具体如下:
·<<|:严格在下。
·|>>:严格在上。
·&<|:没有延展到上面。
·|&>:没有延展到下面。
·<^:在下面(允许接触)。
·>^:在上面(允许接触)。
判断两个对象相对位置的其他运算符如下:
·?#:是否相交。
·?-:是否水平或水平对齐。
·?|:是否竖直或竖直对齐。
·?-|:两个对象是否垂直。
·?||:两个对象是否平行。
·@>:是否包含。
·<@:包含或在其上。
下面来看相关示例:
osdba=# select box '((0,0),(1,1))' << box '((1.1,1.1),(2,2))'; ?column? ---------- t (1 row) osdba=# select polygon '(0,0),(0,1),(1,0)' << polygon '(0,1.1),(1.1,1.1),(1.1,0)'; ?column? ---------- f (1 row) osdba=# select polygon '(0,0),(0,1),(1,0)' << polygon '(1.1,0),(1.1,1),(2,0)'; ?column? ---------- t (1 row) osdba=# select circle '((0,0),1)' << circle '((1,1),1)'; ?column? ---------- f (1 row) osdba=# select circle '((0,0),1)' << circle '((3,3),1)'; ?column? ---------- t (1 row)
对于多边形,如果表示的起点不同,但实现上它们是两个相同的多边形,那么相应的判断代码如下:
osdba=# select polygon '((0,0),(1,1))' ~= polygon '((1,1),(0,0))'; ?column? ---------- t (1 row) osdba=# select polygon '((0,0),(1,1),(1,0))' ~= polygon '((1,1),(0,0),(1,0))'; ?column? ---------- t (1 row)
对于矩形,示例代码如下:
osdba=# select box '(0,0),(1,1)' ~= box '(1,1),(0,0)'; ?column? ---------- t (1 row)
可以用于几何类型的函数见表5-23。
表5-23 几何类型的函数
不同的几何类型间还可以进行互相转换,相关的转换函数见表5-24。
表5-24 几何类型的转换函数