sf | 判断点线面等几何对象的空间位置关系

根据交点的个数和位置,两个几何要素之间的空间位置关系可分为相离、相切、相交和包含四种:

  • 相离是指两个几何要素没有交点,相交是指两个要素存在交点,广义上讲相切和包含是相交关系中的特殊情况;

  • 相切是指交点全部位于其中一个要素的边界上;

  • 包含关系是指一个要素位于另一个要素的内部,这里的“内部”有时也包括“边界”;

  • 面的边界和内部是有明显区别的;对于线要素来讲,它的“边界”是指其端点;而对于点要素来讲,其不存在边界和内部的分别。

1 语法规则

sf中的geos_binary_pred()系列函数用于判断两个几何对象的位置关系:

geos_binary_pred(x, y, sparse = TRUE, ...)
  • 函数返回结果只有TRUE(1)和FASLE(0)两种;

  • x和y是sf、sfc或sfg对象,对应的几何要素类型可以是点、线或面;

  • sparse参数默认为TRUE,结果以稀疏形式返回,即只返回结果为1的情况,若没有为1的情况则返回值为空;若sparse设置为FASLE会返回所有情况的结果。

2 函数功能

相离函数

  • st_disjoint():当输入的两个几何要素没有交点时为真。

相切函数

  • st_touches():主要用于判断线-面和面-面相切关系,当交点全在面的边界上时为真;也可用于判断点-线相切,此时线的“边界”是指其端点。

相交函数

  • st_intersects():当存在至少一个交点时为真,与st_disjoint()功能相反;

  • st_crosses():主要用于判断线-面交叉关系,当线的一部分在面内,一部分在面外时为真;

  • st_overlaps():主要用于判断面-面交叉关系,当两个面有部分重叠时为真;

包含函数

  • st_within():主要用于判断其他要素是否在面内或点-线、线-线包含关系,允许有交点在面的边界上,但不允许所有的交点都在边界上,即不允许点在线的端点上,线完全在面的边界上;

  • st_contains():参数顺序与st_within()颠倒,其他同st_within()

  • st_contains_properly():不允许有交点边界上(包括线的端点),其他同st_contains()

  • st_covers():适用范围最广的包含函数,即使交点全在边界上也仍然为真。

  • st_equals():当几何要素完全重合时为真;

  • st_is_within_distance():与st_within()类似,但多了dist参数,可以设置距离门槛进行模糊判断。

3 相似、相反函数功能对比

创建示例数据

library(sf)

p1 <- c(0, 0)
p2 <- c(0, 2)
p3 <- c(4, 2)
p4 <- c(4, 0)
p5 <- c(1, 1)
p6 <- c(3, 1)
p7 <- c(2, 3)
p8 <- c(0, 3)

pt1 <- st_point(p1)
pt2 <- st_point(p6)
pt3 <- st_point(p7)

ln1 <- st_linestring(rbind(p3, p4))
ln2 <- st_linestring(rbind(p5, p6))
ln3 <- st_linestring(rbind(p1, p2, p8))
ln4 <- st_linestring(rbind(p5, p8))
ln5 <- st_linestring(rbind(p1, p4, p6, p5))

pg1 <- st_polygon(list(rbind(p1, p2, p3, p4, p1)))
pg2 <- st_polygon(list(rbind(p5, p6, p7, p5)))
pg3 <- st_polygon(list(rbind(p2, p3, p7, p2)))

 

3.1 st_intersects()st_disjoint()

这两个函数功能相反,但在用法上也存在相似之处,如只关心有无交点,而不关心交点的位置,不考虑输入对象x和y的顺序。

# 点在线的端点上
st_intersects(pt1, ln3)
st_disjoint(pt1, ln3)

# 点在面的边界上
st_intersects(pt1, pg1)
st_disjoint(pt1, pg1)

# 点在面的内部
st_intersects(pt2, pg1)
st_disjoint(pt2, pg1)
# 部分输出结果
> # 点在线的端点上
> st_intersects(pt1, ln3)
Sparse geometry binary predicate list of length 1, where the predicate was `intersects'
 1: 1
> st_disjoint(pt1, ln3)
Sparse geometry binary predicate list of length 1, where the predicate was `disjoint'
 1: (empty)

3.2 st_touches()

相切函数也不区分输入对象的顺序。

当其中一个要素是面要素时,相切是指交点全在面的边界上

# 以下返回值皆为真
# 点在面的边界上
st_touches(pt1, pg1)
# 线完全在面的边界上
st_touches(ln1, pg1)
# 线的一部分在面的边界上,另一部分在面外
st_touches(ln3, pg1)
# 面和面共边
st_touches(pg1, pg3)

当输入对象只有点或线要素且至少有一个为线要素时,相切是指交点在线的端点上

# 以下返回值皆为真
# 点在线的端点上
st_touches(pt1, ln3)
# 线与线的交点是其中一个线的端点
st_touches(ln3, ln4)

# 以下返回值皆为假
# 两个对象全为点且重合
st_touches(pt1, pt1)
# 点在线上但不在端点上
st_touches(pt2, ln5)
# 线和线存在交点不是端点
st_touches(ln2, ln5)

3.3 st_crosses()st_overlaps()

相同点:

  • 不区分输入对象的顺序;

  • 判断的都是狭义的相交关系,即不包括相切和包含关系,判断广义的相交关系可以使用st_intersects()函数。

不同点:

  • st_crosses()用于判断线-线或线-面相交关系,面面关系一律返回FASLE;

  • st_overlaps()则用于判断面-面相交关系,线面关系一律返回FASLE。

# 以下皆返回为真
# 线的一部分在面内,一部分在面外
st_crosses(ln4, pg1)
# 面与面有重合部分也有不重合部分
st_overlaps(pg2, pg3)

# 以下皆返回为假
# 线-面相切
st_crosses(ln3, pg1)
# 线-线“相切”
st_crosses(ln3, ln4)
# 面-面相切
st_overlaps(pg1, pg3)

3.4 st_within()st_contains()st_covers()

相同点:

  • 都是判断包含关系的函数,区分输入对象的顺序;

不同点:

  • st_within()的逻辑关系是“x包含于y”,st_contains()st_covers()是“x包含y”;

  • st_contains_properly()是最狭义的包含关系,不允许在边界有交点;

  • st_within()st_contains()允许部分交点在边界上;

  • st_covers()是最广义的包含关系,允许所有交点均落在边界上的情况。

比较以下几种情况的输出结果:

# 以下除特殊注释外返回皆为真
# 线完全在面内
st_within(ln2, pg1)
st_contains(pg1, ln2)
st_contains_properly(pg1, ln2)
st_covers(pg1, ln2)

# 线的一部分在面的边界上,另一部分在面内
st_contains(pg1, ln5)
st_contains_properly(pg1, ln5) # 返回假
st_covers(pg1, ln5)

# 线完全在面的边界上
st_contains(pg1, ln1) # 返回假
st_contains_properly(pg1, ln1) # 返回假
st_covers(pg1, ln1)

4 判断多要素对象的位置关系

以上均是以单要素几何对象为例,即sfg对象,而对于sf对象或sfc对象来说,它的每一行都代表了一个几何要素。上述函数在处理多要素对象的空间位置关系时,会逐个判断x中的每个要素和y中的每个要素之间的位置关系,结果以矩阵或列表形式输出。

library(sf)
nc <- st_read(system.file("shape/nc.shp", package = "sf"))
sf1 <- filter(nc, AREA > 0.2)
dim(sf1)
sf2 <- filter(nc, SID74 > 5)
dim(sf2)

# 结果以稀疏形式展示
a <- st_intersects(sf1, sf2)
class(a)
# 结果以矩阵形式展示
b <- st_intersects(sf1, sf2, sparse = F)
class(b)
dim(b)
# 部分输出结果
> dim(sf1)
[1] 11 15
> dim(sf2)
[1] 38 15

> class(a)
[1] "sgbp" "list"
> class(b)
[1] "matrix"
> dim(b)
[1] 11 38

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值