Postgresql主要支持一些二维的几何数据类型,最基本的时 “point” ,它是其他类型的基础。
几何类型如下:
类型名称 | 存储空间 | 描述 | 表现形式 |
---|---|---|---|
point | 16字节 | 平面中的点 | (x,y) |
line | 32字节 | 直线 | ((x1,y1),(x2,y2)) |
lseg | 32字节 | 线段(有限长度) | [(x1,y1),(x2,y2)] |
box | 32字节 | 矩形 | ((x1,y1),(x2,y2)) |
path | 16+16*n | 闭合路径(与多边形类似) | ((x1,y1),(x2,y2),…) |
path | 16+16*n | 开放路径 | [(x1,y1),(x2,y2),…] |
polygon | 40+16n字节 | 多边形(与闭合路径相似) | ((x1,y1),(x2,y2),…) |
circle | 24字节 | 园 | <(x,y),r> |
类型名称 ‘值’ 或者 ‘值’::类型名称
示例:
postgres=# select point '1,2';
point
-------
(1,2)
(1 row)
postgres=# select '(1,2)'::point;
point
-------
(1,2)
(1 row)
postgres=# select lseg '1,2,3,2';
lseg
---------------
[(1,2),(3,2)]
(1 row)
postgres=# select lseg '(1,2),(3,2)';
?column?
-------------
[(1,2),(3,2)]
(1 row)
postgres=# select lseg '[(1,2),(3,2)]';
?column?
---------------
[(1,2),(3,2)]
(1 row)
postgres=# select '1,2,3,2'::lseg;
lseg
---------------
[(1,2),(3,2)]
(1 row)
postgres=# select '(1,2),(3,2)'::lseg;
lseg
---------------
[(1,2),(3,2)]
(1 row)
postgres=# select '[(1,2),(3,2)]'::lseg;
lseg
---------------
[(1,2),(3,2)]
(1 row)
postgres=# select box '1,1,2,2';
box
-------------
(2,2),(1,1)
(1 row)
postgres=# select box '(1,1),(2,2)';
box
-------------
(2,2),(1,1)
(1 row)
postgres=# select box '((1,1),(2,2))';
box
-------------
(2,2),(1,1)
(1 row)
postgres=# select '((1,1),(2,2))'::box;
box
-------------
(2,2),(1,1)
(1 row)
postgres=# select '1,1,2,2'::box;
box
-------------
(2,2),(1,1)
(1 row)
注意:矩形不可以使用类似线段那种中括号输入方式,如:
postgres=# select box '[(1,1),(2,2)]';
2020-02-26 15:17:08.646 CST [49927] ERROR: invalid input syntax for type box: "[(1,1),(2,2)]" at character 12
2020-02-26 15:17:08.646 CST [49927] STATEMENT: 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)]';
postgres=# select path '1,1,2,2,3,3,4,4';
path
---------------------------
((1,1),(2,2),(3,3),(4,4))
(1 row)
postgres=# select '1,1,2,2,3,3,4,4'::path;
path
---------------------------
((1,1),(2,2),(3,3),(4,4))
(1 row)
postgres=# select path '(1,1),(2,2),(3,3),(4,4)';
path
---------------------------
((1,1),(2,2),(3,3),(4,4))
(1 row)
postgres=# select '(1,1),(2,2),(3,3),(4,4)'::path;
path
---------------------------
((1,1),(2,2),(3,3),(4,4))
(1 row)
postgres=# select path '((1,1),(2,2),(3,3),(4,4))';
path
---------------------------
((1,1),(2,2),(3,3),(4,4))
(1 row)
postgres=# select '((1,1),(2,2),(3,3),(4,4))'::path;
path
---------------------------
((1,1),(2,2),(3,3),(4,4))
(1 row)
postgres=# select path '[(1,1),(2,2),(3,3),(4,4)]';
path
---------------------------
[(1,1),(2,2),(3,3),(4,4)]
(1 row)
postgres=# select '[(1,1),(2,2),(3,3),(4,4)]'::path;
path
---------------------------
[(1,1),(2,2),(3,3),(4,4)]
(1 row)
注意:路径中使用方括号 “[ ]” 表示开发路径,使用圆括号 “( )" 表示闭合路径,闭合路径指最后一个点与第一个点时连接在一起的。
postgres=# select polygon '1,1,2,2,3,3,4,4';
polygon
---------------------------
((1,1),(2,2),(3,3),(4,4))
(1 row)
postgres=# select '1,1,2,2,3,3,4,4'::polygon;
polygon
---------------------------
((1,1),(2,2),(3,3),(4,4))
(1 row)
postgres=# select polygon '(1,1),(2,2),(3,3),(4,4)';
polygon
---------------------------
((1,1),(2,2),(3,3),(4,4))
(1 row)
postgres=# select '(1,1),(2,2),(3,3),(4,4)'::polygon;
polygon
---------------------------
((1,1),(2,2),(3,3),(4,4))
(1 row)
postgres=# select polygon '((1,1),(2,2),(3,3),(4,4))';
polygon
---------------------------
((1,1),(2,2),(3,3),(4,4))
(1 row)
postgres=# select '((1,1),(2,2),(3,3),(4,4))'::polygon;
polygon
---------------------------
((1,1),(2,2),(3,3),(4,4))
(1 row)
注意:多边形类型输入中不能使用中括号,例如:
postgres=# select '[(1,1),(2,2),(3,3),(4,4)]'::polygon;
2020-02-26 15:31:51.449 CST [49927] ERROR: invalid input syntax for type polygon: "[(1,1),(2,2),(3,3),(4,4)]" at character 8
2020-02-26 15:31:51.449 CST [49927] STATEMENT: select '[(1,1),(2,2),(3,3),(4,4)]'::polygon;
ERROR: invalid input syntax for type polygon: "[(1,1),(2,2),(3,3),(4,4)]"
LINE 1: select '[(1,1),(2,2),(3,3),(4,4)]'::polygon;
postgres=# select circle '1,1,5';
circle
-----------
<(1,1),5>
(1 row)
postgres=# select circle '((1,1)5)';
circle
-----------
<(1,1),5>
(1 row)
postgres=# select circle '<(1,1)5>';
circle
-----------
<(1,1),5>
(1 row)
postgres=# select '1,1,5'::circle;
circle
-----------
<(1,1),5>
(1 row)
postgres=# select '((1,1)5)'::circle;
circle
-----------
<(1,1),5>
(1 row)
postgres=# select '<(1,1)5>'::circle;
circle
-----------
<(1,1),5>
(1 row)
注意:圆形不能使用一下输入方式:
postgres=# select '(1,1),5'::circle;
2020-02-26 15:35:05.073 CST [49927] ERROR: invalid input syntax for type circle: "(1,1),5" at character 8
2020-02-26 15:35:05.073 CST [49927] STATEMENT: select '(1,1),5'::circle;
ERROR: invalid input syntax for type circle: "(1,1),5"
LINE 1: select '(1,1),5'::circle;
^
postgres=# select circle '(1,1),5';
2020-02-26 15:35:16.025 CST [49927] ERROR: invalid input syntax for type circle: "(1,1),5" at character 15
2020-02-26 15:35:16.025 CST [49927] STATEMENT: select circle '(1,1),5';
ERROR: invalid input syntax for type circle: "(1,1),5"
LINE 1: select circle '(1,1),5';
Postgresql提供了丰富的几何类型的操作符,如下:
这四个运算符都是二次元运算符,运算符左侧值的类型可以时point、box、path、circle。运算符右侧值的类型只能时 point ,例如:
postgres=# select point '(1,2)' + point '(10,20)';
?column?
----------
(11,22)
(1 row)
postgres=# select point '(1,2)' - point '(10,20)';
?column?
----------
(-9,-18)
(1 row)
postgres=# select point '(1,2)' * point '(10,20)';
?column?
----------
(-30,40)
(1 row)
postgres=# select point '(1,2)' / point '(10,20)';
?column?
----------
(0.1,0)
(1 row)
postgres=# select box '((0,0),(1,1))' + point '(2,2)';
?column?
-------------
(3,3),(2,2)
(1 row)
postgres=# select box '((0,0),(1,1))' - point '(2,2)';
?column?
-----------------
(-1,-1),(-2,-2)
(1 row)
postgres=# select path '(0,0),(1,1),(2,2)' + point '(2,2)';
?column?
---------------------
((2,2),(3,3),(4,4))
(1 row)
postgres=# select path '(0,0),(1,1),(2,2)' - point '(2,2)';
?column?
-------------------------
((-2,-2),(-1,-1),(0,0))
(1 row)
postgres=# select circle '((0,0),1)' + point '(10,20)';
?column?
-------------
<(10,20),1>
(1 row)
postgres=# select circle '((0,0),1)' - point '(10,20)';
?column?
---------------
<(-10,-20),1>
(1 row)
postgres=# select circle '((0,0),1)' - point '(10,20)';
?column?
---------------
<(-10,-20),1>
(1 row)
postgres=# select point '(1,2)' * point '(2,0)';
?column?
----------
(2,4)
(1 row)
postgres=# select point '(1,2)' * point '(3,0)';
?column?
----------
(3,6)
(1 row)
postgres=# select circle '((1,2),1)' * point '(3,0)';
?column?
-----------
<(3,6),3>
(1 row)
postgres=# select circle '((0,0),1)' * point '(3,0)';
?column?
-----------
<(0,0),3>
(1 row)
postgres=# select point '(1,2)' * point '(0,1)';
?column?
----------
(-2,1)
(1 row)
postgres=# select point '(1,2)' * point '(0,-1)';
?column?
----------
(2,-1)
(1 row)
postgres=# select circle '((0,0),1)' * point '(0,1)';
?column?
-----------
<(0,0),1>
(1 row)
postgres=# select circle '((1,1),1)' * point '(0,-1)';
?column?
------------
<(1,-1),1>
(1 row)
用法:
(1)对于两个线段,计算出线段交点。
(2)对于两个矩形,计算出相交的矩形。
(3)对于路径或多边形,则计算出顶点数。
两个线段:
postgres=# select lseg '(0,0),(2,2)' # lseg '(0,2),(2,0)';
?column?
----------
(1,1)
(1 row)
如果两个线段不相交,返回空:
postgres=# select lseg '(0,0),(2,2)' # lseg '(3,2),(4,5)';
?column?
----------
(1 row)
两个矩形:
postgres=# select box '(0,0),(2,2)' # box '(1,0),(3,1)';
?column?
-------------
(2,1),(1,0)
(1 row)
一元运算符,参数类型只能是lseg(线段)、path(路径)。一般用于计算几何对象的长度,例如:
postgres=# select @-@ lseg '(1,0),(2,3)';
?column?
--------------------
3.1622776601683795
(1 row)
postgres=# select @-@ path '(1,0),(2,3),(5,6)';
?column?
--------------------
14.616020898215645
(1 row)
注意:开放式路径和闭合式路径的长度时不一样的,例如:
postgres=# select @-@ path '((1,0),(2,3),(5,6))';
?column?
--------------------
14.616020898215645
(1 row)
postgres=# select @-@ path '[(1,0),(2,3),(5,6)]';
?column?
-------------------
7.404918347287666
(1 row)
运算符 ”@@“ 为一元运算符,用于计算中心点,例如:
# 圆
postgres=# select @@ circle '((1,1),4)';
?column?
----------
(1,1)
(1 row)
# 矩形
postgres=# select @@ box '(0,0),(1,1)';
?column?
-----------
(0.5,0.5)
(1 row)
# 线段
postgres=# select @@ lseg '(0,0),(2,2)';
?column?
----------
(1,1)
(1 row)
运算符 ”##“为二元运算符,用于计算两个几何对象上离的最近的点,例如:
postgres=# select point '(0,0)' ## lseg '(2,0),(0,2)';
?column?
----------
(1,1)
(1 row)
postgres=# select lseg '(0,0),(2,4)' ## lseg '(1,3),(4,5)';
?column?
------------
(1.75,3.5)
(1 row)
运算符 ”<->“为二元运算符,用于计算两个几何对象之间的间距,例如:
postgres=# select lseg '(0,0),(2,2)' <-> lseg '(2,3),(4,5)';
?column?
----------
1
(1 row)
postgres=# select circle '<(0,0),4>' <-> circle '<(6,7),2>';
?column?
-------------------
3.219544457292887
(1 row)
运算符 ”&&“ 为二元运算符,用于计算两个几何对象之间是否重叠,只要有一个共同点,则为真,否则返回false。例如:
postgres=# select box '(0,0),(2,2)' && box '(1,0),(4,3)';
?column?
----------
t
(1 row)
postgres=# select box '(0,0),(2,2)' && box '(3,4),(4,3)';
?column?
----------
f
(1 row)
判断左右位置的4个运算符:
1.<< : 是否严格在左
2. >> :是否严格在右
3. &< :没有延展到左边
4. &> :没有延展到右边
判断上下位置的6个运算符:
1.<<| :严格在下
2.|>> :严格在上
3.&<| :没有延展到上面
4.|&> :没有延展到下面
5.<^ :在下面(允许接触)
6.>^ :在上面(允许接触)
额外一些运算符:
1.?# :是否相交
2.?- :是否水平或水平对齐
3.?| :是否竖直或竖直对齐
4.?-| :两个对象是否垂直
5.?|| :两个对象是否平行
6.@> :是否包含
7.<@ :包含或在其上
对于多边形,如果表示的七点不一样,但是实现它们的是相同的两个多边形,只是位置不同而已,那么对应的判断方式如下:
postgres=# select polygon '((1,1),(0,0))' ~= polygon '((2,2),(3,3))';
?column?
----------
f
(1 row)
postgres=# select polygon '((1,1),(0,0))' ~= polygon '((0,0),(1,1))';
?column?
----------
t
(1 row)
postgres=# select box '(0,0),(1,1)' ~= box '(1,1),(0,0)'
postgres-# ;
?column?
----------
t
(1 row)
函数如下:
函数 | 返回类型 | 描述 | 例子 | 结果 |
---|---|---|---|---|
area(object) | double precision | 计算几何对象面积 | select area(box ‘(2,2),(4,4)’); | 4 |
center(object) | point | 中心 | select center(box ‘(2,2),(4,4)’); | 3 |
diameter(circle) | double precision | 计算圆的直径 | select diameter(circle ‘<(1,1),2>’) | 4 |
height(box) | double precision | 矩形的高度 | select height(box ‘(2,4),(5,9)’); | 5 |
witdth(box) | double precision | 矩形的宽度 | select width(box ‘(2,4),(5,9)’); | 3 |
isclosed(path) | blooean | 是否是闭合路径 | select isclosed(path ‘((1,1),(2,2),(3,3))’); | t |
isopen(path) | blooean | 是否是开发路径 | select isclosed(path ‘((1,1),(2,2),(3,3))’); | f |
length(object) | double precision | 长度 | select length(path ‘((1,1),(2,2),(3,3))’); | 5.656854 |
npoints(path) | int | 计算路径上的点 | select npoints(path ‘((1,1),(2,2),(3,3))’); | 3 |
npoints(polygon) | int | 计算多边形上的点 | select npoints(polygon ‘((1,1),(2,2),(3,3),(4,4))’); | 4 |
pclose(path) | path | 把路径转换为闭合路径(不管参数路径是否是闭合) | select pclose(path ‘[(1,1),(2,2),(3,3)]’); | ((1,1),(2,2),(3,3)) |
popen(path) | path | 把路径转换为开放路径(不管参数路径是否是开放) | select popen(path ‘((1,1),(2,2),(3,3))’); | [(1,1),(2,2),(3,3)] |
radius(circle) | double precision | 圆的半径 | select radius(circle ‘<(1,1),3>’); | 3 |
不同的几何类型还可以相互转换,转换函数如下:
函数 | 返回类型 | 描述 |
---|---|---|
box(circle) | box | 将圆形转换为矩形 |
box(point,point) | box | 将两个点转换成矩形 |
box(polygon) | box | 将多边形转换成矩形 |
circle(box) | circle | 将矩形转换成圆 |
circle(point,double precision) | circle | 将圆心和半径转换为圆 |
circle(polygon) | circle | 将多边形转换成圆 |
lseg(box) | lseg | 将矩形转换为对角线线段 |
lseg(point,point) | lseg | 将两个点转化成线段 |
path(polygon) | path | 将多边形转换成路径 |
point(double precision,double precision) | point | 构建一个点 |
point(box) | point | 矩形的中心点 |
point(circle) | point | 圆的圆心 |
point(lseg) | point | 线段的中心点 |
point(polygon) | point | 多边形的中心点 |
polygon(box) | polygon | 将矩形转换成4个点的多边形 |
ploygon(circle) | polygon | 将圆形转换成12个点的多边形 |
polygon(npts,circle) | polygon | 将圆形转换成 npts 个点的多边形 |
polygon(path) | polygon | 将路径转换成多边形 |