
本文共 10139 字,大约阅读时间需要 33 分钟。
1. 安装数据库
1.1 postgresql安装与配置
在centos 7下安装很简单
yum -y install postgresql-serverpostgresql-setup initdb
此外可以再安装一些额外的插件,比如:
yum -y install postgis
按照安装pgrouting。
进行一些配置,让postgresql可被远程连接登录。
进入/var/lib/pgsql/data/postgresql.conf,将第59行取消注释并更改为:listen_addresses = ‘*’,将第395行更改为log_line_prefix = '%t %u %d ’进入/var/lib/pgsql/data/pg_hba.conf,将最后的peer和ident改为trust
开启防火墙设置:
systemctl start firewalldfirewall-cmd --add-service=postgresql --permanent firewall-cmd --reload
然后启动服务:
systemctl start postgresql systemctl enable postgresql
默认用户名和数据库postgres,我们可以切换进postgres,然后新建用户名和数据库:
su - postgrespsql -c "alter user postgres with password 'password'"createuser test_usercreatedb test_db -O test_userexit
然后在本机就可以登录
psql -U test_user -d test_db
postgresql基础操作总结如下:
-h:指定连接的地址hostname -p指定连接的端口号 -d指定连接的数据库名称 -U指定连接的用户名 -W指定在执行时弹出密码输入提示1.2 创建postGis扩展
首先使用postgres账号登录postgres数据库:
psql -U postgres
切换数据库:
\c test_db
创建postgis扩展,并查看postgis的版本号(两种方法),并退出:
CREATE EXTENSION postgis;SELECT postgis_full_version();\dx\q
1.3 下载数据
可以下载免费的osm格式数据。
可以批量下载各个国家的osm和shp格式数据,可以参考链接 。这个数据并不包含行政边界,坐标WGS84。 我们这里下载geofabrik的数据,并解压:wget http://download.geofabrik.de/asia/china-latest-free.shp.zipunzip china-latest-free.shp.zip
1.4 导入数据
使用shp2psql命令行工具导入数据:
shp2pgsql -s 4326 -I "gis_osm_buildings_a_free_1" buildings_a | psql -h localhost -p 5432 -d test_db -U postgres shp2pgsql -s 4326 -I "gis_osm_places_a_free_1" places_a | psql -h localhost -p 5432 -d test_db -U postgres shp2pgsql -s 4326 -I "gis_osm_pois_free_1" pois | psql -h localhost -p 5432 -d test_db -U postgres shp2pgsql -s 4326 -I "gis_osm_traffic_free_1" traffic | psql -h localhost -p 5432 -d test_db -U postgres shp2pgsql -s 4326 -I "gis_osm_transport_a_free_1" transport_a | psql -h localhost -p 5432 -d test_db -U postgresshp2pgsql -s 4326 -I "gis_osm_railways_free_1 " railways | psql -h localhost -p 5432 -d test_db -U postgres shp2pgsql -s 4326 -I "gis_osm_landuse_a_free_1" landuse_a | psql -h localhost -p 5432 -d test_db -U postgres shp2pgsql -s 4326 -I "gis_osm_pofw_a_free_1" pofw_a | psql -h localhost -p 5432 -d test_db -U postgres shp2pgsql -s 4326 -I "gis_osm_roads_free_1" roads | psql -h localhost -p 5432 -d test_db -U postgres shp2pgsql -s 4326 -I "gis_osm_natural_a_free_1" natural_a | psql -h localhost -p 5432 -d test_db -U postgres shp2pgsql -s 4326 -I "gis_osm_water_a_free_1" water_a | psql -h localhost -p 5432 -d test_db -U postgres shp2pgsql -s 4326 -I "gis_osm_waterways_free_1" waterways | psql -h localhost -p 5432 -d test_db -U postgres shp2pgsql -s 4326 -I "gis_osm_places_a_free_1" places_a | psql -h localhost -p 5432 -d test_db -U postgres
shp2pgsql的参数(具体参数使用shp2pgsql --help进行查看)如下:
-s:指定空间参考系,PostGIS的参考系和EPSG代码是一样的,比如EPSG:4326表示WGS84地理坐标系 -I:指定在新建的关系表的空间对象的那一列建立空间索引 。双引号引起来的是Shapefile的文件名称(也可以加上扩展名.shp),再加上关系表的全名。shp2pgsql的输出是一个标准的SQL,然后Linux的管道操作符’|’将结果传入到psql中进行SQL的执行。2. postGis使用
2.1 数据库结构
导入数据如下图:



SELECT UpdateGeometrySRID(‘waterways’,’geom’,4326);
2.2 数据存储格式
在postGis中,几何形状数据类型为geometry。数据可以通过ST_GeometryFromText函数来生成,也可以通过tuple的方式来生成。文本是wkt(well known text)或者wkb(well known binary)类型的数据,在python中可以用shapely库来处理:
SELECT ST_AsText(ST_GeometryFromText('LINESTRING(0 0 0,1 0 0,1 1 2)'));
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_AsText(geom) FROM geometries;
这里面显示了常见几种几何图形(geometry)的用法:
一个点(POINT) 一条线(LINESTRING) 一个多边形(POLYGON) 一个内含空洞的多边形(POLYGON with a hole) 一个图形集合(COLLECTION) 单元素多几何图形(MultiPolygon、MultiPoint、……)PostGIS支持以多种格式进行几何图形的输入和输出:
①Well-known text(WKT)ST_GeomFromText(text, srid) —— 返回geometryST_AsText(geometry) —— 返回textST_AsEWKT(geometry) —— 返回text②Well-known binary(WKB)ST_GeomFromWKB(bytea) —— 返回geometryST_AsBinary(geometry) —— 返回byteaST_AsEWKB(geometry) —— 返回bytea③Geographic Mark-up Language(GML)ST_GeomFromGML(text) —— 返回geometryST_ASGML(geometry) —— 返回text④Keyhole Mark-up Language(KML)ST_GeomFromKML(text) —— 返回geometryST_ASKML(geometry) —— 返回text⑤GeoJsonST_AsGeoJSON(geometry) —— 返回text⑥Scalable Vector Graphics(SVG)ST_AsSVG(geometry) —— 返回text
以上函数最常见的用法是将几何图形的文本(text)表示形式转换为内部表示形式。以下SQL查询展示了一个WKB表示形式的示例(将二进制输出转换为ASCII格式以进行打印时,需要调用encode()):
SELECT encode(ST_AsBinary(ST_GeometryFromText('LINESTRING(0 0,1 0)')),'hex');
由于WKT和WKB是在SFSQL规范中定义的,因此它们不能处理3维或4维的几何图形。对于这些情况,PostGIS定义了Extended Well Known Text(EWKT)和Extended Well Known Binary(EWKB)格式以用于处理3维或4维的几何图形。
PostgreSQL包含一个简短形式的语法,允许数据从一种类型转换到另一种类型,即类型转换语法:
olddata::newtype
例如,将double类型转换为文本字符串类型:
SELECT 0.9::text;
以下SQL语句将一个WKT字符串转换成一个几何图形(geometry):
SELECT 'POINT(0 0)'::geometry;SELECT 'SRID=4326;POINT(0 0)'::geometry;
2.3 重要函数
2.3.1 通用类
ST_AsText(geometry) —— 返回几何图形的值
ST_GeometryType(geometry) —— 返回几何图形的类型 ST_NDims(geometry) —— 返回几何图形的维数 ST_SRID(geometry) —— 返回几何图形的空间参考标识码 ST_StartPoint(geometry) —— 返回几何图形的第一个点 ST_EndPoint(geometry) —— 返回几何图形的最后一个点 点: ST_X(geometry) —— 返回点的X坐标 ST_Y(geometry) —— 返回点的Y坐标 线: 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) —— 返回所有环的长度 集合: ST_NumGeometries(geometry) —— 返回集合中的组成部分的数量 ST_GeometryN(geometry, n) —— 返回集合中指定的组成部分 ST_Area(geometry) —— 返回集合中所有多边形组成部分的总面积 ST_Length(geometry) —— 返回所有线段组成部分的总长度注意在SQL中,使用"%"符号和LIKE运算符来告诉系统执行全局匹配。
对于经纬度,面积计算以平方米为单位。2.3.2 几何操作
ST_Equals(geometry A, geometry B)用于测试两个图形的空间相等性。
ST_Intersects、ST_Intersects、ST_Crosses和ST_Overlaps测试几何图形是否相交。 ST_Touches判断几何图形是否边界相交。 ST_Within()和ST_Contains()测试一个几何图形是否完全位于另一个几何图形内。 ST_Distance(geometry A, geometry B)计算两个几何图形之间的最短距离,并将其作为浮点数返回。 ST_DWithin测试两个几何图形之间的距离是否在某个范围之内。 ST_Centroid(geometry)返回大约位于输入参数的质心上的点。这种简单的计算速度非常快,但有时并不可取,因为返回点不一定在要素本身上。如果输入的几何图形具有凸性(假设字母’C’),则返回的质心可能不在图形的内部。 ST_PointOnSurface(geometry)返回保证在输入多边形内的点。从计算上讲,它比centroid操作代价要大得多。



2.4 空间索引
索引通过将数据组织到搜索树中来加快搜索速度,搜索树可以快速遍历以查找特定记录。空间索引是PostGIS的最大价值之一。在前面的示例中,构建空间连接需要对整个表进行相互比较。这样做的代价很高:连接两个包含10000条记录的表(每个表都没有索引)将需要进行100000000次比较;如果使用空间索引,则比较次数可能低至20000次。用下面的语句查看索引信息:


2.5 空间投影
地球不是平的,也没有简单的方法把它放在一张平面纸地图上(或电脑屏幕上),所以人们想出了各种巧妙的解决方案(投影)。每种投影方案都有优点和缺点,一些投影保留面积特征;一些投影保留角度特征,如墨卡托投影(Mercator);一些投影试图找到一个很好的中间混合状态,在几个参数上只有很小的失真。所有投影的共同之处在于,它们将(地球)转换为平面笛卡尔坐标系,选择哪种投影取决于你将如何使用数据(需要哪些数据特征,面积?角度?或者其他)。
PostGIS包含更改数据投影(重投影)的功能,即使用ST_Transform(geometry, srid)函数就可以实现重投影。另外,为了查看和设置几何图形的空间参照标识符,PostGIS提供了ST_SRID(geometry)和ST_SetSRID(geometry,SRID)函数。我们可以使用ST_SRID(geometry)函数确认数据的SRID:SELECT ST_SRID(geom) FROM nyc_streets LIMIT 1;
返回26919,其定义包含在spatial_ref_sys表中。事实上,有两个定义。“well-known text”(WKT)定义在srtext列中,"proj.4"格式定义在proj4text列。
2.6 地理坐标
与Mercator(墨卡托)、UTM(通用横轴墨卡托)、Stateplane中的坐标不同,地理坐标不是笛卡尔平面坐标(Cartesian coordinates)。地理坐标并不表示平面上与原点的线性距离,相反,这些球坐标描述了地球上的角坐标。在球坐标中,点由该点与参考子午线(经度)的旋转角度和该点与赤道的角度(纬度)指定。

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] 用于创建含有geography列的新表的SQL与用于创建geography表的SQL非常相似。但是,geography包含在表创建时直接指定表类型的功能。例如:CREATE TABLE airports ( code VARCHAR(3), geog GEOGRAPHY(Point));INSERT INTO airports VALUES ('LAX', 'POINT(-118.4079 33.9434)');INSERT INTO airports VALUES ('CDG', 'POINT(2.5559 49.0083)');INSERT INTO airports VALUES ('KEF', 'POINT(-22.6056 63.9850)');
如果你的数据在地理范围上是紧凑的(包含在州、县或市内),请使用基于笛卡尔坐标的geometry类型,这样使你的数据有意义。有关可能的参考系统的选择,请参见http://spatialreference.org站点并输入您所在区域的名称。
\如果你需要测量在地理范围上是分散的数据集(覆盖世界大部分地区)的距离,请使用geography类型。通过基于geography类型运行而节省的应用程序复杂性将抵消任何性能问题。同时转换为geometry可以抵消大多数功能限制。