PostGIS:空间关系

转发:https://blog.csdn.net/qq_35732147/article/details/85615057数据库

目录函数

1、ST_Equals测试

2、ST_Intersects、ST_Disjoint、ST_Crosses和ST_Overlapsspa

3、ST_Touches.net

4、ST_Within和ST_Contains3d

5、ST_Distance和ST_DWithincode

6、空间关系练习blog


   

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

    空间数据库之因此强大,是由于它们不只能存储几何图形,并且还可以比较几何图形之间的关系ip

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

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

1、ST_Equals

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

_images/st_equals.png

    若是两个相同类型的几何图形具备相同的x、y坐标值,即若是第二个图形与第一个图形的坐标信息相等(相同),则ST_Equals()返回TRUE

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

  1.   SELECT name, geom, ST_AsText(geom)
  2.   FROM nyc_subway_stations
  3.   WHERE name = 'Broad St';

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

  1.   SELECT name
  2.   FROM nyc_subway_stations
  3.   WHERE ST_Equals(geom, '0101000020266900000EEBD4CF27CF2141BC17D69516315141');

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

2、ST_Intersects、ST_Disjoint、ST_Crosses和ST_Overlaps

    ST_Intersects、ST_Crosses和ST_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/polygon、multipoint/linestring、linestring/linestring、linestring/polygon和linestring/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()函数肯定其所在社区:

  1.   SELECT name, ST_AsText(geom)
  2.   FROM nyc_subway_stations
  3.   WHERE name = 'Broad St';

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

3、ST_Touches

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

_images/st_touches.png

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

4、ST_Within和ST_Contains

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

_images/st_within.png

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

    若是第二个几何图形彻底包含在第一个几何图形内,则ST_Contains(geometry A, geometry B)返回TRUE。

5、ST_Distance和ST_DWithin

    一个常见的GIS问题是"找到这个物体周围距离X的全部其余物体"。

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

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

    为了测试两个几何图形之间的距离是否在某个范围以内,ST_DWithin()函数提供了一个这样的的功能。

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

_images/st_dwithin.png

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

  1.   SELECT name
  2.   FROM nyc_streets
  3.   WHERE ST_DWithin(
  4.  geom,
  5.  ST_GeomFromText( 'POINT(583571 4506714)',26918),
  6.   10
  7.  );

    咱们能够在地图上验证答案,Broad St站其实是在Wall、Broad和Nassau街道的十字路口。

_images/broad_st.jpg

6、空间关系练习

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

    还请记住咱们如今数据库中已经具备的表:

  • 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值是什么?

  1.   SELECT ST_AsText(geom)
  2.   FROM nyc_streets
  3.   WHERE name = 'Atlantic Commons';

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

  1.   SELECT name, boroname
  2.   FROM nyc_neighborhoods
  3.   WHERE ST_Intersects(
  4.  geom,
  5.  ST_GeomFromText( 'LINESTRING(586782 4504202,586864 4504216)', 26918)
  6.  );

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

    更重要的是,咱们还对坐标进行了四舍五入,以使它们更易于阅读,这实际上改变告终果:咱们如今不能使用ST_Touches()方法来找出哪些道路链接Atlantic Commons,由于坐标再也不与原来的坐标彻底相同。

    ③Atlantic Commons与哪些街道相连?

  1.   SELECT name
  2.   FROM nyc_streets
  3.   WHERE ST_DWithin(
  4.  geom,
  5.  ST_GeomFromText( 'LINESTRING(586782 4504202,586864 4504216)', 26918),
  6.   0.1
  7.  );

_images/atlantic_commons.jpg

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

  1.   SELECT Sum(popn_total)
  2.   FROM nyc_census_blocks
  3.   WHERE ST_DWithin(
  4.  geom,
  5.  ST_GeomFromText( 'LINESTRING(586782 4504202,586864 4504216)', 26918),
  6.   50
  7.  );

相关文章
相关标签/搜索