Postgresql学习笔记之——数据类型之几何类型

一、几何类型概况

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>
二、几何类型的输入
1.输入格式:

类型名称 ‘值’ 或者 ‘值’::类型名称

示例:

点:
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提供了丰富的几何类型的操作符,如下:

1.平移运算符:”+“、”-“,缩放 / 旋转运算符:” * “、” / “

这四个运算符都是二次元运算符,运算符左侧值的类型可以时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)

对于乘法,如果乘数的y值为0,比如 point(x,0),则相当于几何对象缩放了x倍,具体如下:
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)

如果乘法为point(0,1),则相当于几何对象逆时针旋转90度,如果乘数为point(0,-1),则表示顺时针旋转90度,例如:
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)

2.运算符 ”#“

用法:
(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)

3.运算符 ”@-@“

一元运算符,参数类型只能是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)
4.运算符 ”@@“

运算符 ”@@“ 为一元运算符,用于计算中心点,例如:

# 圆
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)

5.运算符 ”##“

运算符 ”##“为二元运算符,用于计算两个几何对象上离的最近的点,例如:

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)

6.运算符 ”<->“

运算符 ”<->“为二元运算符,用于计算两个几何对象之间的间距,例如:

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)

7.运算符 ”&&“

运算符 ”&&“ 为二元运算符,用于计算两个几何对象之间是否重叠,只要有一个共同点,则为真,否则返回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)

8.判断两个对象相对位置的运算符

判断左右位置的4个运算符:
1.<< : 是否严格在左
2. >> :是否严格在右
3. &< :没有延展到左边
4. &> :没有延展到右边

判断上下位置的6个运算符:
1.<<| :严格在下
2.|>> :严格在上
3.&<| :没有延展到上面
4.|&> :没有延展到下面
5.<^ :在下面(允许接触)
6.>^ :在上面(允许接触)

额外一些运算符:
1.?# :是否相交
2.?- :是否水平或水平对齐
3.?| :是否竖直或竖直对齐
4.?-| :两个对象是否垂直
5.?|| :两个对象是否平行
6.@> :是否包含
7.<@ :包含或在其上

9.判断两个几何对象是否相同的运算符 ”~=“

对于多边形,如果表示的七点不一样,但是实现它们的是相同的两个多边形,只是位置不同而已,那么对应的判断方式如下:

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 将路径转换成多边形

你可能感兴趣的:(Postgresql)