PostGIS教程九:空间关系

 

目录

一、ST_Equals

二、ST_Intersects、ST_Disjoint、ST_Crosses和ST_Overlaps

三、ST_Touches

四、ST_Within和ST_Contains

五、ST_Distance和ST_DWithin

六、空间关系练习


   

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

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

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

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

一、ST_Equals

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

_images/st_equals.png

    如果两个相同类型的几何图形具有相同的xy坐标值,即如果第二个图形与第一个图形的坐标信息相等(相同),则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测试几何图形是否相交。

_images/st_intersects.png

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

_images/st_disjoint.png

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

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

    事实上测试"not intersect"通常比测试"disjoint"更有效,因为intersect测试可以使用空间索引

_images/st_crosses.png

    对于multipoint/polygonmultipoint/linestringlinestring/linestringlinestring/polygonlinestring/multipolygon的比较,如果相交生成的几何图形的维度小于两个源几何图形的最大维度,且相交集位于两个源几何图形的内部,则ST_Crosses(geometry A, geometry B)将返回TRUE

_images/st_overlaps.png

    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()测试两个几何图形是否在它们的边界上接触,但在它们的内部不相交。

_images/st_touches.png

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

四、ST_Within和ST_Contains

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

_images/st_within.png

    如果第一个几何图形完全位于第二个几何图形内,则ST_Within(geometry A, geometry B)返回TRUEST_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米的缓冲区内有多少棵树?"这样的问题很有用,你不必计算实际的缓冲区,只需测试距离关系即可。

_images/st_dwithin.png

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

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

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

_images/broad_st.jpg

六、空间关系练习

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

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

  • 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
);

_images/atlantic_commons.jpg

    ④大约有多少人住在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
  );

  • 23
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
PostGIS是一个开源的地理信息系统(GIS)扩展,可与PostgreSQL数据库一起使用。PostGIS教程提供了使用PostGIS进行地理数据存储,查询和分析的指导。 首先,PostGIS使用需要在PostgreSQL数据库中安装和启用PostGIS扩展。安装完毕后,可以创建一个新的空间数据库或将PostGIS添加到现有数据库中。 接下来,学习如何在PostGIS中导入和管理地理数据。可以使用常见的地理信息文件格式(如Shapefile)或使用其他GIS软件生成的数据进行导入。导入后,可以使用SQL命令查询和分析地理数据。 PostGIS支持多种地理数据类型,如点(Point),线(LineString)和面(Polygon)。可以使用这些数据类型创建空间表,然后将地理数据插入到这些表中。还可以在表中创建索引来提高查询性能,并使用规则和触发器来实现数据完整性和一致性。 除了基本的地理数据管理外,PostGIS还提供了强大的地理分析功能。例如,可以使用PostGIS函数计算两个地理对象之间的距离,或者使用缓冲区操作创建一个围绕地理对象的缓冲区区域。还可以执行空间联接操作,通过对两个地理对象进行交集、并集或差集操作来分析它们之间的空间关系。 此外,PostGIS还支持地理数据的可视化。可以使用GIS软件(如QGIS)或Web地图库(如Leaflet)来加载和显示PostGIS中的地理数据。还可以利用GeoJSON格式将地理数据导出到其他GIS工具中进行处理和分析。 总的来说,PostGIS教程是学习使用PostGIS进行地理数据存储、查询和分析的指南。通过掌握PostGIS的基本概念和操作,可以更好地利用PostgreSQL数据库构建和管理地理信息系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值