一、空间数据库介绍
1.什么是空间数据库
人类理解世界其实是按照三维的角度,而传统的关系型数据库是二维的,要想描述空间地理位置,点、线、面,我们就需要一个三维数据库,即所谓空间数据库。
postGIS就是一个空间数据库。
2.空间数据库是怎么存储的
除了普通数据库所具备的字符串、数值、日期等,空间数据库增加了空间数据类型。
这些空间数据类型抽象并封装了诸如边界(boundary)和维度(dimension)等空间结构。
可以这么理解,空间数据库内置了许多属性,这些属性用于描述空间结构信息。
以点(Point)数据类型为例,一个点可以由它在某一坐标参考系下的X、Y坐标值来表示,如“POINT(116.4074 39.9042)”表示了一个位于北京市中心的点。
并且,空间数据类型按类型层次结构组织。每个子类型继承其父类型的结构(属性)和行为(方法或函数)。
3.空间数据库有索引吗
普通数据库有索引。空间数据库也有空间索引,它有什么作用呢?
举个应用的栗子帮助理解。查找你附近100m以内的所有商场。如果没有空间索引,你需要苦逼的按照坐标取平方根穷举计算,然后保留所有距离小于100的商场数据。
但是空间数据库的索引设计有难点:如何组织数据的结构。普通数据库用B+树等就可以。空间索引有很多种,网格索引、四叉树索引、金字塔索引…
其原理:过于先进,暂不展示
4.空间函数是什么东东
二维的虫子可想不到三维的世界有多复杂:分析几何信息、确定空间关系…
空间数据库当然需要专业的解决这些问题,因此,它内置空间函数。
空间函数主要分为五类:
转换 —— 在geometry(PostGIS中存储空间信息的格式)和外部数据格式之间进行转换的函数
管理 —— 管理关于空间表和PostGIS组织的信息的函数
检索 —— 检索几何图形的属性和空间信息测量的函数
比较 —— 比较两种几何图形的空间关系的函数
生成 —— 基于其他几何图形生成新图形的函数
二、PostGIS快速入门
1.postGIS是什么
其实您应该猜到了,他就是在postgreSQL上的一个插件,但是因为有它,postgreSQL摇身一变,成了一个强大的空间数据库。
这就意味着,这哥们儿开源啊。
2.postGIS怎么用啊
这个教程主要是帮助快速理解什么是postGIS,因此不会太细致。
自行下载安装postGreSQL、postGIS
导入数据文件shape file
一个shapfile必须有的文件:
.shp —— 存储地理要素的几何信息
.shx —— 存储要素几何图形的索引信息
.dbf —— 存储地理要素的属性信息(非几何信息)
可选文件包括:
.prj —— 存储空间参考信息,即地理坐标系统信息和投影坐标系统信息。使用well-known文本格式进行描述。
Soga!原来就是导文件给你可视化展示啊。这题咱会!
操作数据,用SQL
哦,原来还是熟悉的配方,还是原来的味道。
SELECT name FROM nyc_neighborhoods WHERE boroname = 'Brooklyn';
元数据管理
PostGIS提供了两张表用于追踪和报告数据库中的几何图形(这两张表中的内容相当于元数据)
第一张表spatial_ref_sys —— 定义了数据库已知的所有空间参照系统,稍后将对其进行更详细的说明。
第二张表(实际上是视图-view)geometry_columns —— 提供了数据库中所有空间数据表的描述信息
通过查询该表,GIS客户端和数据库可以确定检索数据时的预期内容,并可以执行任何必要的投影、处理、渲染而无需检查每个几何图形(geometry)—— 这些就是元数据所带来的作用。
表示真实世界的对象
Simple Features for SQL(SFSQL)规范是PostGIS开发的原始指导标准,它定义了如何表示真实世界的对象。但是这个哥们只表示了二维,而PostGIS扩展了3维、4维的表示。
说人话,就是可以表示:点、线串、多边形、图形集合(Collection)。
举一个图形集合的例子。
SELECT name, ST_AsText(geom) FROM geometries WHERE name = 'Collection';
返回结果就是一个点和一个多边形的集合。
基本操作而已,你是不是也学会了。
几何图形的存储
PostGIS支持以多种格式进行几何图形的输入和输出:
Well-known text(WKT)
Well-known binary(WKB)
Geographic Mark-up Language(GML)
Keyhole Mark-up Language(KML)
GeoJson
Scalable Vector Graphics(SVG)
使用方法就是调用encode函数,以下SQL查询展示了一个WKB表示形式的示例
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;
搞半天,原来这玩意有手(册)就行,不用太费劲学。
内置函数
这里介绍下它有哪些功能函数,同志们心里有个底,需要时查查手册。
sum(expression) aggregate to return a sum for a set of records count(expression) aggregate to return the size of a set of records ST_GeometryType(geometry) returns the type of the geometry ST_NDims(geometry) returns the number of dimensions of the geometry ST_SRID(geometry) returns the spatial reference identifier number of the geometry ST_X(point) returns the X ordinate ST_Y(point) returns the Y ordinate ST_Length(linestring) returns the length of the linestring ST_StartPoint(geometry) returns the first coordinate as a point ST_EndPoint(geometry) returns the last coordinate as a point ST_NPoints(geometry) returns the number of coordinates in the linestring ST_Area(geometry) returns the area of the polygons ST_NRings(geometry) returns the number of rings (usually 1, more if there are holes) ST_ExteriorRing(polygon) returns the outer ring as a linestring ST_InteriorRingN(polygon, integer) returns a specified interior ring as a linestring ST_Perimeter(geometry) returns the length of all the rings ST_NumGeometries(multi/geomcollection) returns the number of parts in the collection ST_GeometryN(geometry, integer) returns the specified part of the collection ST_GeomFromText(text) returns geometry ST_AsText(geometry) returns WKT text ST_AsEWKT(geometry) returns EWKT text ST_GeomFromWKB(bytea) returns geometry ST_AsBinary(geometry) returns WKB bytea ST_AsEWKB(geometry) returns EWKB bytea ST_GeomFromGML(text) returns geometry ST_AsGML(geometry) returns GML text ST_GeomFromKML(text) returns geometry ST_AsKML(geometry) returns KML text ST_AsGeoJSON(geometry) returns JSON text ST_AsSVG(geometry) returns SVG text
总的来说,就是可以:求面积、求边界、求大边形里有多少小多边形…在多维的世界里为所欲为。
空间关系
目前为止,我们一次只能处理一个几何图形。
空间数据库之所以强大,是因为它们不仅能存储几何图形,而且还能够分析几何图形之间的关系。
诸如"哪一个是离公园最近的自行车位?"或者"地铁线路和街道的交叉路口在哪里?"这样的问题,只能通过比较、分析表示自行车位、街道和地铁线路的几何图形来回答。
OGC标准定义了以下一组用于比较几何图形的方法。
ST_Equals(geometry A, geometry B)用于测试两个图形的空间相等性。
ST_Intersects、ST_Crosses和ST_Overlaps都用于测试几何图形内部是否相交。
ST_Touches()测试两个几何图形是否在它们的边界上接触,但在它们的内部不相交
ST_Within()和ST_Contains()测试一个几何图形是否完全包含于另一个几何图形内
ST_Distance(geometry A, geometry B)计算两个几何图形之间的最短距离
空间连接
空间连接(spatial joins)是空间数据库的主要组成部分,它们允许你使用空间关系作为连接键(join key)来连接来自不同数据表的信息
还支持汇总。JOIN和GROUP BY的组合支持通常在GIS系统中的某些分析。这个和普通的关系型数据库几乎一样。不多介绍了。
随便举个栗子,感受下。
SELECT n.name, Sum(c.popn_total) / (ST_Area(n.geom) / 1000000.0) AS popn_per_sqkm FROM nyc_census_blocks AS c JOIN nyc_neighborhoods AS n ON ST_Intersects(c.geom, n.geom) WHERE n.name = 'Upper West Side' OR n.name = 'Upper East Side' GROUP BY n.name, n.geom;
上面sql计算了:"'Upper West Side’和’Upper East Side’的人口密度(人/平方千米 )是多少?
三、PostGIS进阶玩法
到目前为止,都平平无奇,接下来介绍进阶玩法。
1.空间索引
空间索引是PostGIS的最大价值之一。在前面的示例中,构建空间连接需要对整个表进行相互比较。这样做的代价很高:连接两个各包含10000条记录的表(每个表都没有索引)将需要进行100000000次比较;如果使用空间索引,则比较次数可能低至20000次
创建索引、删除索引就不多BB了。你们都会。
CREATE INDEX nyc_census_blocks_geom_idx ON nyc_census_blocks USING GIST (geom);
注意:USING GIST子句告诉PostgreSQL在构建索引时使用generic index structure(GIST-通用索引结构)。
原理
先回答一个问题,空间索引干了啥?
提高查询效率。
那空间索引是怎么做到提高查询效率的?
标准的数据库索引,是根据被索引的列的值去创建树结构的。空间索引略不同,因为数据库并不能索引几何字段的值 —— 也就是几何对象本身,我们改索引要素的范围边界框。
上图中,和黄色星星相交的线的数量是 1,即红色那条线。但是与黄色框相交的范围框有红色和蓝色,共 2 个。
数据库求解 “什么线与黄色星相交” 这个问题,是先用空间索引求解 “什么范围框与黄色范围框相交” 这个问题的(速度非常快),然后才是 “什么线与黄色的星星相交”。上述过程仅对于第一次测试的空间要素而言。
对于数量庞大的数据表,这种索引先行,然后局部精确计算的 “两遍法” 可以在根本上减少查询计算量。
简单来说就是,规则的几何图形的计算比不规则的图形计算简单,利用这一点做为优化的基本思想。
PostGIS中最常用的函数(ST_Contains、ST_Intersects、ST_DWithin等)都包含自动索引过滤器。但有些函数(如ST_Relate)不包括索引过滤器。
要使用索引执行边界框搜索(即纯索引查询-Index only Query-没有过滤器),需要使用"&&"运算符
查询规划器:用不用索引?
PostgreSQL查询规划器(query planner)智能地选择何时使用或不使用空间索引来计算查询。与直觉相反,执行空间索引搜索并不总是更快。
默认情况下,PostgreSQL定期收集数据统计信息,共查询规划器使用。但是,如果你在短时间内更改了表的构成,则统计数据将不会是最新的。因此,为确保统计信息与表内容匹配,明智的做法是在表中加载和删除大容量数据后手动运行ANALYZE命令。
ANALYZE nyc_census_blocks;
清理:回收空间
每当创建新索引或对表大量更新、插入或删除后,都必须执行清理(VACUUMing)。VACUUM命令要求PostgreSQL回收表页面中因记录的更新或删除而留下的任何未使用的空间。
VACUUM ANALYZE nyc_census_blocks;