admin 管理员组

文章数量: 1184232


2024年4月14日发(作者:distinctiong)

PostGIS开启开源空间数据库的未来

1986年,加州大学伯克利分校的Michael Stonebraker教授领导了Postgres的项目,

它是PostgreSQL的前身。随后出现了PostGIS,PostGIS是对象-关系型数据库系统

PostgreSQL的一个扩展,它的出现让人们开始重视基于数据库管理系统的空间扩展方式,

而且使PostGIS有望成为今后管理空间数据的主流技术。

由于空间数据具有空间位置、非结构化、空间关系、分类编码、海量数据等特征,一

般的商用数据库管理系统难以满足要求。

为了提高数据库管理系统(DBMS)对空间数据的管理能力,国内外先后出现过:文件

与关系数据库混合管理系统、全关系型空间数据库管理系统、关系型数据库+空间数据引

擎、扩展对象关系型数据库管理系统,以及面向对象空间数据库管理系统等多种解决方案。

目前,国内外较为流行的主要集中在“关系型数据库+空间数据引擎”、“扩展对象关系

型数据库”两方面。

“关系型数据库+空间数据引擎”通常是近年来由GIS厂商研发的一种中间件解决方

案。用户将自己的空间数据交给独立与数据库之外的空间数据引擎,有空间数据引擎来组

织空间数据在关系型数据库种的存储;当用户需要访问数据的时候,再通知空间数据引擎,

有引擎从关系型数据库中取出数据,并转化为客户可以使用的方式。

因此,关系型数据库仅仅是存放空间数据的容器,而空间数据引擎则是空间数据进出

该容器的转换通道。这类系统的典型代表有ESRI的ArcSDE和MapInfo的SpatialWare。

其优点是,访问速度快,支持通用的关系数据库管理系统,空间数据按BLOB存取,可跨

数据库平台,与特定GIS平台结合紧密,应用灵活。其缺点主要表现为,空间操作和处理

无法在数据库内核中实现,数据模型较为复杂,扩展SQL比较困难,不易实现数据共享与

互操作。

扩展对象关系型数据库管理系统是由数据库厂商研发的管理空间数据一种解决方案。

由于关系型数据库难以管理非结构化数据(也包括空间数据),数据库厂商借鉴面向对象技

术,发展了对象关系型数据库管理系统。

此系统支持抽象的数据类型(ADT)及其相关操作的定义;用户利用这种能力可以增加

空间数据类型及相关函数,从而将空间数据类型与函数就从中间件(空间数据引擎)转移

到了数据库管理系统中,客户也不必采用空间数据引擎的专用接口进行编程,而是使用增

加了的空间数据类型和函数的标准扩展型SQL语言来操作空间数据。

这类支持空间扩展的产品有Oracle的Oracle Spatial, IBM的DB2 Spatial Extender,

Informix 的Spatial DataBlade。其优点是,空间数据的管理与通用数据库系统融为一体,

空间数据按对象存取,可在数据库内核中实现空间操作和处理,扩展SQL比较方便,较易

实现数据共享与互操作。其缺点主要表现为,实现难度大,压缩数据比较困难,目前的功

能和性能与第一类系统尚存在差距。

目前开源空间信息软件领域最性能优秀的数据库软件当属PostgreSQL数据库,而构

建在其上的空间对象扩展模块PostGIS则使得其成为一个真正的大型空间数据库。

缘起PostgrSQL

1986年,加州大学伯克利分校的Michael Stonebraker教授领导了Postgres的项目,

它是PostgreSQL的前身。这个项目的成果非常显著,在现代数据库的许多方面都作出了

大量的贡献,如在面向对象的数据库、部分索引技术、规则、过程和数据库扩展方面都取

得了显著的成果。同时,Stonebraker将PostgreSQL纳入到BSD版权体系中,使得

PostgreSQL在各种科研机构和一些公共服务组织得到了广泛的应用。

在PostgreSQL中已经定义了一些基本的集合实体类型,这些类型包括:点(POINT)、

线(LINE)、线段(LSEG)、方形(BOX)、多边形(POLYGON)和圆(CIRCLE)等;另外,

PostgreSQL定义了一系列的函数和操作符来实现几何类型的操作和运算;同时,

PostgreSQL引入空间数据索引R-tree。

尽管在PostgreSQL提供了上述几项支持空间数据的特性,但其提供的空间特性很难

达到GIS的要求,主要表现在:缺乏复杂的空间类型;没有提供空间分析;没有提供投影变换

功能。为了使得PostgreSQL更好的提供空间信息服务,PostGIS应运而生。

PostGIS简介

PostGIS是对象关系型数据库系统PostgreSQL的一个扩展,PostGIS提供如下空间

信息服务功能:空间对象、空间索引、空间操作函数和空间操作符。同时,PostGIS遵循

OpenGIS的规范。

PostGIS的版权被纳入到GNU的GPL中,也就是说任何人可以自由得到PostGIS的

源码并对其做研究和改进。正是由于这一点,PostGIS得到了迅速的发展,越来越多的爱

好者和研究机构参与到PostGIS的应用开发和完善当中。

PostGIS发展历程

PostGIS是由Refractions Research Inc开发的,Refractions是一家GIS和数据库

咨询公司,Refraction公司最初是在PostgreSQL的基础上研究空间数据库的实现,由于

PostgreSQL所提供的空间数据类型和功能远远不能满足GIS的需求,研究工作经常陷入

到进退维谷的境地,最终的结果往往是耗费了大量的人力物力,而产品却极其复杂并且性

能低下。这些原因直接或间接促成PostGIS项目的实施。

PostGIS的实施也不是一帆风顺,直到PostgreSQL 7.1发布之后,PostGIS的实现才

变为可能,主要原因是7.1版本之前PostgreSQL支持的记录大小最大为8Kb,从7.1之

后,PostgreSQL将这一限制摈弃。即使采用二进制方式存储,空间数据对象也往往会经

常超过8Kb,如果这个限制存在的话,空间数据的存储就无从谈起。

伴随着这一限制的消除,PostGIS的研究和开发也随即在2001年的4月展开,并于

2001年的5月发布了PostGIS的第一版(PostGIS V0.1)。在PostGIS的第一版中,主要

包括空间数据库、采用标准表示方式的空间数据对象、支持快速查询的空间索引和一些简

单的分析函数(如area和length等)。PostGIS V0.1中支持的空间数据对象类型包括:点、

线、多边形、几何对象类型,以及多点、多线、多多边形的几何对象类型。

2001年5月发布的PostGIS V0.2增加了对于Windows平台下二进制表示的支持,

同时为新用户提供帮助文档。不过,用户反馈PostGIS的函数命名没有遵循OpenGIS规

范。

2001年7月PostGIS V0.5发布,PostGIS增加了OpenGIS现有的所有功能性函数

并在函数的命名上与其保持一致。增加了24个OpenGIS存取函数,同时删除了与这些函

数功能等价的不标准的原有函数。

伴随着来自不列颠哥伦比亚省政府的资金支持,对于在球体表面的长度运算支持也加

入到0.5版中。同期,Refractions公司将British Columbia省的数字道路地图集移植到

PostGIS中,同时使用数据库的模式和数据转换功能为地图集客户提供支持(急救车派遣、

紧急事物响应,以及其他市政事物等)。

PostGIS V0.5之所以重要,还有一个原因就是Minnesota大学的Mapserver的发布。

Minnesota大学的Mapserver是一个开源的互联网地图发布引擎,就像ESRI公司的

ArcIMS系统,Mapserver同时增加了对于PostGIS的支持。

在Mapserver中,提供了一个Web驱动的接口,这个接口用于检查数据库中数据的

空间特征。在PostGIS中,PostGIS为了使得Mapserver能够更好的提供服务,提供了一

个易于读写的数据源,这个数据源将会在网络事务繁忙的时候发挥其效用。比如,如果用

标准的GIS文件作为数据源,如果有两个用户并发的对同一文件进行写入操作,这样将会

不可避免的导致操作冲突,而利用PostGIS就能够很好的解决这个缺陷,同时确保数据的

完整性。

2001年9月,PostGIS V0.6发布,PostGIS V0.6提供了完整的OpenGIS支持,加

入了标准的元数据表,并且提供了对于空间参照系统标识的支持。另外还加入了OpenGIS

支持的12个功能函数,同时对于Mapserver的支持得到了进一步的增强。

2002年2月,PostgreSQL V7.2发布,在7.2版中,GIST索引的API函数作了一点

改进。由于这些API函数同样应用于PostGIS中,这给PostGIS V0.6的应用带来了麻烦,

促使PostGIS必须作出改进适应PostgreSQL的变化。2002年PostGIS V0.7发布,在0.7

版中,提供了新的对于GIST的API函数支持,同时在这一版中,提供了对于坐标变换的

支持。

从2002年到现在,PostGIS又陆续发布了一系列的新版本,这些PostGIS产品在继

承PostGIS产品原有优点的同时,又针对PostGIS本身存在的问题和不足进行了进一步的

改进。到现在为止,PostGIS的最新版本是PostGIS V1.1.4。PostGIS V1.1.4主要改进的

地方包括:⑴提供了对于将要发布的PostgreSQL V8.2的支持;⑵修复了函数collect中存

在的bug;⑶在MakeBox2d和MakeBox3d中增加了对SRID的匹配检查;⑷提高了

pgsql2shp的运行并发性;⑸进一步改进了对于Java的支持。

PostGIS特性

PostGIS支持所有的空间数据类型,这些类型包括:点(POINT)、线(LINESTRING)、

多边形(POLYGON)、多点(MULTIPOINT)、多线(MULTILINESTRING)、多多边形

(MULTIPOLYGON)和集合对象集(GEOMETRYCOLLECTION)等。PostGIS支持所有

的对象表达方法,比如WKT和WKB。

PostGIS支持所有的数据存取和构造方法,如GeomFromText()、AsBinary(),以及

GeometryN()等。

PostGIS提供简单的空间分析函数(如Area和Length)同时也提供其他一些具有复

杂分析功能的函数,比如Distance。

PostGIS提供了对于元数据的支持,如GEOMETRY_COLUMNS和SPATIAL_REF_SYS,

同时,PostGIS也提供了相应的支持函数,如AddGeometryColumn和

DropGeometryColumn。

PostGIS提供了一系列的二元谓词(如Contains、Within、Overlaps和Touches)

用于检测空间对象之间的空间关系,同时返回布尔值来表征对象之间符合这个关系。

PostGIS提供了空间操作符(如Union和Difference)用于空间数据操作。比如,

Union操作符融合多边形之间的边界。两个交迭的多边形通过Union运算就会形成一个新

的多边形,这个新的多边形的边界为两个多边形中最大边界。

PostGIS还提供以下功能:

数据库坐标变换

数据库中的几何类型可以通过Transform函数从一种投影系变换到另一种投影系中。

在OpenGIS中的几何类型都将SRID作为自身结构的一部分,但不知什么原因,在

OpenGIS的SFSQL规范中,并没有引入Transform。

球体长度运算

存储在普通地理坐标系中的集合类型如果不进行坐标变换是无法进行程度运算的,

OpenGIS所提供的坐标变换使得积累类型的程度计算变成可能。

三维的几何类型

SFSQL规范只是针对二维集合类型。OpenGIS提供了对三维集合类型的支持,具体

是利用输入的集合类型维数来决定输出的表现方式。例如,即便所有几何对象内部都以三

维形式存储,纯粹的二维交叉点通常还是以二维的形式返回。此外,还提供几何对象在不

同维度间转换的功能。

空间聚集函数

在数据库中,聚集函数是一个执行某一属性列所有数据操作的函数。比如Sum和

Average,Sum是求某一关系属性列的数据总和,Average则是求取某一关系属性列的数

据平均值。与此对应,空间聚集函数也是执行相同的操作,不过操作的对象是空间数据。

例如聚集函数Extent返回一系列要素中的最大的包裹矩形框,如“SELECT

EXTENT(GEOM) FROM ROADS”这条SQL语句的执行结果是返回ROADS这个数据表

中所有的包裹矩形框。

栅格数据类型

PostGIS通过一种新的数据类型片,提供对于大的栅格数据对象的存储。片由以下几

个部分组成:包裹矩形框、SRID、类型和一个字节序列。通过将片的大小控制在数据库页值

(32×32)以下,使得快速的随即访问变成可能。一般大的图片也是通过将其切成32×32

像素的片然后再存储在数据库中的。

PostGIS发展展望

目前,由于“关系型数据库+空间数据引擎”的技术方案访问迅速、与GIS联系紧密

的优点,在应用中占有一定的优势,但空间数据引擎独立于数据库内核,难以充分利用关

系型数据库中各种成熟的数据管理、访问技术,成为进一步发展的致命弱点。另外,难以

支持扩展SQL,不易实现数据共享与互操作等问题也逐渐暴露出来。

尽管面向对象空间数据库管理系统最适应于空间数据的表达和管理,不仅支持变长记

录,而且支持对象的嵌套、信息的继承与聚集。有关面向对象数据库管理系统的研究已有十

多年了,由于缺乏良好的数据基础,在访问速度尚未有重大突破,难以发展成熟,据估计

在较长一段时间内面向对象数据库管理系统都不会替代对象关系型数据库管理系统。

扩展对象关系型数据库管理系统无疑将成为以后的发展方向。尽管目前

PostGIS/PostgreSQL和Spatial Oracle的性能与ArcSDE仍有一定的差距,但是随着数

据库厂商对空间数据管理市场的不断重视、结构化数据管理方式与空间数据管理方式的进

一步融合、数据压缩传输技术的不断提高,基于数据库管理系统的空间扩展方式将会不断

的完善,成为今后管理空间数据的主流技术。而多数GIS厂商则应将精力集中到空间分析、

空间模型等方面,从而形成较好的社会分工结构。

目前,软件开源已经成为IT界的一种发展趋势,越来越多的软件加入到开源系统中。

PostGIS不论在功能还是扩展性方面都不落后于商业GIS平台的空间数据库,而且由于其

源代码的公开性,更加容易吸引广大爱好者参与到PostGIS的开发中,不断完善现有的功

能同时进一步扩展新的特性,相信PostGIS的发展前景将会非常美好。

图 大象是Postgre SQL的Logo,地球暗喻地理空间信息,

此Logo图表示基于PG数据库玩转地球

PostgreSQL安装及地理空间数据库实现

1、 PostgreSQL简介

PostgreSQL是基于加州大学伯克利分校计算机系写的 POSTGRES(Version 4.2 )

软件包开发的对象关系型数据库管理系统(ORDBMS),是开源的,发布在 BSD许可下 。

经过二十几年的发展(起始与1986年), PostgreSQL 是世界上可以获得的最先进的开

放源码的数据库系统, 它提供了多版本并行控制,支持几乎所有 SQL 构件(包括子查询,

事务和用户定 义类型和函数), 并且可以获得非常广阔范围的(开发)语言绑定 (包括 C,

C++,Java,perl,tcl,和 python),目前最新的版本是 PostgreSQL8.3.x。

PostgreSQL 使用一种客户端/服务器的模式,即一次 PostgreSQL 会话在,需要执

行数据库操作的用户的客户端(前端)应用和数据库服务器程序(postmaster)之间完成。

这跟典型的客户端/服务器应用(C/S应用)一样,这些客户端和服务器可以在不同的主机

上,它们通过 TCP/IP 网络联接通讯。

两个图形界面工具:

pgAdmin III : 图形界面形式的管理工具

PhpPgAdmin :Web-based PostgreSQL 管理工具

2、 安装( windons环境 )

下载 PostgreSQL安装程序,这里8.3.0版或其他。

解压文件后,双击安装程序即可。

安装过程大概会遇到: Secongdary Logon服务没有运行 的问题。

在系统服务里,找到 Secongdary Logon服务,启动之,即可。

这样,完成之后, pgAdmin III 同时也会被安装。

3、 使用

对于不使用命令进行操作的朋友来说,图形用户界面是直观方便、容易上手的,其主

窗口如下图:

4、 PostGIS概述

PostGIS是对象关系型数据库系统PostgreSQL的一个扩展,PostGIS提供如下空间

信息服务功能:空间对象、空间索引、空间操作函数和空间操作符。同时,PostGIS遵循

OpenGIS的规范。

PostGIS是在 “关系型数据库+空间数据引擎”的大背景下诞生的。因此, PostGIS

之于 PostgreSQL,就像ArcSDE之于ArcGIS, Oracle's Spatial 之于Oracle。

PostGIS的版权被纳入到GNU的GPL中,也就是说任何人可以自由得到PostGIS的

源码并对其做研究和改进。正是由于这一点,PostGIS得到了迅速的发展,越来越多的爱

好者和研究机构参与到PostGIS的应用开发和完善当中。

5、数据库实现

实现步骤如下:

a.以系统提供的“PostGIS”数据库为母板创建一个数据库,取名为mychina;

b.把预先准备好的数据用命令导入到mychina数据库,命令:shp2pgsql

-c C: china mychina|psql -d mychina。

上面命令中china是存储数据的关系表。另外,除了用户定义的数据表之

外,PostGIS还存在两个系统表,分别是SPATIAL_REF_SYS(空间参考表格)和

GEOMETRY_COLUMNS(几何体属性列),用于存储空间数据库使用的坐标系统数字ID

和文本描述。

PostgreSQL8.4安装问题及解决

PostgreSQL是开源数据库系统。其8.4.1版本的下载地址

系统安装过程中会遇到几个问题:

一、语言

因PostgreSql未提供简体中文支持,简体中文操作系统用户在选择语言时可以选择

Lang_C,不要留着默认选项。否则安装过程中不能初始化数据库。当然数据库初始化可以

在之后手工进行。方法如下:

cmd

cd "Program FilesPostgreSQL8.4bin"

initdb -D "c:Program FilesPostgreSQL8.4data" -E UTF8 --locale=C

二、用户

如果系统用户不是administrator,或者不是postgres上面的指令可能会报错。称

XXX角色不存在。那就创建用户和角色。方法如下:

runas /user:postgres cmd ---!以postgres用户登录,系统安装时会自动创建

该用户。

cd "Program FilesPostgreSQL8.4bin"

createuser -d -e -i -l -P -r myusername ---!把myusername换成您的登录名。

三、密码

如果重复安装时忘记上次安装的密码,记住卸载后清空系统临时文件夹%temp%,密

码就能清楚。

四、用户无法登录

那么打开data文件夹下的pg_。找到下面一行

# IPv4 local connections:

host all all 127.0.0.1/32 md5

改为

# IPv4 local connections:

host all all 127.0.0.1/32 trust

PostgreSQL+PostGIS的使用

一、 PostgreSQL与PostGIS的关系

PostgreSQL 是世界上技术最先进的开源数据库,其前身是1977年一个源于

Berkeley名为Ingres的非关系型数据库,其项目领导人为Michael Stonebraker教授。

1982年该教授商业化了Ingres;1985年,Michael Stonebraker教授回到Berkeley,

开始对新的数据库设计进行研究,并于次年在美国防务高级研究项目局(DARPA)、陆军

研究办公室 (ARO)、国家科学基金(NSF)以及ESL, Inc等机构的赞助下启动了Postgres

(Post-Ingres)项目。

Postgres 在1987年形成第一个Demo,1989年发布第一个版本,直到1993年的

4.2版本,由于外部用户过多,做技术支持和维护源代码的时间影响到了对数 据库的研究,

因此Berkeley中止了该项目。在此期间,Postgres项目就已经被使用在了一些GIS系统

中。

Postgres项目并未就此消亡,在1994年两个Berkeley的研究生向Postgres中加入

了SQL语言解释器,将之改名为Postgre95并发布到了互联网 上。经过一些黑客的修改,

1996年Postgres95再次更名为PostgreSQL,并采用BSD许可证发布了第一个开源版本。

经过多年发 展,PostgreSQL已经发展成为一个技术非常先进的开源数据库,其支持特性

之多性能之强可与诸多高级商业数据库比肩。

这里提供了一个世界上主流数据库的特性比较,有兴趣的可以从中管窥PostgreSQL

在数据库领域中的成就。

/wiki/Comparison_of_relational_database_managemen

t_systems

PostGIS 则是PostgreSQL的一个扩展,目的是使PostgreSQL支持空间数据的存储

和使用,其本质类似于ArcSDE和Oracle Spatial Extension。PostGIS是采用GPL许可

发布的,完整地实现了OGC的《Simple Features Specification for SQL》规范,并于

2006年获得OGC认证。在此基础上,PostGIS还对规范进行了一些扩展,在后面的特性

中我们可以慢慢了解到。

二、 PostGIS中的几何类型

PostGIS支持所有OGC规范的“Simple Features”类型,同时在此基础上扩展了对

3DZ、3DM、4D坐标的支持。

1. OGC的WKB和WKT格式

OGC定义了两种描述几何对象的格式,分别是WKB(Well-Known Binary)和WKT

(Well-Known Text)。

在SQL语句中,用以下的方式可以使用WKT格式定义几何对象:

POINT(0 0) ——点

LINESTRING(0 0,1 1,1 2) ——线

POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1)) ——面

MULTIPOINT(0 0,1 2) ——多点

MULTILINESTRING((0 0,1 1,1 2),(2 3,3 2,5 4)) ——多线

MULTIPOLYGON(((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2

-1,-1 -1))) ——多面

GEOMETRYCOLLECTION(POINT(2 3),LINESTRING((2 3,3 4))) ——几何集合

以下语句可以使用WKT格式插入一个点要素到一个表中,其中用到的

GeomFromText等函数在后面会有详细介绍:

INSERT INTO table ( SHAPE, NAME )

VALUES ( GeomFromText('POINT(116.39 39.9)', 4326), '北京');

2. EWKT、EWKB和Canonical格式

EWKT和EWKB相比OGC WKT和WKB格式主要的扩展有3DZ、3DM、4D坐标和

内嵌空间参考支持。

以下以EWKT语句定义了一些几何对象:

POINT(0 0 0) ——3D点

SRID=32632;POINT(0 0) ——内嵌空间参考的点

POINTM(0 0 0) ——带M值的点

POINT(0 0 0 0) ——带M值的3D点

SRID=4326;MULTIPOINTM(0 0 0,1 2 1) ——内嵌空间参考的带M值的多点

以下语句可以使用EWKT格式插入一个点要素到一个表中:

INSERT INTO table ( SHAPE, NAME )

VALUES ( GeomFromEWKT('SRID=4326;POINTM(116.39 39.9 10)'), '北京' )

Canonical格式是16进制编码的几何对象,直接用SQL语句查询出来的就是这种格

式。

3. SQL-MM格式

SQL-MM格式定义了一些插值曲线,这些插值曲线和EWKT有点类似,也支持3DZ、

3DM、4D坐标,但是不支持嵌入空间参考。

以下以SQL-MM语句定义了一些插值几何对象:

CIRCULARSTRING(0 0, 1 1, 1 0) ——插值圆弧

COMPOUNDCURVE(CIRCULARSTRING(0 0, 1 1, 1 0),(1 0, 0 1)) ——插值复合曲

线

CURVEPOLYGON(CIRCULARSTRING(0 0, 4 0, 4 4, 0 4, 0 0),(1 1, 3 3, 3 1, 1 1)) —

—曲线多边形

MULTICURVE((0 0, 5 5),CIRCULARSTRING(4 0, 4 4, 8 4)) ——多曲线

MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(0 0, 4 0, 4 4, 0 4, 0 0),(1 1,

3 3, 3 1, 1 1)),((10 10, 14 12, 11 10, 10 10),(11 11, 11.5 11, 11 11.5, 11 11))) ——多曲

三、 PostGIS中空间信息处理的实现

1. spatial_ref_sys表

在基于PostGIS模板创建的数据库的public模式下,有一个spatial_ref_sys表,它

存放的是OGC规范的空间参考。我们取我们最熟悉的4326参考看一下:

它的srid存放的就是空间参考的Well-Known ID,对这个空间参考的定义主要包括

两个字段,srtext存放的是以字符串描述的空间参考,proj4text存放的则是以字符串描述

的PROJ.4 投影定义(PostGIS使用PROJ.4实现投影)。

4326空间参考的srtext内容:

GEOGCS["WGS 84",DATUM["WGS_1984",

SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],

TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],

PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],

UNIT["degree",0.94328,AUTHORITY["EPSG","9122"]],AUTHORIT

Y["EPSG","4326"]]

4326空间参考的proj4text内容:

+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs

2. geometry_columns表

geometry_columns表存放了当前数据库中所有几何字段的信息,比如我当前的库里

面有两个空间表,在geometry_columns表中就可以找到这两个空间表中几何字段的定义:

其中f_table_schema字段表示的是空间表所在的模式,f_table_name字段表示的是

空间表的表名,f_geometry_column字段表示的是该空间表中几何字段的名称,srid字

段表示的是该空间表的空间参考。

3. 在PostGIS中创建一个空间表

在PostGIS中创建一个包含几何字段的空间表分为2步:第一步创建一个一般表,第

二步给这个表添加几何字段。

以下先在test模式下创建一个名为cities的一般表:

create table (id int4, name varchar(20))

再给cities添加一个名为shape的几何字段(二维点):

select AddGeometryColumn('test', 'cities', 'shape', 4326, 'POINT', 2)

4. PostGIS对几何信息的检查

PostGIS可以检查几何信息的正确性,这主要是通过IsValid函数实现的。

以下语句分辨检查了2个几何对象的正确性,显然,(0, 0)点和(1,1)点可以构成一条线,

但是(0, 0)点和(0, 0)点则不能构成,这个语句执行以后的得出的结果是TRUE,FALSE。

select IsValid('LINESTRING(0 0, 1 1)'), IsValid('LINESTRING(0 0,0 0)')

默认PostGIS并不会使用IsValid函数检查用户插入的新数据,因为这会消耗较多的

CPU资源(特别是复杂的几何对象)。当你需要使用这个功能的时候,你可以使用以下语

句为表新建一个约束:

ALTER TABLE cities

ADD CONSTRAINT geometry_valid

CHECK (IsValid(shape))

这时当我们往这个表试图插入一个错误的空间对象的时候,会得到一个错误:

INSERT INTO ( shape, name )

VALUES ( GeomFromText('LINESTRING(0 0,0 0)', 4326), '北京');

ERROR: new row for relation "cities" violates check constraint

"geometry_valid"

SQL 状态: 23514

5. PostGIS中的空间索引

数据库对多维数据的存取有两种索引方案,R-Tree和GiST(Generalized Search

Tree),在PostgreSQL中的GiST比R-Tree的健壮性更好,因此PostGIS对空间数据的

索引一般采用GiST实现。

以下的语句给sde模式中的cities表添加了一个空间索引shape_index_cities,在

pgAdmin中也可以通过图形界面完成相同的功能。

CREATE INDEX shape_index_cities

ON

USING gist

(shape);

另外要注意的是,空间索引只有在进行基于边界范围的查询时才起作用,比如“&&”

操作。

四、 PostGIS中的常用函数

以下内容包括比较多的尖括号,发布到blogger的时候会显示不正常,内容太多我也

无暇一个个手动改代码,因此如有问题就去参考PostGIS官方文档。

首先需要说明一下,这里许多函数是以ST_[X]yyy形式命名的,事实上很多函数也可

以通过xyyy的形式访问,在PostGIS的函数库中我们可以看到这两种函数定义完全一样。

1. OGC标准函数

管理函数:

添加几何字段 AddGeometryColumn(, , , , , )

删除几何字段 DropGeometryColumn(, , )

检查数据库几何字段并在

Probe_Geometry_Columns()

geometry_columns中归档

给几何对象设置空间参考(在通过一个范围做空间查询时常用)

ST_SetSRID(geometry, integer)

几何对象关系函数:

获取两个几何对象间的距离 ST_Distance(geometry, geometry)

如果两个几何对象间距离在给定值范围内,则返回TRUE ST_DWithin(geometry,

geometry, float)

判断两个几何对象是否相等

(比如LINESTRING(0 0, 2 2)和LINESTRING(0 0, 1 1, 2 2)是相同的几何对象)

ST_Equals(geometry, geometry)

判断两个几何对象是否分离 ST_Disjoint(geometry, geometry)

判断两个几何对象是否相交 ST_Intersects(geometry, geometry)

判断两个几何对象的边缘是否接触 ST_Touches(geometry, geometry)

判断两个几何对象是否互相穿过 ST_Crosses(geometry, geometry)

判断A是否被B包含 ST_Within(geometry A, geometry B)

判断两个几何对象是否是重叠 ST_Overlaps(geometry, geometry)

判断A是否包含B ST_Contains(geometry A, geometry B)

判断A是否覆盖 B ST_Covers(geometry A, geometry B)

判断A是否被B所覆盖 ST_CoveredBy(geometry A, geometry B)

通过DE-9IM 矩阵判断两个几何对象的关系是否成立 ST_Relate(geometry,

geometry, intersectionPatternMatrix)

获得两个几何对象的关系(DE-9IM矩阵) ST_Relate(geometry, geometry)

几何对象处理函数:

获取几何对象的中心 ST_Centroid(geometry)

面积量测 ST_Area(geometry)

长度量测 ST_Length(geometry)

返回曲面上的一个点 ST_PointOnSurface(geometry)

获取边界 ST_Boundary(geometry)

获取缓冲后的几何对象 ST_Buffer(geometry, double, [integer])

获取多几何对象的外接对象 ST_ConvexHull(geometry)

获取两个几何对象相交的部分 ST_Intersection(geometry, geometry)

将经度小于0的值加360使所有经度值在0-360间 ST_Shift_Longitude(geometry)

获取两个几何对象不相交的部分(A、B可互换) ST_SymDifference(geometry A,

geometry B)

从A去除和B相交的部分后返回 ST_Difference(geometry A, geometry B)

返回两个几何对象的合并结果 ST_Union(geometry, geometry)

返回一系列几何对象的合并结果 ST_Union(geometry set)

用较少的内存和较长的时间完成合并操作,结果和ST_Union相同

ST_MemUnion(geometry set)

几何对象存取函数:

获取几何对象的WKT描述 ST_AsText(geometry)

获取几何对象的WKB描述 ST_AsBinary(geometry)

获取几何对象的空间参考ID ST_SRID(geometry)

获取几何对象的维数 ST_Dimension(geometry)

获取几何对象的边界范围 ST_Envelope(geometry)

判断几何对象是否为空 ST_IsEmpty(geometry)

判断几何对象是否不包含特殊点(比如自相交) ST_IsSimple(geometry)

判断几何对象是否闭合 ST_IsClosed(geometry)

判断曲线是否闭合并且不包含特殊点 ST_IsRing(geometry)

获取多几何对象中的对象个数 ST_NumGeometries(geometry)

获取多几何对象中第N个对象 ST_GeometryN(geometry,int)

获取几何对象中的点个数 ST_NumPoints(geometry)

获取几何对象的第N个点 ST_PointN(geometry,integer)

获取多边形的外边缘 ST_ExteriorRing(geometry)

获取多边形内边界个数 ST_NumInteriorRings(geometry)

同上 ST_NumInteriorRing(geometry)

获取多边形的第N个内边界 ST_InteriorRingN(geometry,integer)

获取线的终点 ST_EndPoint(geometry)

获取线的起始点 ST_StartPoint(geometry)

获取几何对象的类型 GeometryType(geometry)

类似上,但是不检查M值,即POINTM对象会被判断为

ST_GeometryType(geometry)

获取点的X坐标 ST_X(geometry)

获取点的Y坐标 ST_Y(geometry)

获取点的Z坐标 ST_Z(geometry)

point

获取点的M值 ST_M(geometry)

几何对象构造函数:

参考语义:

Text:WKT

WKB:WKB

Geom:Geometry

M:Multi

Bd:BuildArea

Coll:Collection ST_GeomFromText(text,[])

ST_PointFromText(text,[])

ST_LineFromText(text,[])

ST_LinestringFromText(text,[])

ST_PolyFromText(text,[])

ST_PolygonFromText(text,[])

ST_MPointFromText(text,[])

ST_MLineFromText(text,[])

ST_MPolyFromText(text,[])

ST_GeomCollFromText(text,[])

ST_GeomFromWKB(bytea,[])

ST_GeometryFromWKB(bytea,[])

ST_PointFromWKB(bytea,[])

ST_LineFromWKB(bytea,[])

ST_LinestringFromWKB(bytea,[])

ST_PolyFromWKB(bytea,[])

ST_PolygonFromWKB(bytea,[])

ST_MPointFromWKB(bytea,[])

ST_MLineFromWKB(bytea,[])

ST_MPolyFromWKB(bytea,[])

ST_GeomCollFromWKB(bytea,[])

ST_BdPolyFromText(text WKT, integer SRID)

ST_BdMPolyFromText(text WKT, integer SRID)

2. PostGIS扩展函数

管理函数:

删除一个空间表(包括geometry_columns中的记录)

更新空间表的空间参考 UpdateGeometrySRID([], , , )

更新空间表的统计信息 update_geometry_stats([, ])

参考语义:

Geos:GEOS库

Jts:JTS库

DropGeometryTable([], )

Proj:PROJ4库 postgis_version()

postgis_lib_version()

postgis_lib_build_date()

postgis_script_build_date()

postgis_scripts_installed()

postgis_scripts_released()

postgis_geos_version()

postgis_jts_version()

postgis_proj_version()

postgis_uses_stats()

postgis_full_version()

几何操作符:

A范围=B范围 A = B

A范围覆盖B范围或A范围在B范围左侧 A &<> B

A范围在B范围左侧 A <<>> B

A范围覆盖B范围或A范围在B范围下方 A &<| B A范围覆盖B范围或A范围在B

范围上方 A |&> B

A范围在B范围下方 A <<| B A范围在B范围上方 A |>> B

A=B A ~= B

A范围被B范围包含 A @ B

A范围包含B范围 A ~ B

A范围覆盖B范围 A && B

几何量测函数:

量测面积 ST_Area(geometry)

根据经纬度点计算在地球曲面上的距离,单位米,地球半径取值6370986米

ST_distance_sphere(point, point)

类似上,使用指定的地球椭球参数 ST_distance_spheroid(point, point, spheroid)

量测2D对象长度 ST_length2d(geometry)

量测3D对象长度 ST_length3d(geometry)

根据经纬度对象计算在地球曲面上的长度

ST_length_spheroid(geometry,spheroid)

ST_length3d_spheroid(geometry,spheroid)

量测两个对象间距离 ST_distance(geometry, geometry)

量测两条线之间的最大距离 ST_max_distance(linestring,linestring)

量测2D对象的周长 ST_perimeter(geometry)

ST_perimeter2d(geometry)

量测3D对象的周长 ST_perimeter3d(geometry)

量测两点构成的方位角,单位弧度 ST_azimuth(geometry, geometry)

几何对象输出:

参考语义:

NDR:Little Endian

XDR:big-endian

HEXEWKB:Canonical

SVG:SVG 格式

GML:GML 格式

KML:KML 格式

GeoJson:GeoJson 格式

ST_AsBinary(geometry,{'NDR'|'XDR'})

ST_AsEWKT(geometry)

ST_AsEWKB(geometry, {'NDR'|'XDR'})

ST_AsHEXEWKB(geometry, {'NDR'|'XDR'})

ST_AsSVG(geometry, [rel], [precision])

ST_AsGML([version], geometry, [precision])

ST_AsKML([version], geometry, [precision])

ST_AsGeoJson([version], geometry, [precision], [options])

几何对象创建:

参考语义:

Dump:转储 ST_GeomFromEWKT(text)

ST_GeomFromEWKB(bytea)

ST_MakePoint(, , [], [])

ST_MakePointM(, , )

ST_MakeBox2D(, )

ST_MakeBox3D(, )

ST_MakeLine(geometry set)

ST_MakeLine(geometry, geometry)

ST_LineFromMultiPoint(multipoint)

ST_MakePolygon(linestring, [linestring[]])

ST_BuildArea(geometry)

ST_Polygonize(geometry set)

ST_Collect(geometry set)

ST_Collect(geometry, geometry)

ST_Dump(geometry)

ST_DumpRings(geometry)

几何对象编辑:

给几何对象添加一个边界,会使查询速度加快 ST_AddBBOX(geometry)

删除几何对象的边界 ST_DropBBOX(geometry)

添加、删除、设置点 ST_AddPoint(linestring, point, [])

ST_RemovePoint(linestring, offset)

ST_SetPoint(linestring, N, point)

几何对象类型转换 ST_Force_collection(geometry)

ST_Force_2d(geometry)

ST_Force_3dz(geometry), ST_Force_3d(geometry),

ST_Force_3dm(geometry)

ST_Force_4d(geometry)

ST_Multi(geometry)

将几何对象转化到指定空间参考 ST_Transform(geometry,integer)

对3D几何对象作仿射变化 ST_Affine(geometry, float8, float8, float8, float8,

float8, float8, float8, float8, float8, float8, float8, float8)

对2D几何对象作仿射变化 ST_Affine(geometry, float8, float8, float8, float8,

float8, float8)

对几何对象作偏移 ST_Translate(geometry, float8, float8, float8)

对几何对象作缩放 ST_Scale(geometry, float8, float8, float8)

对3D几何对象作旋转 ST_RotateZ(geometry, float8)

ST_RotateX(geometry, float8)

ST_RotateY(geometry, float8)

对2D对象作偏移和缩放 ST_TransScale(geometry, float8, float8, float8, float8)

反转 ST_Reverse(geometry)

转化到右手定则 ST_ForceRHR(geometry)

参考IsSimple函数

使用Douglas-Peuker算法 ST_Simplify(geometry, tolerance)

ST_SimplifyPreserveTopology(geometry, tolerance)

讲几何对象顶点捕捉到网格 ST_SnapToGrid(geometry, originX, originY, sizeX,

sizeY)

ST_SnapToGrid(geometry, sizeX, sizeY), ST_SnapToGrid(geometry, size)

第二个参数为点,指定原点坐标 ST_SnapToGrid(geometry, geometry, sizeX, sizeY,

sizeZ, sizeM)

分段 ST_Segmentize(geometry, maxlength)

合并为线 ST_LineMerge(geometry)

线性参考:

根据location(0-1)获得该位置的点 ST_line_interpolate_point(linestring,

location)

获取一段线 ST_line_substring(linestring, start, end)

根据点获取location(0-1) ST_line_locate_point(LineString, Point)

根据量测值获得几何对象 ST_locate_along_measure(geometry, float8)

根据量测值区间获得几何对象集合 ST_locate_between_measures(geometry,

float8, float8)

杂项功能函数:

几何对象的摘要 ST_Summary(geometry)

几何对象的边界 ST_box2d(geometry)

ST_box3d(geometry)

多个几何对象的边界 ST_extent(geometry set)

0=2d, 1=3dm, 2=3dz, 3=4d ST_zmflag(geometry)

是否包含Bounding Box ST_HasBBOX(geometry)

几何对象的维数:2、3、4 ST_ndims(geometry)

子对象的个数 ST_nrings(geometry)

ST_npoints(geometry)

对象是否验证成功 ST_isvalid(geometry)

扩大几何对象 ST_expand(geometry, float)

计算一个空间表的边界范围 ST_estimated_extent([schema], table, geocolumn)

获得空间参考 ST_find_srid(, , )

几何对象使用的内存大小,单位byte ST_mem_size(geometry)

点是否在圆上 ST_point_inside_circle(,,,)

获取边界的X、Y、Z ST_XMin(box3d)

ST_YMin(box3d)

ST_ZMin(box3d)

ST_XMax(box3d)

ST_YMax(box3d)

ST_ZMax(box3d)

构造一个几何对象的数组 ST_Accum(geometry set)

长事务支持:

启用/关闭长事务支持,重复调用无副作用 EnableLongTransactions()

DisableLongTransactions()

检查对行的update和delete操作是否已授权 CheckAuth([],

, )

锁定行 LockRow([], , , , [])

解锁行 UnlockRows()

在当前事务中添加授权ID AddAuth()

其它还有SQL-MM和ArcSDE样式的函数支持,可以参考

/documentation/manual-1.3/#id27506

11,这里就不详细列了。

五、 PostGIS示例

下面我们通过一个简单的Flex应用示例来看一下PostGIS的用法:

假想现在发生了恐怖袭击,导致在一些城市有污染物出现,现在我们要根据污染物和

当地风力、风向情况,计算污染扩散范围,针对这些区域及时进行警报和疏散。

首先我们希望获得所有发生污染的城市的当前风速、风向等信息,在我们的PostGIS

数据库中有一个空间表保存着这些信息,我们构造这样的SQL语句进行查询:

select *,ST_AsGeoJson(shape) from

这里会获取所有风相关的信息,并且附加了以JSON格式返回的几何信息,这有助于

我们在Flex中进行解析。如下图是关于风的查询结果:

下面我们希望PostGIS帮助我们实现一些空间分析。我们以污染发生的城市为起点,

当地风向为主方向,构造一个30度开角的范围;这个范围将是污染扩散的主要方向,扩

散的范围主要和风的强度有关;在构造这个区域以后,为了保险起见,我们在对其进行一

定范围的缓冲,最后得到每个污染源可能扩散的范围。我们构造的SQL语句如下:

select *,

ST_AsGeoJson(

ST_Buffer( ST_PolygonFromText( 'POLYGON(('

||ST_X(shape)||' '||ST_Y(shape)||','

||ST_X(shape)+velocity*cos((direction+15)*PI()/180)/20||'

'||ST_Y(shape)+velocity*sin((direction+15)*PI()/180)/20||','

||ST_X(shape)+velocity*cos((direction-15)*PI()/180)/20||'

'||ST_Y(shape)+velocity*sin((direction-15)*PI()/180)/20||','

||ST_X(shape)||' '||ST_Y(shape)||'))' ) , velocity/50 ) ) from

下面是PostGIS进行运算后返回的结果:

在这里,Flex应用与服务器的交互通过BlazeDS进行,下面是本示例在服务器端的Java

代码:

package wuyf;

import tion;

import Manager;

import Set;

import ent;

import ist;

import p;

public class Wind

{

private Connection conn = null;

public Connection getConn()

{

if (conn==null)

{

try

{

e("");

String url = "jdbc:postgresql://localhost:5432/sde" ;

conn = nection(url, "sde" , "pwd" );

oCommit(false);

}

catch(Exception e)

{

(e);

}

}

return conn;

}

public ArrayList > getWinds()

{

ArrayList> result = new ArrayList>();

if ( n()==null )

return result;

try

{

String sql = "select *,ST_AsGeoJson(shape) from ";

Statement st = n().createStatement();

chSize(0);

ResultSet rs = eQuery(sql);

while (())

{

HashMap map = new HashMap();

("shape", ing("ST_AsGeoJson"));

("velocity", ing("velocity"));

("direction", ing("direction"));

(map);

}

();

();

}

catch(Exception e)

{

(e);

}

return result;

}

public ArrayList > getEffectZones()

{

ArrayList> result = new ArrayList>();

if ( n()==null )

return result;

try

{

String sql = "select *,ST_AsGeoJson(";

sql+= "ST_Buffer(";

sql+= "ST_PolygonFromText(";

sql+= "'POLYGON(('";

sql+= "||ST_X(shape)||' '||ST_Y(shape)||','";

sql+= "||ST_X(shape)+velocity*cos((direction+15)*PI()/180)/20||'

'||ST_Y(shape)+velocity*sin((direction+15)*PI()/180)/20||','";

sql+= "||ST_X(shape)+velocity*cos((direction-15)*PI()/180)/20||'

'||ST_Y(shape)+velocity*sin((direction-15)*PI()/180)/20||','";

sql+= "||ST_X(shape)||' '||ST_Y(shape)||'))'";

sql+= ")";

sql+= ", velocity/50";

sql+= ")";

sql+= ") ";

sql+="from ";

Statement st = n().createStatement();

chSize(0);

ResultSet rs = eQuery(sql);

while (())

{

HashMap map = new HashMap();

("shape", ing("ST_AsGeoJson"));

("velocity", ing("velocity"));

("direction", ing("direction"));

(map);

}

();

();

}

catch(Exception e)

{

(e);

}

return result;

}

}

postgis 使用

一. 安装postgis

(1) 首先到postgresql的官方网站()上下载最新版的开源数据

库postgresql,当前下载的最新安装包是

(2) 运行该exe,按照向导安装之,在安装过程中最好关闭防火墙,以及监控;另外最好将

安装目录设置为NTFS分区的盘上.

(3) 安装完成后提示你是否在退出时配置application stack builder,这里勾选上它,然

后点finish。

(4) 进入application stack builder向导后,选择postgresql 8.3 on port 5432,点

next.

(5) 在application list中勾选上要安装的application,这里必须勾选

(6) 下一步,选择下载服务器,下载完成后开始安装相应的application.

(7) 在安装时要注意,有两处都要设置密码,不要设置密码为空.

(8) 这样根据向导就可以成功安装postgis了

安装postgis过程中可能会出现:

"Error opening file for writing: c:program

"的提示,这里我们可以忽略之.

二. 向postgis导入shapefile数据

(1)安装后运行pgadmin III,右击postgresql 8.3(localhost)服务器,连接,这里的密码

是你安装时设置的密码,务必牢记.

(2)连接后,我们发现postgis安装后自动给我们生成了一个数据库template_postgis,

我们将要导入的数据就需要放到这个数据库中.

(3)运行命名提示符,将其转向C:Program FilesPostgreSQL8.3bin(或者

将复制到该目录下)如下:

C:Program FilesPostgreSQL8.3bin>

(4)首先将shp生成对应的sql脚本,键入以下字符

C:Program FilesPostgreSQL8.3bin>shp2pgsql -W "GBK"

D:CampusGISProjectnew_pku_ viwpt >

D:CampusGISProjectnew_pku_

这里的-W "GBK"代表字符编码的转换,

D:CampusGISProjectnew_pku_则是要生成sql脚本的shp文

件.viwpt是创建数据表的表名,>不能少,

D:CampusGISProjectnew_pku_vector 则是要生成SQL文件的绝对目

生成成功后命令提示符会显示如下:

Shapefile type: Point

Postgis type: POINT[2]

(5)然后我们执行sql语句,执行该SQL语句文件,导入数据到数据库template_postgis

C:Program FilesPostgreSQL8.3bin>psql -d template_postgis -f

D:CampusGISProjectnew_pku_ postgres

其中 template_postgis是数据库名,postgres是该数据库的用户.

执行成功后,刷新该数据库,就可以看到新生成的数据表viwpt, 这样数据就

成功导入到了postgis中了.


本文标签: 对象 空间 数据库