到目前为止,我们只使用了测量(ST_Area、ST_Length)、序列化(ST_GeomFromText)或者反序列化(ST_AsGML)几何图形(geometry)的空间函数。这些函数的共同之处在于它们一次只能处理一个几何图形。

空间数据库之所以强大,是因为它们不仅能存储几何图形,而且还能够分析几何图形之间的关系

诸如"哪一个是离公园最近的自行车位?"或者"地铁线路和街道的交叉路口在哪里?"这样的问题,只能通过比较、分析表示自行车位、街道和地铁线路的几何图形来回答。

OGC标准定义了以下一组用于比较几何图形的方法。

一、ST_Equals

ST_Equals(geometry A, geometry B)用于测试两个图形的空间相等性。

如果两个相同类型的几何图形具有相同的x、y坐标值,即如果第二个图形与第一个图形的空间形状与位置相等(空间相等性),则ST_Equals()返回TRUE

首先,让我们从nyc_subway_stations表中检索点数据,我们只选"Broad St"的条目。

SELECT name, geom, ST_AsText(geom)
FROM nyc_subway_stations
WHERE name = 'Broad St';

然后,将几何图形表示数据插入ST_Equals()进行测试:

SELECT name
FROM nyc_subway_stations
WHERE ST_Equals(geom, '0101000020266900000EEBD4CF27CF2141BC17D69516315141');

注意:点在空间数据表中的表示不是很容易理解(0101000020266900000EEBD4CF27CF2141BC17D69516315141),但它是坐标值的精确表示(十六进制)。对于像相等这样的测试,使用精确的坐标信息进行比较是必要的。

二、ST_Intersects、ST_Disjoint、ST_Crosses和ST_Overlaps

ST_IntersectsST_CrossesST_Overlaps都用于测试几何图形内部是否相交。

如果两个图形有相同的空间部分,即如果它们的边界或内部相交,则ST_Intersects(geometry A, geometry B)返回TRUE。

ST_Intersects()方法的对立方法是ST_Disjoint(geometry A, geometry B)

如果两个几何图形没有相交的部分,则它们不相交,反之亦然。

事实上测试"not intersect"(!ST_Intersects)通常比测试"disjoint"(ST_Disjoint)更有效,因为intersect测试会自动使用空间索引

对于multipoint/polygon、multipoint/linestring、linestring/linestring、linestring/polygon和linestring/multipolygon的比较,如果相交生成的几何图形的维度小于两个源几何图形的最大维度,且相交集位于两个源几何图形的内部,则ST_Crosses(geometry A, geometry B)将返回TRUE(其实就是判断两个几何图形是否交叉)。

ST_Overlaps(geometry A, geometry B)比较两个相同维度的几何图形,如果它们的结果集与两个源几何图形都不同但具有相同维度,则返回TRUE(其实就是判断两个几何图形是否叠置)。

让我们以宽街地铁站(Broad Street)为例,使用ST_Intersects()函数确定其所在社区:

SELECT name, ST_AsText(geom)
FROM nyc_subway_stations
WHERE name = 'Broad St';

SELECT name, boroname
FROM nyc_neighborhoods
WHERE ST_Intersects(geom, ST_GeomFromText('POINT(583571 4506714)', 26918));

三、ST_Touches

ST_Touches()测试两个几何图形是否在它们的边界上接触,但在它们的内部不相交。

如果两个几何图形的边界相交,或者只有一个几何图形的内部与另一个几何图形的边界相交,则ST_Touches(geometry A, geometry B)将返回TRUE。

四、ST_Within和ST_Contains

ST_Within()和ST_Contains()测试一个几何图形是否完全位于另一个几何图形内。

如果第一个几何图形完全位于第二个几何图形内,则ST_Within(geometry A, geometry B)返回TRUE,ST_Within()测试的结果与ST_Contains()完全相反。

如果第二个几何图形B完全包含在第一个几何图形A内,则ST_Contains(geometry A, geometry B)返回TRUE。

五、ST_Distance和ST_DWithin

一个常见的GIS问题是"找到这个物体周围距离它X的所有其他物体"。

ST_Distance(geometry A, geometry B)计算两个几何图形之间的最短距离,并将其作为浮点数返回。这对于实际报告几何图形之间的距离非常有用。

SELECT ST_Distance(
ST_GeometryFromText('POINT(0 5)'),
ST_GeometryFromText('LINESTRING(-2 2, 2 2)'));

为了测试两个几何图形之间的距离是否在某个范围之内,ST_DWithin()函数提供了一个基于索引加速的功能。

这对于"在距离道路500米的缓冲区内有多少棵树?"这样的问题很有用,你不必计算实际的缓冲区,只需测试距离关系即可。

再次使用我们的宽街地铁站(Broad Street subway station),我们可以找到地铁站附近(10米内)的街道:

SELECT name
FROM nyc_streets
WHERE ST_DWithin(geom,ST_GeomFromText('POINT(583571 4506714)',26918),10);

我们可以在地图上验证答案,Broad St站实际上是在Wall、Broad和Nassau街道的十字路口。

六、空间关系练习

下面是我们在文章上面部分涉及到的一些函数,它们应该对练习有用!

  • 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_Contains(geometry A, geometry B) returns true if geometry A contains geometry B
  • ST_Crosses(geometry A, geometry B) returns true if geometry A crosses geometry B
  • ST_Disjoint(geometry A , geometry B) returns true if the geometries do not “spatially intersect”
  • ST_Distance(geometry A, geometry B) returns the minimum distance between geometry A and geometry B
  • ST_DWithin(geometry A, geometry B, radius) returns true if geometry A is radius distance or less from geometry B
  • ST_Equals(geometry A, geometry B) returns true if geometry A is the same as geometry B
  • ST_Intersects(geometry A, geometry B) returns true if geometry A intersects geometry B
  • ST_Overlaps(geometry A, geometry B) returns true if geometry A and geometry B share space, but are not completely contained by each other.
  • ST_Touches(geometry A, geometry B) returns true if the boundary of geometry A touches geometry B
  • ST_Within(geometry A, geometry B) returns true if geometry A is within geometry B

还请记住我们现在数据库中已经具有的表:

练习

①名为"Atlantic Commonts(大西洋公地)"的街道的geometry值是什么?

SELECT ST_AsText(geom)
FROM nyc_streets
WHERE name = 'Atlantic Commons';

②Atlantic Commons(大西洋公地)位于哪个社区(neighborhood)和行政区(borough)?

SELECT name, boroname
FROM nyc_neighborhoods
WHERE ST_Intersects(geom,ST_GeomFromText('LINESTRING(586782 4504202,586864 4504216)', 26918)
);

注意:嘿,为什么要将"MULTILINESTRING"变成"LINESTRING"呢?因为在空间上,它们描述的是相同的形状。

更重要的是,我们还对坐标进行了四舍五入,以使它们更易于阅读,这实际上改变了结果:我们现在不能使用ST_Touches()方法来找出哪些道路连接Atlantic Commons,因为坐标不再与原来的坐标完全相同。

③Atlantic Commons(大西洋公地)与哪些街道相连?

SELECT name
FROM nyc_streets
WHERE ST_DWithin(geom,ST_GeomFromText('LINESTRING(586782 4504202,586864 4504216)', 26918),0.1
);

④大约有多少人住在Atlantic Commons上(距离Atlantic Commons50米以内)?

SELECT Sum(popn_total)
FROM nyc_census_blocks
WHERE ST_DWithin(geom,ST_GeomFromText('LINESTRING(586782 4504202,586864 4504216)', 26918),50
);

七、本文涉及的函数

ST_Contains(geometry A, geometry B): Returns true if and only if no points of B lie in the exterior of A, and at least one point of the interior of B lies in the interior of A.

ST_Crosses(geometry A, geometry B): Returns TRUE if the supplied geometries have some, but not all, interior points in common.

ST_Disjoint(geometry A , geometry B): Returns TRUE if the Geometries do not “spatially intersect” - if they do not share any space together.

ST_Distance(geometry A, geometry B): Returns the 2-dimensional cartesian minimum distance (based on spatial ref) between two geometries in projected units.

ST_DWithin(geometry A, geometry B, radius): Returns true if the geometries are within the specified distance (radius) of one another.

ST_Equals(geometry A, geometry B): Returns true if the given geometries represent the same geometry. Directionality is ignored.

ST_Intersects(geometry A, geometry B): Returns TRUE if the Geometries/Geography “spatially intersect” - (share any portion of space) and FALSE if they don’t (they are Disjoint).

ST_Overlaps(geometry A, geometry B): Returns TRUE if the Geometries share space, are of the same dimension, but are not completely contained by each other.

ST_Touches(geometry A, geometry B): Returns TRUE if the geometries have at least one point in common, but their interiors do not intersect.

ST_Within(geometry A , geometry B): Returns true if the geometry A is completely inside geometry B

pg PostGIS教程:空间关系相关推荐

  1. postgresql 创建用户_Liunx系统安装PostgreSQL数据库教程,值得程序员收藏pg安装教程

    介绍 PostgreSQL是以加州大学伯克利分校计算机系开发的 POSTGRES,现在已经更名为PostgreSQL,版本 4.2为基础的对象关系型数据库管理系统(ORDBMS).PostgreSQL ...

  2. PostGIS教程十一:空间索引

    目录 一.空间索引是怎样工作的? 二.纯索引查询 三.分析 四.清理(VACUUM) 五.相关函数 回想一下,空间索引是空间数据库的三个关键特性之一.空间索引使得使用空间数据库存储大型数据集成为可能. ...

  3. PostGIS教程四:加载空间数据

    在各种库和应用程序的支持下,PostGIS提供了许多用于加载数据的选项. 本节将重点介绍使用PostGIS shapefile加载工具加载shapefile的基础知识. 一.PostGIS shape ...

  4. PostGIS教程五:数据

    目录 一.nyc_census_blocks 二.nyc_neighborhoods 三.nyc_streets 四.nyc_subway_stations 五.nyc_census_sociodat ...

  5. PostGIS教程十:空间连接

    目录 一.连接和汇总 二.高级连接 三.空间连接练习 空间连接(spatial joins)是空间数据库的主要组成部分,它们允许你使用空间关系作为连接键(join key)来连接来自不同数据表的信息. ...

  6. PG+POSTGIS地图空间位置网格聚合算法

    目录 PG核心分包函数WIDTH_BUCKET 聚合点的归类过程演示 空间聚合效果展示 大规模空间数据方案 PG,Postgresql数据库的简称,POSGIS是空间函数扩展支持插件集成了很多数据库级 ...

  7. PostGIS教程二:PostGIS的安装

    目录 一.下载安装程序 二.安装PostgreSQL 三.安装PostGIS 一.下载安装程序 在安装PostGIS前首先必须安装PostgreSQL,然后在安装好的Stack Builder中选择安 ...

  8. PostGIS教程十三:地理

    目录 一.使用Geography 二.创建一个Geography表 三.转换为Geometry 四.为什么使用Geography 坐标为"地理(geographics)"或者说是& ...

  9. PostGIS教程三:创建空间数据库

    目录 一.PgAdmin 二.创建一个数据库 三.函数列表 一.PgAdmin PostgreSQL有许多管理工具,主要的一个是psql,一个输入SQL命令查询的命令行工具. 另一个流行的Postgr ...

最新文章

  1. [PHP] 访问MySQL
  2. mysql8.0创建属性_MySQL8.0新特性——资源管理
  3. 【入门6】函数与结构体(今天刷洛谷了嘛)
  4. 编译文件出错fatal error: GL/glew.h: No such file or directory
  5. 学生信息管理系统(c++源代码实现)
  6. Linux查看分析任务计划命令,Linux任务计划crontab
  7. Unity MRTK 制作按钮调整大小
  8. 力扣14最长公共子串
  9. visio怎么画球_cad怎么画装配图
  10. 从大数据的角度看 房价一定会下跌
  11. HTML的head,头头头头!!!
  12. git目录下object文件过大清理
  13. Numpy创建正态分布和均匀分布
  14. 一个清华差生10年奋斗经历
  15. 成功誓言之我永远不再自怜自贱
  16. eclipse新建类auther自填充
  17. matches()方法的使用规则
  18. PCIe TLP详解
  19. linux vt码的学习和使用
  20. 2--java面向对象语法学习(部分1-变量,重载,重写)

热门文章

  1. 《那一场昨夜的长风》
  2. linux远程ipv6端口,SSH端口转发笔记(ipv6 与 端口映射)
  3. 因程序员开发速度太慢,公司索赔90万败诉后不服申请再审,法院判了
  4. oracle10g安装教程
  5. gophp解释器_[2020年面试题-PHP 与 golang] .Go 和 PHP 在运行的时候有什么区别和优势...
  6. Opencv教程(Python)
  7. 【四足机器人】SOLO技术详解--(1)介绍(2)平台和机器人概述【翻译】
  8. PaddleWeekly | ArcFace Paddle全面开源,人脸识别也可以轻松实战
  9. 使用SDK查看apk文件简单信息:包名、版本
  10. 在vue中使用海康插件实现视频监控,视频直播方法一(RTMP流加Flash加videoJS)