PostGIS教程九:空间关系
目录
目录
二、ST_Intersects、ST_Disjoint、ST_Crosses和ST_Overlaps
到目前为止,我们只使用了测量(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_Intersects、ST_Crosses和ST_Overlaps测试几何图形是否相交。
如果两个图形有相同的部分,即如果它们的边界或内部相交,则ST_Intersects(geometry A, geometry B)返回TRUE。
ST_Intersects()方法的对立方法是ST_Disjoint(geometry A, geometry B)。
如果两个几何图形没有共同的部分,则它们不相交,反之亦然。
事实上测试”not intersect“通常比测试”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 subway station)为例,使用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()完全相反。
如果第二个几何图形完全包含在第一个几何图形内,则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街道的十字路口。
六、空间关系练习
下面是我们在上面部分涉及到的函数,它们应该对练习有用!
还请记住我们现在数据库中已经具有的表:
nyc_census_blocks
- blkid, popn_total, boroname, geom
nyc_streets
- name, type, geom
nyc_subway_stations
- name, geom
nyc_neighborhoods
- name, boroname, geom
练习:
①名为”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
);
转载自:https://blog.csdn.net/qq_35732147/article/details/85615057