ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] > [home](https://postgis.net/documentation/getting_started/) > [官方中文教程](https://postgis.net/workshops/zh_Hans/postgis-intro/) ## postgis PostGIS是一个开源的空间数据存储和查询库,它可以与PostgreSQL数据库一起使用。PostGIS允许你将地理空间数据存储在数据库中,并提供了一系列功能强大的函数和操作符,以便对这些数据进行查询、分析和处理。 使用PostGIS,你可以存储各种类型的地理空间数据,如点、线、面、多边形等,并支持对这些数据进行距离计算、缓冲区分析、空间关系查询等操作。同时,PostGIS还支持各种标准和格式,如OGC Simple Features for SQL,GeoJSON,KML等。 PostGIS已经成为了许多GIS应用程序和Web GIS系统的核心组件之一,它为地理空间数据的管理和分析提供了灵活而强大的工具。 目录列表 ![](https://img.kancloud.cn/88/a1/88a12c64cdf2c382b2518df3e48f0d12_232x462.png) ## 下载 [下载地址](https://postgis.net/documentation/getting_started/) **win** https://download.osgeo.org/postgis/windows/ 或通过 ![](https://img.kancloud.cn/0b/04/0b043b29d5e39fe8c35676783e274062_617x424.png) RedHat 系列 ``` $ sudo yum install postgis33_15 ``` ## 快速入门 ### 安装并确认 在需要用到 psotgis 的数据库中执行 `create extension postgis` 才能使用.不同数据库此sql需要重新执行 ``` > CREATE EXTENSION postgis; //不报错就说明安装成功 > SELECT PostGIS_Full_Version(); .// 查看版本 POSTGIS="3.3.2 3.3.2" [EXTENSION] PGSQL="150" GEOS="3.11.1-CAPI-1.17.1" PROJ="7.2.1" LIBXML="2.9.9" LIBJSON="0.12" LIBPROTOBUF="1.2.1" WAGYU="0.5.0 (Internal)" > SELECT * FROM pg_available_extensions WHERE name = 'postgis'; / 另一个查看版本 name | default_version | installed_version | comment ---------+-----------------+-------------------+------------------------------------------------------------ postgis | 3.3.2 | | PostGIS geometry and geography spatial types and functions ``` ## 空间数据库的操作 1. 创建空间数据库 ``` CREATE TABLE geometries (name varchar, geom geometry); INSERT INTO geometries VALUES ('Point', 'POINT(0 0)'), ('Linestring', 'LINESTRING(0 0, 1 1, 2 1, 2 2)'), ('Polygon', 'POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'), ('PolygonWithHole', 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 1 2, 2 2, 2 1, 1 1))'), ('Collection', 'GEOMETRYCOLLECTION(POINT(2 0),POLYGON((0 0, 1 0, 1 1, 0 1, 0 0)))'); ``` ### 查询空间点 ``` > SELECT name, ST_GeometryType(geom), ST_NDims(geom), ST_SRID(geom) FROM geometries; name | st_geometrytype | st_ndims | st_srid -----------------+-----------------------+----------+--------- Point | ST_Point | 2 | 0 Polygon | ST_Polygon | 2 | 0 PolygonWithHole | ST_Polygon | 2 | 0 Collection | ST_GeometryCollection | 2 | 0 Linestring | ST_LineString | 2 | 0 ``` - ST_GeometryType 返回集合类型,如点,线,面等 - ST_NDims 返回维度,如点,线,对变形,返回2,球,立方体返回3,更高维度则返回相应的值 - ST_SRID(geometry) 函数用于获得传入几何图形对象的空间参考标识符 ``` > SELECT ST_AsText(geom) FROM geometries WHERE name = 'Point'; POINT(0 0) > SELECT ST_X(geom), ST_Y(geom) FROM geometries WHERE name = 'Point'; st_x | st_y ------+------ 0 | 0 ``` ### 查询面空间 ``` > SELECT ST_AsText(geom) FROM geometries WHERE name = 'Linestring'; st_astext ----------------------------- LINESTRING(0 0,1 1,2 1,2 2) ``` ``` > SELECT ST_Length(geom) FROM geometries WHERE name = 'Linestring'; st_length ------------------- 3.414213562373095 ``` * **ST_Length(geometry)** 计算线长 * **ST_StartPoint(geometry)** 以点的形式返回第一个坐标 * **ST_EndPoint(geometry)** 以点的形式返回最后一个坐标 * **ST_NPoints(geometry)** 返回linestring中坐标的个数 ### 查询多边形 ``` > SELECT ST_AsText(geom) FROM geometries WHERE name LIKE 'Polygon%'; st_astext ---------------------------------------------------------- POLYGON((0 0,1 0,1 1,0 1,0 0)) POLYGON((0 0,10 0,10 10,0 10,0 0),(1 1,1 2,2 2,2 1,1 1)) ``` * **ST_Area(geometry)** 返回多边形的面积 * **ST_NRings(geometry)** 返回环的数量(通常为1,如果有孔则更多) * **ST_ExteriorRing(geometry)** 用于提取多边形(Polygon)的外环(Exterior Ring) * **ST_InteriorRingN(geometry,n)** 用于提取多边形(Polygon)的内环(Interior Ring * **ST_Perimeter(geometry)** 用于计算给定几何对象的周长 ### 查询集合 ``` > SELECT name, ST_AsText(geom) FROM geometries WHERE name = 'Collection'; name | st_astext ------------+--------------------------------------------------------------- Collection | GEOMETRYCOLLECTION(POINT(2 0),POLYGON((0 0,1 0,1 1,0 1,0 0))) ``` * **ST_NumGeometries(geometry)** 返回几何由几个部门组成 * **ST_GeometryN(geometry,n)** 返回指定第n个对象的几何 * **ST_Area(geometry)** 计算总面积 * **ST_Length(geometry)** 返回所有线的总长 ### 经纬度 **ST_Distance(geometry, geometry)** 计算两个点的距离 **ST_DistanceSphere(geometry, geometry)** 计算两个点的距离,但是是考虑地球曲率,性能较差,如果位置相近,则推荐使用 ST_Distance --- 例如,这里是洛杉矶和巴黎的坐标。 洛杉矶:POINT(-118.4079 33.9434) 巴黎:POINT(2.3490 48.8533) ``` > SELECT ST_Distance( 'SRID=4326;POINT(-118.4079 33.9434)'::geometry, -- 洛杉矶 'SRID=4326;POINT(2.5559 49.0083)'::geometry -- 巴黎 ); 121.898285970107 > SELECT ST_Distance( 'SRID=4326;POINT(-118.4079 33.9434)'::geography, -- 洛杉矶 'SRID=4326;POINT(2.5559 49.0083)'::geography -- 巴黎 ); 9124665.27317673 ``` > 如果对点使用 geometry时,计算的举例是几何点的举例,没有实际意义,应该使用 geography 指定点为地理坐标点 > 返回的 9124665.27317673 单位是米 **示例1: 离我最近的10家店铺** ``` CREATE TABLE shop ( code VARCHAR(3), geog GEOGRAPHY(Point) --经纬度 ); INSERT INTO shop VALUES ('LAX', 'POINT(-118.4079 33.9434)'); INSERT INTO shop VALUES ('CDG', 'POINT(2.5559 49.0083)'); INSERT INTO shop VALUES ('KEF', 'POINT(-22.6056 63.9850)'); ``` 查看距离 `120.153576, 30.287459` 最近的10家店铺 ``` > SELECT code, ST_Distance(geog, ST_MakePoint(120.153576, 30.287459)) AS distance FROM shop ORDER BY distance ASC // 可以直接根据 别名值进行排序 LIMIT 10; > SELECT code, ST_Distance(geog, ST_MakePoint(120.153576, 30.287459)) AS distance FROM shop ORDER BY geog <-> ST_SetSRID(ST_MakePoint(120.153576, 30.287459), 4326) -- 使用 "<->" 运算符按照几何对象间的距离排序,性能更好 LIMIT 10; code | distance ------+------------------- SH | 164034.83554803 KEF | 9057126.39178544 CDG | 9272472.78234009 LAX | 10615294.90430514 ``` > 经过检验,上海到杭州的实际记录为164.03 公里,与 SH的输出结果相同 > `<->` 值距离排序 > 在处理距离排序时,使用 "<->" 运算符的性能往往更好。因为它利用了 PostgreSQL 的索引机制,可以通过 GiST 空间索引加速查询。而直接使用别名进行排序则需要对整个结果集进行排序,性能相对较低。 **示例2: 离我最近的10家店铺,字段采用小数点字段,二非地理字段** ``` CREATE TABLE shop ( code VARCHAR(3), longitude numeric, latitude numeric ); INSERT INTO shop1 VALUES ('SH', '121.472644', '31.231706'); INSERT INTO shop1 VALUES ('DD', '2.5559', '49.0083'); ``` 查看距离 `120.153576, 30.287459` 最近的10家店铺 ``` > EXPLAIN SELECT code,longitude,latitude, ST_Distance(ST_MakePoint(longitude,latitude)::geography, ST_MakePoint(120.153576, 30.287459)) AS distance FROM shop1 ORDER BY ST_MakePoint(longitude,latitude)::geography <-> ST_SetSRID(ST_MakePoint(120.153576, 30.287459), 4326) LIMIT 10; code longitude latitude distance SH 121.472644 31.231706 164034.83554803 DD 2.5559 49.0083 9272472.78234009 ```