购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

5.9 几何类型

PostgreSQL数据库提供了点、线、矩形、多边形等几何类型,其他数据库大都没有这些类型,本节将详细讲解这些类型的使用方法。

5.9.1 几何类型概况

PostgreSQL主要支持一些二维的几何数据类型。最基本的类型是“point”,它是其他类型的基础。PostgreSQL支持的几何类型见表5-22。

表5-22 PostgreSQL支持的几何类型列表

5.9.2 几何类型的输入

可以使用下面的格式输入几何类型:


类型名称 '表现形式'

也可以使用类型转换,形式如下:


'表现形式'::类型名称

下面用例子说明如何输入这些几何类型。

点的示例如下:


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;
               ^

5.9.3 几何类型的操作符

对于几何类型,PostgreSQL提供了丰富的操作符,具体如下。

·+:平移。

·-:平移。

·*:缩放/旋转。

·/:缩放/旋转。

·#:对于两个线段,计算出交点,而对于两个矩形,计算出相关的矩形。

·#:对于路径或多边形,则计算出顶点数。

·@-@:计算出长度或周长。

·@@:计算中心点。

·##:第一个和第二个操作数的最近点。

·<->:计算间距。

·&&:是否重叠,有一个共同点为真。

·<<:是否严格在左。

·>>:是否严格在右。

·&<:没有延展到右边。

·&>:没有延展到左边。

·<<|:严格在下。

·|>>:严格在上。

·&<|:没有延展到上面。

·|&>:没有延展到下面。

·<^:在下面(允许接触)。

·>^:在上面(允许接触)。

·?#:是否相交。

·?-:是否水平或水平对齐。

·?|:是否竖直或竖直对齐。

·?-|:两个对象是否垂直。

·?||:两个对象是否平行。

·@>:是否包含。

·<@:包含或在其上。

·~=:是否相同。

下面通过示例详细讲解这些运算符。

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

这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)

2.运算符“#”

运算符“#”有以下几种用法:

·对于两个线段,计算出交点。

·对于两个矩形,计算出相交的矩形。

·对于路径或多边形,则计算出顶点数。

两个线段的示例如下:


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)

3.运算符“@-@”

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

4.运算符“@@”

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


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)

5.运算符“##”

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


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)

6.运算符“<->”

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


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)

7.运算符“&&”

运算符“&&”为二元运算符,用于计算两个几何对象之间是否重叠,只要有一个共同点,返回结果即为真,示例如下:


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)

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

判断左右位置的运算符有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)

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

对于多边形,如果表示的起点不同,但实现上它们是两个相同的多边形,那么相应的判断代码如下:


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.9.4 几何类型的函数

可以用于几何类型的函数见表5-23。

表5-23 几何类型的函数

不同的几何类型间还可以进行互相转换,相关的转换函数见表5-24。

表5-24 几何类型的转换函数 ucvJYRmRva2ejc9QkEHm7+TPM1fvwe3q9f7Tbh9ATxL2rpvrTfSfjiCMrtulZp4R

点击中间区域
呼出菜单
上一章
目录
下一章
×