PG数据库GIS基础

基础知识

https://www.cnblogs.com/denny402/p/4968201.html interior:内部,boundary:边界,exterior:外部
postgis:https://postgis.net/docs/
SRID(空间参考信息):https://spatialreference.org/
知乎文章:https://www.zhihu.com/people/li-yang-qiao-89/posts?page=10

几何类别

普通的几何类别:(无法进行GIS操作)
名字存储空间说明表现形式
point16 字节平面中的点(x,y)
line32 字节(无穷)直线(未完全实现)((x1,y1),(x2,y2))
lseg32 字节(有限)线段((x1,y1),(x2,y2))
box32 字节矩形((x1,y1),(x2,y2))
path16+16n 字节闭合路径(与多边形类似)((x1,y1),…)
path16+16n 字节开放路径[(x1,y1),…]
polygon40+16n 字节多边形(与闭合路径相似)((x1,y1),…)
circle24 字节<(x,y),r> (圆心和半径)
参考:
https://blog.csdn.net/liyazhen2011/article/details/82993954
注意点:
lseg:必须是一条线段,多条线段报错
多条线段可以使用path
test=# create table test_circle(id varchar(10), geom circle);
CREATE TABLE
test=# insert into test_circle values('1', circle'<( 1 , 2 ) , 2 >');
INSERT 0 1
test=# select * from test_circle;
 id |   geom    
----+-----------
 1  | <(1,2),2>
(1 行记录)
地理几何类型(Geometry)
创建数据库
create database test
create extension postgis(否则test数据库不支持gis操作)
几何类型
点(POINT)

最多4维,常用2维
创建:

test=# select ST_GeomFromText('POINT(118.7830931 32.0450039)', 4326);
                  st_geomfromtext                   
----------------------------------------------------
 0101000020E61000004A8E85321EB25D40A25813B0C2054040
(1 行记录)

test=# select ST_NDims(ST_GeomFromText('POINT(1 2 3 4)', 4326));
 st_ndims 
----------
        4
(1 行记录)

test=# select ST_NDims(ST_GeomFromText('POINT(1 2 3 4 5)', 4326));
ERROR:  parse error - invalid geometry
提示:  "POINT(1 2 3 4 5)" <-- parse error at position 16 within geometry

常用方法,详细使用见常用GIS操作:

  • ST_X(geometry) —— 返回X坐标
  • ST_Y(geometry) —— 返回Y坐标
  • ST_Z(geometry) —— 返回Z坐标
  • ST_M(geometry) —— 返回M信息
线(LINESTRING)

由点组成,可以多维
创建

select ST_GeomFromText('LINESTRING(118.7830931 32.0450039, 118.7840931 32.0750039)', 4326);

test=# select ST_NDims(ST_GeomFromText('LINESTRING(118.7830931 32.0450039 2 , 118.7840931 32.0750039 2)', 4326));
 st_ndims 
----------
        3
(1 行记录)

所有点的维度也必须一致
test=# select ST_NDims(ST_GeomFromText('LINESTRING(118.7830931 32.0450039 2 , 118.7840931 32.0750039 )', 4326));
ERROR:  can not mix dimensionality in a geometry
提示:  "...0450039 2 , 118.7840931 32.0750039 )" <-- parse error at position 63 within geometry

常用方法,详细使用见常用GIS操作:

  • ST_Length(geometry) —— 返回线串的长度
  • ST_StartPoint(geometry) —— 将线串的第一个坐标作为点返回
  • ST_EndPoint(geometry) —— 将线串的最后一个坐标作为点返回
  • ST_NPoints(geometry) —— 返回线串的坐标数量
多边形(POLYGON)

创建:
当有多个多边形时:
A,B,C
D = AB的并集减去,AB的交集
res=DC的并集减去DC的交集

select ST_GeomFromText('Polygon((118.7830931 32.0450039, 118.7830931 32.0750039, 118.9840931 32.0750039,118.9840931 32.0450039,118.7830931 32.0450039))', 4326);

select ST_GeomFromText('Polygon((118.7830931 32.0450039, 118.7830931 32.0750039, 118.9840931 32.0750039,118.9840931 32.0450039,118.7830931 32.0450039), (118.6830931 32.0350039, 118.6830931 32.0650039, 118.8840931 32.0650039,118.8840931 32.0350039,118.6830931 32.0350039))', 4326);

select ST_GeomFromText('Polygon((118.7830931 32.0450039, 118.7830931 32.0750039, 118.9840931 32.0750039,118.9840931 32.0450039,118.7830931 32.0450039), (118.6830931 32.0350039, 118.6830931 32.0650039, 118.8840931 32.0650039,118.8840931 32.0350039,118.6830931 32.0350039), (118.7830931 32.0450039,118.8840931 32.0450039, 118.8840931 32.0650039,118.7830931 32.0650039,118.7830931 32.0450039))', 4326);

常用方法,详细使用见常用GIS操作:

  • ST_Area(geometry) —— 返回多边形的面积
  • ST_NRings(geometry) —— 返回多边形中环的数量(通常为1个,其他是孔)
  • ST_ExteriorRing(geometry) —— 以线串的形式返回多边形最外面的环
  • ST_InteriorRingN(geometry, n) —— 以线串形式返回指定的内部环
  • ST_Perimeter(geometry) —— 返回所有环的长度
图形集合(GEOMETRYCOLLECTION)

包括:

  • MultiPoint —— 点集合
  • MultiLineString —— 线串集合
  • MultiPolygon —— 多边形集合
  • GeometryCollection —— 由任意几何图形(包括其他GeometryCollection)组成的异构集合
    创建:
    MultiPoint
test=# select ST_GeomFromText('MultiPoint ((118.7830931 32.0450039),(118.8840931 32.0450039),(118.8840931 32.0650039))', 4326);
                                                                     st_geomfromtext                                                                      
----------------------------------------------------------------------------------------------------------------------------------------------------------
 0104000020E61000000300000001010000004A8E85321EB25D40A25813B0C20540400101000000A2C739FB94B85D40A25813B0C20540400101000000A2C739FB94B85D40654E3C0C52084040
(1 行记录)

test=# select ST_GeomFromText('MultiPoint (118.7830931 32.0450039, 118.8840931 32.0450039, 118.8840931 32.0650039)', 4326);
                                                                     st_geomfromtext                                                                      
----------------------------------------------------------------------------------------------------------------------------------------------------------
 0104000020E61000000300000001010000004A8E85321EB25D40A25813B0C20540400101000000A2C739FB94B85D40A25813B0C20540400101000000A2C739FB94B85D40654E3C0C52084040
(1 行记录)

test=# select ST_GeomFromText('MultiPoint ((118.7830931 32.0450039))', 4326);
                           st_geomfromtext                            
----------------------------------------------------------------------
 0104000020E61000000100000001010000004A8E85321EB25D40A25813B0C2054040
(1 行记录)

test=# select ST_GeomFromText('MultiPoint (118.7830931 32.0450039)', 4326);
                           st_geomfromtext                            
----------------------------------------------------------------------
 0104000020E61000000100000001010000004A8E85321EB25D40A25813B0C2054040
(1 行记录)

MultiLineString:

select ST_GeomFromText('MultiLineString(118.7830931 32.0450039, 118.8840931 32.0450039, 118.8840931 32.0650039)', 4326);
ERROR:  parse error - invalid geometry
提示:  "MultiLineString(118.7830931 " <-- parse error at position 28 within geometry
test=# select ST_GeomFromText('MultiLineString((118.7830931 32.0450039, 118.8840931 32.0450039, 118.8840931 32.0650039))', 4326);
                                                               st_geomfromtext                                                                
----------------------------------------------------------------------------------------------------------------------------------------------
 0105000020E6100000010000000102000000030000004A8E85321EB25D40A25813B0C2054040A2C739FB94B85D40A25813B0C2054040A2C739FB94B85D40654E3C0C52084040
(1 行记录)

select ST_GeomFromText('MultiLineString((118.7830931 32.0450039, 118.8840931 32.0450039, 118.8840931 32.0650039),(118.9830931 32.0450039, 119.3840931 32.0450039))', 4326);

MultiPolygon:

select ST_GeomFromText('MultiPolygon(((118.7830931 32.0450039, 118.8840931 32.0450039, 118.8840931 32.0650039,118.7830931 32.0450039)),((118.9830931 32.0450039, 119.3840931 32.0450039,119.3840931 32.5450039,118.9830931 32.0450039)))', 4326);

GeometryCollection:

需要指定类型
select ST_GeomFromText('GeometryCollection(Polygon((118.7830931 32.0450039, 118.8840931 32.0450039, 118.8840931 32.0650039,118.7830931 32.0450039)),Polygon((118.9830931 32.0450039, 119.3840931 32.0450039,119.3840931 32.5450039,118.9830931 32.0450039)))', 4326);

select ST_GeomFromText('GeometryCollection(Polygon((118.7830931 32.0450039, 118.8840931 32.0450039, 118.8840931 32.0650039,118.7830931 32.0450039)),Point(118.9830931 32.0450039))', 4326);

常用方法,详细使用见常用GIS操作:

  • ST_NumGeometries(geometry) —— 返回集合中的组成部分的数量
  • ST_GeometryN(geometry, n) —— 返回集合中指定的组成部分
  • ST_Area(geometry) —— 返回集合中所有多边形组成部分的总面积
  • ST_Length(geometry) —— 返回所有线段组成部分的总长度

常用的GIS操作

创建几何图形的几种方式

类型的转换

olddata::newtype
SELECT ST_GeomFromText('POINT(2 2)',4326)::text;
ST_GeomFromText/ST_GeogFromText

ST_GeomFromText(text, srid) —— 返回geometry
ST_GeogFromText(text) —— 返回geography
注意SRID
0105000020E6100000010000000102000000020000004A8E85321EB25D40A25813B0C2054040A1F2542C23B25D40A99894CCFB054040本身就代表是geometry

test=# select ST_GeomFromText('MULTILINESTRING((118.7830931 32.0450039,118.7833968 32.0467468))',4326)
test-# ;
                                               st_geomfromtext                                                
--------------------------------------------------------------------------------------------------------------
 0105000020E6100000010000000102000000020000004A8E85321EB25D40A25813B0C2054040A1F2542C23B25D40A99894CCFB054040
(1 行记录)
test=# select ST_GeogFromText('MULTILINESTRING((118.7830931 32.0450039,118.7833968 32.0467468))');
                                               st_geogfromtext                                                
--------------------------------------------------------------------------------------------------------------
 0105000020E6100000010000000102000000020000004A8E85321EB25D40A25813B0C2054040A1F2542C23B25D40A99894CCFB054040
(1 行记录)
test=# select 'MULTILINESTRING((118.7830931 32.0450039,118.7833968 32.0467468))'::geography ;
                                                  geography                                                   
--------------------------------------------------------------------------------------------------------------
 0105000020E6100000010000000102000000020000004A8E85321EB25D40A25813B0C2054040A1F2542C23B25D40A99894CCFB054040
(1 行记录)

test=# select 'MULTILINESTRING((118.7830931 32.0450039,118.7833968 32.0467468))'::Geometry;
                                               geometry                                               
------------------------------------------------------------------------------------------------------
 0105000000010000000102000000020000004A8E85321EB25D40A25813B0C2054040A1F2542C23B25D40A99894CCFB054040
(1 行记录)

ST_GeomFromGeoJSON

ST_AsGeoJSON(geometry) —— 返回text
默认SRID为0

SELECT ST_AsText(ST_GeomFromGeoJSON('{"type":"Point","coordinates":[-48.23456,20.12345]}')) As wkt;
wkt
------
POINT(-48.23456 20.12345)

SELECT ST_AsText(ST_GeomFromGeoJSON('{"type":"Point","coordinates":[-48.23456,20.12345]}'))::geography As wkt;
ST_GeomFromWKB
test=# select st_ASText(ST_GeomFromWKB('0105000020E6100000010000000102000000020000004A8E85321EB25D40A25813B0C2054040A1F2542C23B25D40A99894CCFB054040'::geometry));
WARNING:  OGC WKB expected, EWKB provided - use GeometryFromEWKB() for this
                            st_astext                             
------------------------------------------------------------------
 MULTILINESTRING((118.7830931 32.0450039,118.7833968 32.0467468))
(1 行记录)

test=# select st_ASText(ST_GeomFromWKB('0105000020E6100000010000000102000000020000004A8E85321EB25D40A25813B0C2054040A1F2542C23B25D40A99894CCFB054040'));
ERROR:  Invalid endian flag value encountered.
test=# select st_ASText(ST_GeomFromWKB('0105000020E6100000010000000102000000020000004A8E85321EB25D40A25813B0C2054040A1F2542C23B25D40A99894CCFB054040'::geography));
WARNING:  OGC WKB expected, EWKB provided - use GeometryFromEWKB() for this
                            st_astext                             
------------------------------------------------------------------
 MULTILINESTRING((118.7830931 32.0450039,118.7833968 32.0467468))
(1 行记录)
返回text获取经纬度
ST_ASText

ST_AsText(geometry) —— 返回text

test=# select ST_ASText(ST_GeomFromText('POINT(118.7830931 32.0450039)', 4326));
           st_astext           
-------------------------------
 POINT(118.7830931 32.0450039)
(1 行记录)

test=# select ST_ASText(ST_GeomFromText('Polygon((118.7830931 32.0450039, 118.784 32.075, 118 32, 118.7830931 32.0450039))', 4326));
                                   st_astext                                    
--------------------------------------------------------------------------------
 POLYGON((118.7830931 32.0450039,118.784 32.075,118 32,118.7830931 32.0450039))
(1 行记录)

test=# select ST_AsText('0105000020E6100000010000000102000000020000004A8E85321EB25D40A25813B0C2054040A1F2542C23B25D40A99894CCFB054040');
                            st_astext                             
------------------------------------------------------------------
 MULTILINESTRING((118.7830931 32.0450039,118.7833968 32.0467468))
(1 行记录)
ST_AsEWKT

ST_AsEWKT(geometry) —— 返回text
与ST_ASText用法基本一致

test=# select ST_AsEWKT('0105000020E6100000010000000102000000020000004A8E85321EB25D40A25813B0C2054040A1F2542C23B25D40A99894CCFB054040');
                                 st_asewkt                                  
----------------------------------------------------------------------------
 SRID=4326;MULTILINESTRING((118.7830931 32.0450039,118.7833968 32.0467468))
(1 行记录)

test=# select ST_AsEWKT('0105000000010000000102000000020000004A8E85321EB25D40A25813B0C2054040A1F2542C23B25D40A99894CCFB054040');
                            st_asewkt                             
------------------------------------------------------------------
 MULTILINESTRING((118.7830931 32.0450039,118.7833968 32.0467468))
(1 行记录)
其他操作
POINT
ST_X(只能用于POINT)

ST_X(geometry)

获取点的第一个字段

test=# select ST_X(ST_GeomFromText('POINT(118.7830931 32.0450039)', 4326));
    st_x     
-------------
 118.7830931
(1 行记录)

test=# select ST_X(ST_GeomFromText('MULTILINESTRING((118.7830931 32.0450039,118.7833968 32.0467468))', 4326));
ERROR:  Argument to ST_X() must be a point

SELECT ST_X(ST_GeomFromText('POINT(2 2)',4326)::text);
ST_Y(只能用于POINT)

ST_Y(geometry)

获取点的第二个字段

test=# select ST_Y(ST_GeomFromText('POINT(118.7830931 32.0450039)', 4326));
    st_y    
------------
 32.0450039
(1 行记录)
ST_Z(只能用于POINT)

ST_Z(geometry)

获取点的第三个字段,没有则为空

test=# select ST_Z(ST_GeomFromText('POINT(118.7830931 32.0450039 2)', 4326));
 st_z 
------
    2
(1 行记录)

test=# select ST_Z(ST_GeomFromText('POINT(118.7830931 32.0450039)', 4326));
 st_z 
------
     
(1 行记录)
ST_M(只能用于POINT)

ST_M(geometry) 
获取点的第四个字段,没有则为空

test=# select ST_M(ST_GeomFromText('POINT(118.7830931 32.0450039 2 3)', 4326));
 st_m 
------
    3
(1 行记录)
LINESTRING
ST_Length

ST_Length(geometry)

计算线段长度,每两点读一个欧几里得距离并求和
其他geometry也可以计算,但是结果都为0

test=# select ST_Length(ST_GeomFromText('LINESTRING(114 35, 118 32)', 4326));
 st_length 
-----------
         5
(1 行记录)

test=# select ST_Length(ST_GeomFromText('LINESTRING(114 35, 118 32, 114 35)', 4326));
 st_length 
-----------
        10
(1 行记录)

test=# select ST_Length(ST_GeomFromText('POINT(118.7830931 32.0450039)', 4326));
 st_length 
-----------
         0
(1 行记录)

test=# select ST_Length(ST_GeomFromText('Polygon((114 35, 118 32, 122 35, 114 35))', 4326));
 st_length 
-----------
         0
(1 行记录)

参数是geography时,计算地理距离

test=# select ST_Length(ST_GeogFromText('LINESTRING(114 35, 118 32)'));
    st_length     
------------------
 498778.107681175
(1 行记录)

图形集合

test=# select ST_Length(ST_GeomFromText('MultiLineString((118.7830931 32.0450039, 118.8840931 32.0450039, 118.8840931 32.0650039),(118.9830931 32.0450039, 118.9840931 32.0450039))', 4326));
     st_length     
-------------------
 0.121999999999993
(1 行记录)

test=# select ST_Length(ST_GeometryN(ST_GeomFromText('MultiLineString((118.7830931 32.0450039, 118.8840931 32.0450039, 118.8840931 32.0650039),(118.9830931 32.0450039, 118.9840931 32.0450039))', 4326),1));
     st_length     
-------------------
 0.121000000000002
(1 行记录)

test=# select ST_Length(ST_GeometryN(ST_GeomFromText('MultiLineString((118.7830931 32.0450039, 118.8840931 32.0450039, 118.8840931 32.0650039),(118.9830931 32.0450039, 118.9840931 32.0450039))', 4326),2));
      st_length       
----------------------
 0.000999999999990564
(1 行记录)

ST_StartPoint/ST_EndPoint

ST_StartPoint/ST_EndPoint(geometry)
获取线段的开始/结束点
其他geometry返回空值

test=# select ST_StartPoint(ST_GeomFromText('Polygon((114 35, 118 32, 122 35, 114 35))', 4326));
 st_startpoint 
---------------
 
(1 行记录)

test=# select ST_StartPoint(ST_GeomFromText('LINESTRING(114 35, 118 32, 114 35)', 4326));
                   st_startpoint                    
----------------------------------------------------
 0101000020E61000000000000000805C400000000000804140
(1 行记录)

test=# select ST_ASText(ST_StartPoint(ST_GeomFromText('LINESTRING(114 35, 118 32, 114 35)', 4326)));
   st_astext   
---------------
 POINT(114 35)
(1 行记录)
ST_NPoints

ST_NPoints(geometry)

获取geometry中点的个数

test=# select ST_NPoints(ST_GeomFromText('LINESTRING(114 35, 118 32, 114 35)', 4326));
 st_npoints 
------------
          3
(1 行记录)

test=# select ST_NPoints(ST_GeomFromText('LINESTRING(114 35, 114 35, 118 32, 114 35)', 4326));
 st_npoints 
------------
          4
(1 行记录)

test=# select ST_NPoints(ST_GeomFromText('Polygon((114 35, 118 32, 122 35, 1 1,114 35))', 4326));
 st_npoints 
------------
          5
(1 行记录)

ST_Area

ST_Area(geometry)

计算面积
当时点和线段时结果为0
输入为geometry时是用平面距离
输入为geography时是用地理面积

test=# select ST_Area(ST_GeomFromText('LINESTRING(114 35, 118 32, 114 35)', 4326));
 st_area 
---------
       0
(1 行记录)

test=# select ST_Area(ST_GeomFromText('Polygon((114 35, 118 35, 118 38,114 38,114 35))', 4326));
 st_area 
---------
      12
(1 行记录)

test=# select ST_Area(ST_GeogFromText('Polygon((114 35, 118 35, 118 38,114 38,114 35))'));
     st_area      
------------------
 119284641095.694
(1 行记录)

select ST_Area(ST_GeomFromText('Polygon((118.7830931 32.0450039, 118.7830931 32.0750039, 118.9840931 32.0750039,118.9840931 32.0450039,118.7830931 32.0450039), (118.6830931 32.0350039, 118.6830931 32.0650039, 118.8840931 32.0650039,118.8840931 32.0350039,118.6830931 32.0350039), (118.7830931 32.0450039,118.8840931 32.0450039, 118.8840931 32.0650039,118.7830931 32.0650039,118.7830931 32.0450039))', 4326));
A-B-C

select ST_Area(ST_GeomFromText('Polygon((118.7830931 32.0450039, 118.7830931 32.0750039, 118.9840931 32.0750039,118.9840931 32.0450039,118.7830931 32.0450039))', 4326));

select ST_Area(ST_GeomFromText('Polygon((118.6830931 32.0350039, 118.6830931 32.0650039, 118.8840931 32.0650039,118.8840931 32.0350039,118.6830931 32.0350039))', 4326));

select ST_Area(ST_GeomFromText('Polygon((118.7830931 32.0450039,118.8840931 32.0450039, 118.8840931 32.0650039,118.7830931 32.0650039,118.7830931 32.0450039))', 4326));

图形集合

select ST_Area(ST_GeomFromText('GeometryCollection(Polygon((118.7830931 32.0450039, 118.8840931 32.0450039, 118.8840931 32.0650039,118.7830931 32.0450039)),Point(118.9830931 32.0450039))', 4326));
ST_NRings

ST_NRings(geometry)

返回polygon中环的个数

test=# select ST_NRings(ST_GeomFromText('Polygon((118.7830931 32.0450039, 118.7830931 32.0750039, 118.9840931 32.0750039,118.9840931 32.0450039,118.7830931 32.0450039), (118.6830931 32.0350039, 118.6830931 32.0650039, 118.8840931 32.0650039,118.8840931 32.0350039,118.6830931 32.0350039), (118.7830931 32.0450039,118.8840931 32.0450039, 118.8840931 32.0650039,118.7830931 32.0650039,118.7830931 32.0450039))', 4326));
 st_nrings 
-----------
         3
(1 行记录)

test=# select ST_NRings(ST_GeomFromText('Polygon((118.7830931 32.0450039, 118.7830931 32.0750039, 118.9840931 32.0750039,118.9840931 32.0450039,118.7830931 32.0450039), (118.6830931 32.0350039, 118.6830931 32.0650039, 118.8840931 32.0650039,118.8840931 32.0350039,118.6830931 32.0350039))', 4326));
 st_nrings 
-----------
         2
(1 行记录)

ST_ExteriorRing

ST_ExteriorRing(geometry)

以线串的形式返回多边形最外面的环

test=# select ST_ASText(ST_ExteriorRing(ST_GeomFromText('Polygon((118.7830931 32.0450039, 118.7830931 32.0750039, 118.9840931 32.0750039,118.9840931 32.0450039,118.7830931 32.0450039), (118.6830931 32.0350039, 118.6830931 32.0650039, 118.8840931 32.0650039,118.8840931 32.0350039,118.6830931 32.0350039), (118.7830931 32.0450039,118.8840931 32.0450039, 118.8840931 32.0650039,118.7830931 32.0650039,118.7830931 32.0450039))', 4326)));
                                                           st_astext                                                            
--------------------------------------------------------------------------------------------------------------------------------
 LINESTRING(118.7830931 32.0450039,118.7830931 32.0750039,118.9840931 32.0750039,118.9840931 32.0450039,118.7830931 32.0450039)
(1 行记录)

ST_InteriorRingN

ST_InteriorRingN(geometry, n)

以线串形式返回指定的内部环,不存在返回空

test=# select ST_ASText(ST_InteriorRingN(ST_GeomFromText('Polygon((118.7830931 32.0450039, 118.7830931 32.0750039, 118.9840931 32.0750039,118.9840931 32.0450039,118.7830931 32.0450039), (118.6830931 32.0350039, 118.6830931 32.0650039, 118.8840931 32.0650039,118.8840931 32.0350039,118.6830931 32.0350039), (118.7830931 32.0450039,118.8840931 32.0450039, 118.8840931 32.0650039,118.7830931 32.0650039,118.7830931 32.0450039))', 4326), 1));
                                                           st_astext                                                            
--------------------------------------------------------------------------------------------------------------------------------
 LINESTRING(118.6830931 32.0350039,118.6830931 32.0650039,118.8840931 32.0650039,118.8840931 32.0350039,118.6830931 32.0350039)
(1 行记录)

test=# select ST_ASText(ST_InteriorRingN(ST_GeomFromText('Polygon((118.7830931 32.0450039, 118.7830931 32.0750039, 118.9840931 32.0750039,118.9840931 32.0450039,118.7830931 32.0450039), (118.6830931 32.0350039, 118.6830931 32.0650039, 118.8840931 32.0650039,118.8840931 32.0350039,118.6830931 32.0350039), (118.7830931 32.0450039,118.8840931 32.0450039, 118.8840931 32.0650039,118.7830931 32.0650039,118.7830931 32.0450039))', 4326), 2));
                                                           st_astext                                                            
--------------------------------------------------------------------------------------------------------------------------------
 LINESTRING(118.7830931 32.0450039,118.8840931 32.0450039,118.8840931 32.0650039,118.7830931 32.0650039,118.7830931 32.0450039)
(1 行记录)

test=# select ST_ASText(ST_InteriorRingN(ST_GeomFromText('Polygon((118.7830931 32.0450039, 118.7830931 32.0750039, 118.9840931 32.0750039,118.9840931 32.0450039,118.7830931 32.0450039), (118.6830931 32.0350039, 118.6830931 32.0650039, 118.8840931 32.0650039,118.8840931 32.0350039,118.6830931 32.0350039), (118.7830931 32.0450039,118.8840931 32.0450039, 118.8840931 32.0650039,118.7830931 32.0650039,118.7830931 32.0450039))', 4326), 3));
 st_astext 
-----------
 
(1 行记录)

ST_Perimeter

ST_Perimeter(geometry)

返回所有环的长度之和

test=# select ST_Perimeter(ST_GeomFromText('Polygon((118.7830931 32.0450039, 118.7830931 32.0750039, 118.9840931 32.0750039,118.9840931 32.0450039,118.7830931 32.0450039), (118.6830931 32.0350039, 118.6830931 32.0650039, 118.8840931 32.0650039,118.8840931 32.0350039,118.6830931 32.0350039), (118.7830931 32.0450039,118.8840931 32.0450039, 118.8840931 32.0650039,118.7830931 32.0650039,118.7830931 32.0450039))', 4326));
   st_perimeter   
------------------
 1.16600000000001
(1 行记录)

test=# select ST_Perimeter(ST_GeogFromText('Polygon((118.7830931 32.0450039, 118.7830931 32.0750039, 118.9840931 32.0750039,118.9840931 32.0450039,118.7830931 32.0450039), (118.6830931 32.0350039, 118.6830931 32.0650039, 118.8840931 32.0650039,118.8840931 32.0350039,118.6830931 32.0350039), (118.7830931 32.0450039,118.8840931 32.0450039, 118.8840931 32.0650039,118.7830931 32.0650039,118.7830931 32.0450039))'));
   st_perimeter   
------------------
 112745.336562741
 
(1 行记录)
test=# select ST_Perimeter(ST_GeogFromText('Polygon((118.7830931 32.0450039, 118.7830931 32.0750039, 118.9840931 32.0750039,118.9840931 32.0450039,118.7830931 32.0450039))'));
   st_perimeter   
------------------
 44614.7485352211
(1 行记录)

test=# select ST_Perimeter(ST_GeogFromText('Polygon((118.6830931 32.0350039, 118.6830931 32.0650039, 118.8840931 32.0650039,118.8840931 32.0350039,118.6830931 32.0350039))'));
   st_perimeter   
------------------
 44618.8672026453
(1 行记录)

test=# select ST_Perimeter(ST_GeogFromText('Polygon((118.7830931 32.0450039,118.8840931 32.0450039, 118.8840931 32.0650039,118.7830931 32.0650039,118.7830931 32.0450039))'));
   st_perimeter   
------------------
 23511.7208248746
(1 行记录)

针对一个多边形的方法
ST_GeometryType

ST_GeometryType(geometry) —— 返回几何图形的类型

test=# select ST_GeometryType(ST_GeogFromText('MULTILINESTRING((118.7830931 32.0450039,118.7833968 32.0467468))'));
ERROR:  function st_geometrytype(geography) does not exist
第1行select ST_GeometryType(ST_GeogFromText('MULTILINESTRING((118...
            ^
提示:  No function matches the given name and argument types. You might need to add explicit type casts.
test=# select ST_GeometryType(ST_GeomFromText('MULTILINESTRING((118.7830931 32.0450039,118.7833968 32.0467468))',4326));
  st_geometrytype   
--------------------
 ST_MultiLineString
ST_NDims

ST_NDims(geometry) —— 返回几何图形的维数

test=# select ST_NDims(ST_GeomFromText('MULTILINESTRING((118.7830931 32.0450039,118.7833968 32.0467468))'));
 st_ndims 
----------
        2
ST_SRID

ST_SRID(geometry) —— 返回几何图形的空间参考标识码

test=# select ST_SRID(ST_GeomFromText('MULTILINESTRING((118.7830931 32.0450039,118.7833968 32.0467468))'));
 st_srid 
---------
       0
(1 行记录)

test=# select ST_SRID(ST_GeomFromText('MULTILINESTRING((118.7830931 32.0450039,118.7833968 32.0467468))', 4326));
 st_srid 
---------
    4326
(1 行记录)
ST_IsClosed

ST_IsClosed(geomtery)
判断geometry是否闭合

test=# select ST_IsClosed(ST_GeomFromText('LINESTRING(118.7830931 32.0450039, 118.7840931 32.0750039)', 4326));
 st_isclosed 
-------------
 f
(1 行记录)

test=# select ST_IsClosed(ST_GeomFromText('LINESTRING(118.7830931 32.0450039, 118.7840931 32.0750039, 118 32, 118.7830931 32.0450039)', 4326));
 st_isclosed 
-------------
 t
(1 行记录)

test=# select ST_IsClosed(ST_GeomFromText('Polygon((118.7830931 32.0450039, 118.784 32.075, 118 32, 118.7830931 32.0450039))', 4326));
 st_isclosed 
-------------
 t
(1 行记录)
ST_IsSimple

ST_IsSimple(geometry)
判断geometry是否与与自身交叉或接触

test=# select ST_IsSimple(ST_GeomFromText('LINESTRING(118.7830931 32.0450039, 118 32)', 4326));
 st_issimple 
-------------
 t
(1 行记录)

test=# select ST_IsSimple(ST_GeomFromText('LINESTRING(118.7830931 32.0450039, 118 32, 118.7830931 32.0450039)', 4326));
 st_issimple 
-------------
 f
(1 行记录)

test=# select ST_IsSimple(ST_GeomFromText('Polygon((118.7830931 32.0450039, 118.784 32.075, 118 32, 118.7830931 32.0450039))', 4326));
 st_issimple 
-------------
 t
(1 行记录)
ST_NumGeometries

ST_NumGeometries(geometry)
集合中的组成部分的数量

test=# select ST_NumGeometries(ST_GeomFromText('MultiLineString((118.7830931 32.0450039, 118.8840931 32.0450039, 118.8840931 32.0650039),(118.9830931 32.0450039, 118.9840931 32.0450039))', 4326));
 st_numgeometries 
------------------
                2
(1 行记录)

test=# select ST_NumGeometries(ST_GeomFromText('Polygon((118.7830931 32.0450039, 118.7830931 32.0750039, 118.9840931 32.0750039,118.9840931 32.0450039,118.7830931 32.0450039), (118.6830931 32.0350039, 118.6830931 32.0650039, 118.8840931 32.0650039,118.8840931 32.0350039,118.6830931 32.0350039), (118.7830931 32.0450039,118.8840931 32.0450039, 118.8840931 32.0650039,118.7830931 32.0650039,118.7830931 32.0450039))', 4326));
 st_numgeometries 
------------------
                1
(1 行记录)

ST_GeometryN

ST_GeometryN(geometry, n) —— 返回集合中指定的组成部分

test=# select ST_ASText(ST_GeometryN(ST_GeomFromText('MultiLineString((118.7830931 32.0450039, 118.8840931 32.0450039, 118.8840931 32.0650039),(118.9830931 32.0450039, 118.9840931 32.0450039))', 4326),2));
                         st_astext                         
-----------------------------------------------------------
 LINESTRING(118.9830931 32.0450039,118.9840931 32.0450039)
(1 行记录)

test=# select ST_ASText(ST_GeometryN(ST_GeomFromText('MultiLineString((118.7830931 32.0450039, 118.8840931 32.0450039, 118.8840931 32.0650039),(118.9830931 32.0450039, 118.9840931 32.0450039))', 4326),3));
 st_astext 
-----------
 
(1 行记录)
ST_Buffer

ST_Buffer(geometry, distance)
缓冲区操作,接受几何图形和缓冲区距离作为参数,并输出一个多边形,这个多边形的边界与输入的几何图形之间的距离与输入的缓冲区距离相等。
ST_Buffer函数也接受负的距离值,从而在输入的多边形内构建内接多边形。而对于线串和点,只会返回空值。

select ST_GeomFromText( ST_ASText( ST_Buffer(ST_Boundary(geom)::geography, 1000)), 4326) as bm from bt_boundary_info where properties -> 'all_tags' ->> 'name:zh' like '%江宁%'

select ST_Buffer(ST_Boundary(geom)::geography, 1000)::geometry as bm from bt_boundary_info where properties -> 'all_tags' ->> 'name:zh' like '%江宁%'1

select station_name,ci,geom
from cmcc_metro_bts_with_geom a
where ST_Contains(
(select 
	   st_buffer(geom::geography,500)::geometry as geom
	   from nanjing_station_coordinate_with_geom b where b.station_id = a.station_id), geom)
	   
select station_name,ci,
ST_Contains(
(select 
	   st_buffer(geom::geography,500)::geometry as geom
	   from nanjing_station_coordinate_with_geom b where b.station_id = a.station_id), geom)
from cmcc_metro_bts_with_geom a
geometry与geometry的关系
ST_Distance

计算两个geometry/geography间的距离

2维:
点与点:

3维计算,只与X,Y有关
test=# select ST_Distance(ST_GeomFromText('MULTILINESTRING((118 35 2,119 35 2))', 4326), ST_GeomFromText('POINT(118 32 6)', 4326));
 st_distance 
-------------
           3
(1 行记录)

test=# select ST_Distance(ST_GeomFromText('MULTILINESTRING((118 35 2,119 35 2))', 4326), ST_GeomFromText('POINT(118 32 5)', 4326));
 st_distance 
-------------
           3
(1 行记录)

test=# select ST_Distance(ST_GeomFromText('MULTILINESTRING((118 35 2,119 35 2))'), ST_GeomFromText('POINT(118 32 5)'));
 st_distance 
-------------
           3
(1 行记录)

计算地理距离:

结果正确,单位:M
select ST_Distance('POINT(121 31)'::geography, 'POINT(124 35)'::geography)
select ST_Distance(ST_GeogFromText('MULTILINESTRING((118 35 2,119 35 2))'), ST_GeogFromText('POINT(118 32 5)'));
ST_DWithin

ST_DWithin(geometry A, geometry B, radius)
测试两个几何图形之间的距离是否在某个范围之内

SELECT name FROM nyc_streets WHERE ST_DWithin(
        geom,
        ST_GeomFromText('POINT(583571 4506714)',26918),
        10
      );
      
 select 
ST_GeomFromText('POINT(118 32)', 4326), 
ST_GeomFromText('POINT(118 32.001)', 4326),
ST_DISTANCE('POINT(118 32)'::geography, 'POINT(118 32.001)'::geography),
ST_DWithin(
        ST_GeogFromText('POINT(118 32)'),
        ST_GeogFromText('POINT(118 32.001)'),
        100
      );
ST_Contains

ST_Contains(geometry A, geometry B)
如果第二个几何图形B完全包含在第一个几何图形A内,则返回TRUE
只支持geometry之间的判断

test=# select ST_Contains(ST_GeogFromText('MULTILINESTRING((118.7830931 32.0450039,118.7833968 32.0467468))'), ST_GeogFromText('MULTILINESTRING((118.7830931 32.0450039,118.7833968 32.0467468))'));

ERROR: syntax error at or near "ST_Contains" LINE 1: ST_Contains(ST_GeogFromText('MULTILINESTRING((118.7830931 32...

test=# select ST_Contains(ST_GeomFromText('MULTILINESTRING((118.7830931 32.0450039,118.7833968 32.0467468))',4326), ST_GeomFromText('MULTILINESTRING((118.7830931 32.0450039,118.7833968 32.0467468))',4326));
 st_contains 
-------------
 t
(1 行记录)
ST_Equals

ST_Equals(geometry A, geometry B)用于测试两个图形的空间相等性。

SELECT name, geom, ST_AsText(geom) FROM nyc_subway_stations WHERE name = 'Broad St';

SELECT name
FROM nyc_subway_stations
WHERE ST_Equals(geom, ST_GeomFromText('POINT(583571.905921312 4506714.34119218)',26918));
没有结果

SELECT ST_AsText('0101000020266900000EEBD4CF27CF2141BC17D69516315141')
POINT(583571.905921312 4506714.34119218)
SELECT ST_AsText('01010000202669000010EBD4CF27CF2141BA17D69516315141')
POINT(583571.905921312 4506714.34119218)

SELECT ST_Equals(ST_GeomFromText(ST_AsText('0101000020266900000EEBD4CF27CF2141BC17D69516315141'),4326),
ST_GeomFromText(ST_AsText('01010000202669000010EBD4CF27CF2141BA17D69516315141'),4326));

(true)

select st_distance(
	'0101000020266900000EEBD4CF27CF2141BC17D69516315141',
	'01010000202669000010EBD4CF27CF2141BA17D69516315141'
);

select ST_DWithin(
	'0101000020266900000EEBD4CF27CF2141BC17D69516315141',
	'01010000202669000010EBD4CF27CF2141BA17D69516315141',
	0.001
);

补充:
select 
	'0101000020266900000EEBD4CF27CF2141BC17D69516315141'::geography,
	'01010000202669000010EBD4CF27CF2141BA17D69516315141'::geography;
    报错
    
select 
	ST_SetSRID('0101000020266900000EEBD4CF27CF2141BC17D69516315141'::geometry, 4326),
	ST_SetSRID('01010000202669000010EBD4CF27CF2141BA17D69516315141'::geometry, 4326);
    
 select 
	ST_ASTEXT(ST_SetSRID('0101000020266900000EEBD4CF27CF2141BC17D69516315141'::geometry, 4326)::geography),
	ST_ASTEXT(ST_SetSRID('01010000202669000010EBD4CF27CF2141BA17D69516315141'::geometry, 4326));
    
 select 
	ST_distance(ST_SetSRID('0101000020266900000EEBD4CF27CF2141BC17D69516315141'::geometry, 4326)::geography,
	ST_SetSRID('01010000202669000010EBD4CF27CF2141BA17D69516315141'::geometry, 4326)::geography);
ST_Intersects

ST_Intersects(geometry A, geometry B)
如果两个图形有相同的空间部分,即如果它们的边界或内部相交,则为true。

SELECT name, boroname
FROM nyc_neighborhoods
WHERE ST_Intersects(geom, ST_GeomFromText('POINT(583571 4506714)', 26918));

select ST_Intersects(ST_GeomFromText('LINESTRING(118.8840931 32.0450039, 115.7840 30.0750,115 30, 116 30)', 4326), 
				  ST_GeomFromText('MultiPoint ((116 30),(115.78401 30.07501))', 4326))
 (true)
ST_Crosses

ST_Crosses(geometry A, geometry B)
对于multipoint/polygon、multipoint/linestring、linestring/linestring、linestring/polygon和linestring/multipolygon的比较,如果相交生成的几何图形的维度小于两个源几何图形的最大维度,且相交集位于两个源几何图形的内部,则ST_Crosses(geometry A, geometry B)将返回TRUE(其实就是判断两个几何图形是否交叉)

select ST_Crosses(ST_GeomFromText('LINESTRING(118.8840931 32.0450039, 115.7840 30.0750,115 30)', 4326),
	ST_GeomFromText('MultiPoint ((115.7840 30.0750),(118.8840 32.045))', 4326))
    
 (true)
 
 select ST_Crosses(ST_GeomFromText('LINESTRING(118.8840931 32.0450039, 115.7840 30.0750,115 30)', 4326), 
				  ST_GeomFromText('MultiPoint ((115 30),(118.8840 32.045))', 4326))
 (false)
 
 select ST_Crosses(ST_GeomFromText('LINESTRING(118.8840931 32.0450039, 115.7840 30.0750,115 30, 116 30)', 4326), 
				  ST_GeomFromText('MultiPoint ((115 30),(115.7840 30.0750))', 4326))
 (false)
ST_Touches

ST_Touches(geometry A, geometry B)
测试两个几何图形是否在它们的边界上接触,但在它们的内部不相交。

select ST_Touches(ST_GeomFromText('LINESTRING(118.8840931 32.0450039, 115.7840 30.0750,115 30)', 4326),
	ST_GeomFromText('MultiPoint ((115 30),(118.8840 32.045))', 4326))
    
    (true)
ST_Intersection

ST_Intersection(geometry A, geometry B)
函数返回两个参数共有的空间区域(或直线,或点)。如果参数不相交,该函数将返回一个空几何图形。

SELECT name, boroname,ST_ASText(geom),ST_Intersection(geom, ST_GeomFromText('POINT(583571 4506714)', 26918))
FROM nyc_neighborhoods
ST_Union

ST_Union(geometry, geometry)
接受两个几何图形参数并返回合并的并集

SELECT ST_Union(
  ST_Buffer('POINT(0 0)', 2),
  ST_Buffer('POINT(3 0)', 2));
注意点

对于geography类型,只有相关的少量空间函数:
ST_AsText(geography) returns text
ST_GeographyFromText(text) returns geography
ST_AsBinary(geography) returns bytea
ST_GeogFromWKB(bytea) returns geography
ST_AsSVG(geography) returns text
ST_AsGML(geography) returns text
ST_AsKML(geography) returns text
ST_AsGeoJson(geography) returns text
ST_Distance(geography, geography) returns double
ST_DWithin(geography, geography, float8) returns boolean
ST_Area(geography) returns double
ST_Length(geography) returns double
ST_Covers(geography, geography) returns boolean
ST_CoveredBy(geography, geography) returns boolean
ST_Intersects(geography, geography) returns boolean
ST_Buffer(geography, float8) returns geography[1]
ST_Intersection(geography, geography) returns geography[1]

常用场景

获取一个区域的道路或者基站数据

select * 
from dw_bts
where ST_Contains((select geom from gis_osm_boundary where local_name = '江宁区'), geom)

select *
from gis_osm_roads_free_1 
where ST_Contains((select geom from gis_osm_boundary where local_name = '江宁区'), geom);

获取一个点,道路,区域边界范围一定距离内的poi

select gid, geom as am
from gis_osm_pois_free_1 
where ST_Contains((select 
ST_Buffer(
 ST_GeomFromText('POINT(121.08679 31.44893)',4326)::geography, 10000)::geometry), geom);
 
 select gid, geom as am
from gis_osm_pois_free_1 
where ST_Contains((select 
  ST_Buffer(ST_Boundary(geom)::geography, 1000)::geometry from gis_osm_boundary where local_name = '江宁区'), geom)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值