PostGIS使用
PostgreSQL安装
参考文章:https://blog.csdn.net/duan9015/article/details/115896166
安装数据库
# 添加以下文件依赖:
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
# Import the repository signing key:
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
# Update the package lists:
sudo apt-get update
# Install the latest version of PostgreSQL.
# If you want a specific version, use 'postgresql-12' or similar instead of 'postgresql':
sudo apt-get -y install postgresql
开启数据库服务器
sudo pg_ctlcluster 13 main start
查看pg状态
sudo systemctl is-active postgresql
sudo systemctl is-enabled postgresql
sudo systemctl status postgresql
查看是否接受来自客户端的接受
sudo pg_isready
修改配置,默认监听IP
sudo vim /etc/postgresql/13/main/postgresql.conf
将下列语句去除注释,并改成*
listen_addresses = '*'
修改pg_hba.conf配置,允许远程连接
sudo vim /etc/postgresql/13/main/pg_hba.conf
在最后一行加上
host all all 0.0.0.0/0 md5
重启数据库
先查看数据库的服务
ls /usr/lib/systemd/system | grep postgresql
然后停止再重开
sudo systemctl stop postgresql.service
sudo systemctl start postgresql.service
修改linux系统postgres用户的密码
PostgreSQL会创建一个默认的linux用户postgres,修改该用户密码的方法如下:
该命令用来删除postgres用户的密码(即删除密码)
sudo passwd -d postgres
新增密码
sudo -u postgres passwd
#密码太低可能会被挖矿
新密码
pgsql用户添加密码(默认postgres)
su - postgres
psql
postgres=# \password postgres
#密码设为
新密码
安装pgAdmin4(可选)
pgAdmin4在Ubuntu源中不可用。我们需要从pgAdmin4 APT源安装。添加源公钥并创建源配置文件。
curl https://www.pgadmin.org/static/packages_pgadmin_org.pub | sudo apt-key add
sudo sh -c 'echo "deb https://ftp.postgresql.org/pub/pgadmin/pgadmin4/apt/$(lsb_release -cs) pgadmin4 main" > /etc/apt/sources.list.d/pgadmin4.list && apt update'
sudo apt install pgadmin4
安装web脚本,将系统配置为在web模式下运行,创建账户和密码
sudo /usr/pgadmin4/bin/setup-web.sh
就可以在以下网址打开了
http://127.0.0.1/pgadmin4
然后添加服务器,地址为服务器的地址,用户名是postgres,密码是之前自己设置的。
这里我为了操控方便,用的是win10上的pgAdmin4来远程操作数据库。
PostGIS安装
参考网址:http://postgis.net/install/
查看postgresql-13所支持的postgis
apt-cache search postgresql-13
然后安装postgis3版本的
apt-get install postgresql-13-postgis-3
启用PostGIS
使用psql或PgAdmin连接到数据库。运行以下SQL:
CREATE EXTENSION postgis;
查看是否安装了
SELECT postgis_full_version();
在数据库中查找SRID
SELECT srtext FROM spatial_ref_sys WHERE srid = 26918;
视图geometry_columns提供了数据库中所有空间数据表的描述信息
SELECT * FROM geometry_columns;
Nodejs操控数据库
参考网址:https://node-postgres.com/
PostGreSQL使用手册
创建空间表
create table beijingtest(id serial primary key,
name text not NULL,
geom geometry(LINESTRING,4326));
建立索引
CREATE INDEX beijingtest_geom_idx
ON beijingtest
USING GIST (geom);
查询SRID
SELECT * FROM geometry_columns;
插入数据
INSERT INTO beijingtest VALUES(8,'pl',ST_geomfromText('Linestring(116 39,115 38)',4326));
语句记录
SELECT * FROM public.beijingtest ORDER BY id DESC LIMIT 100;
select id,name,ST_AsText(geom) from beijingtest ORDER BY id DESC LIMIT 100;
select id,name,ST_AsText(geom) from beijingtest where id=261;
update beijingtest set name='TESTWFS1' where id=261;
truncate table beijingtest;
delete from beijingtest where id=1;
INSERT INTO beijingtest VALUES(1,'TESTWFS',ST_geomfromText('Linestring(115 39,116 40)',4326));
PostGIS学习教程
安装完Postgresql的时候可以选择安装postgis,或者安装完后单独安装
postgis的相关教程可以看这个博主的
加载了PostGIS空间扩展
CREATE EXTENSION postgis;
查看是否安装了
SELECT postgis_full_version();
在数据库中查找SRID
SELECT srtext FROM spatial_ref_sys WHERE srid = 26918;
视图geometry_columns提供了数据库中所有空间数据表的描述信息
SELECT * FROM geometry_columns;
空间函数
ST_AsText可以把geom类型转换成文本
SELECT ST_AsText(geom)
FROM geometries
WHERE name = 'Point';
点的空间函数
- ST_X(geometry) —— 返回X坐标
- ST_Y(geometry) —— 返回Y坐标
SELECT ST_X(geom), ST_Y(geom)
线段的空间函数
- ST_Length(geometry) —— 返回线串的长度
- ST_StartPoint(geometry) —— 将线串的第一个坐标作为点返回
- ST_EndPoint(geometry) —— 将线串的最后一个坐标作为点返回
- ST_NPoints(geometry) —— 返回线串的坐标数量
多边形的空间函数
- ST_Area(geometry) —— 返回多边形的面积
- ST_NRings(geometry) —— 返回多边形中环的数量(通常为1个,其他是孔)
- ST_ExteriorRing(geometry) —— 以线串的形式返回多边形最外面的环
- ST_InteriorRingN(geometry, n) —— 以线串形式返回指定的内部环
- ST_Perimeter(geometry) —— 返回所有环的长度
集合
- MultiPoint —— 点集合
- MultiLineString —— 线串集合
- MultiPolygon —— 多边形集合
- GeometryCollection —— 由任意几何图形(包括其他GeometryCollection)组成的异构集合
集合空间函数
- ST_NumGeometries(geometry) —— 返回集合中的组成部分的数量
- ST_GeometryN(geometry, n) —— 返回集合中指定的组成部分
- ST_Area(geometry) —— 返回集合中所有多边形组成部分的总面积
- ST_Length(geometry) —— 返回所有线段组成部分的总长度
几何图形的输入和输出
①Well-known text(WKT)
-
ST_GeomFromText(text, srid) —— 返回geometry
-
ST_AsText(geometry) —— 返回text
-
ST_AsEWKT(geometry) —— 返回text
②Well-known binary(WKB)
-
ST_GeomFromWKB(bytea) —— 返回geometry
-
ST_AsBinary(geometry) —— 返回bytea
-
ST_AsEWKB(geometry) —— 返回bytea
③Geographic Mark-up Language(GML)
-
ST_GeomFromGML(text) —— 返回geometry
-
ST_ASGML(geometry) —— 返回text
④Keyhole Mark-up Language(KML)
-
ST_GeomFromKML(text) —— 返回geometry
-
ST_ASKML(geometry) —— 返回text
-
ST_AsGeoJSON(geometry) —— 返回text
⑥Scalable Vector Graphics(SVG)
-
ST_AsSVG(geometry) —— 返回text
ST_GeomFromText()将文本转换成geometry
下面的语句可以进行类型转换
olddata::newtype
例子:
SELECT 'POINT(0 0)'::geometry;
包含指定SRID的图形转换:
SELECT 'SRID=4326;POINT(0 0)'::geometry;
空间关系
-
**ST_Equals(geometry A, geometry B)**用于测试两个图形的空间相等性
-
ST_Intersects(geometry A, geometry B)边界或内部相交返回True
-
**ST_Disjoint(geometry A, geometry B)**对立的方法,即没有重合的部分,则它们不相交,但not intersect更有效,因为可以使用空间索引
-
**ST_Crosses(geometry A, geometry B)**如果相交生成的几何图形的维度小于两个源几何图形的最大维度,且相交集位于两个源几何图形的内部,则返回真
-
**ST_Overlaps(geometry A, geometry B)**比较两个相同维度的几何图形,如果它们的结果集与两个源几何图形都不同但具有相同维度,则返回TRUE。
-
**ST_Touches()**测试两个几何图形是否在它们的边界上接触,但在它们的内部不相交。
-
如果第一个几何图形完全位于第二个几何图形内,则**ST_Within(geometry A, geometry B)**返回TRUE,ST_Within()测试的结果与ST_Contains()完全相反。
-
如果第二个几何图形完全包含在第一个几何图形内,则**ST_Contains(geometry A, geometry B)**返回TRUE。
-
**ST_Distance(geometry A, geometry B)**计算两个几何图形之间的最短距离,并将其作为浮点数返回。
-
ST_DWithin()测试两个几何图形之间的距离是否在某个范围之内
找到地铁站附近(10米内)的街道
SELECT name FROM nyc_streets WHERE ST_DWithin( geom, ST_GeomFromText('POINT(583571 4506714)',26918), 10 );
空间连接
JOIN…ON
strpos
空间索引
INDEX
USING GIST (geom);
&&纯索引搜索
ANALYZE命令要求PostgreSQL遍历该表并更新用于查询操作而估算的内部统计信息。
VACUUM清理回收表页面中因记录的更新或删除而留下的任何未使用的空间。
两个可以一起用
VACUUM ANALYZE nyc_census_blocks;
投影数据
**ST_Transform(geometry, srid)**函数就可以实现重投影
**ST_SRID(geometry)和ST_SetSRID(geometry,SRID)**查看和设置几何图形的空间参照标识符
定义包含在spatial_ref_sys表中。事实上,有两个定义。”well-known text”(WKT)定义在srtext列中,”proj.4″格式定义在proj4text列。srtext列由GeoServer、uDig和FME等外部程序使用;proj4text列由内部程序使用。
若要查看表的SRID,请查询数据库的geometry_columns视图表:
SELECT f_table_name AS name, srid
FROM geometry_columns;
**ST_Transform(geometry, srid)**转换坐标系
**ST_AsKML()**会变成地理坐标,因为所有的KML都是地理坐标,会进行自动转换s [si]
地理坐标
使用geography而不是geometry类型
SELECT ST_Distance(
ST_GeographyFromText('POINT(-118.4079 33.9434)'), -- Los Angeles (LAX)
ST_GeographyFromText('POINT(2.5559 49.0083)') -- Paris (CDG)
);
返回值单位为米
为了将geometry数据加载到geography表中,首先需要将geometry投影到EPSG:4326(经度-longitude/纬度-latitude),然后再将其转换为geography。
**ST_Transform(geometry, srid)**函数能将坐标转换为地理坐标,**Geography(geometry)**函数能将geometry转换为geography
CREATE TABLE nyc_subway_stations_geog AS
SELECT
Geography(ST_Transform(geom,4326)) AS geog,
name,
routes
FROM nyc_subway_stations;
建立索引的方式也一样,就是空间函数会少一点。
geography包含在表创建时直接指定表类型的功能。
geog GEOGRAPHY(Point)
并且在geography_columns视图中注册
转换成geometry
geog::geometry
**如果你的数据在地理范围上是紧凑的(包含在州、县或市内),请使用基于笛卡尔坐标的*geometry*类型,这样使你的数据有意义。有关可能的参考系统的选择,请参见http://spatialreference.org站点并输入您所在区域的名称。
**如果你需要测量在地理范围上是分散的数据集(覆盖世界大部分地区)的距离,请使用**geography**类型。**通过基于geography类型运行而节省的应用程序复杂性将抵消任何性能问题。同时转换为geometry可以抵消大多数功能限制。
几何图形创建函数
ST_Centroid计算质心
ST_PointOnSurface返回在多边形内的“质心”
**ST_Buffer(geometry, distance)**创建缓冲区,也支持负数的距离,在里面构建内接多边形
CREATE TABLE liberty_island_zone ASSELECT ST_Buffer(geom,500)::geometry(Polygon,26918) AS geomFROM nyc_census_blocksWHERE blkid = '360610001001001';
**ST_Intersection(geometry A, geometry B)**函数返回两个参数共有的空间区域(或直线,或点)
ST_Union(geometry A, geometry B)接受两个几何图形参数并返回合并的并集
有效性
ST_IsValid检测有效性
ST_IsValidReason(geometry)*
OpenJump工具可以修复无效图形
修复有效性
- ST_MakeValid函数,对于清晰但无效的数据来说,这个函数非常适用
- ST_Buffer函数
相等
ST_OrderingEquals精确相等
ST_Equals空间相等
供了等边界运算符 = ,这仅在边界框**(矩形)**上操作,确保几何图形占用相同的二维范围,但不一定占用相同的空间。
线性参考
ST_LineLocatePoint函数接受线串和点,并返回该点沿线串的线性参考比例。
ST_LineInterpolatePoint从线性参考比例得到相应的点。
线性参考可以来实现捕捉功能
维数扩展的9交集模型
ST_Relate有两个参数和三个参数的用法
最近邻域搜索
挺重要的,建议看一下网页
基于索引的KNN查询的语法在查询的ORDER BY子句中放置了一个特殊的”基于索引的距离运算符“,在本例中为”<->”。有两种基于索引的距离运算符:
- <-> —— 表示边界框中心之间的距离
- <#> —— 表示边界框边界之间的距离





