如何找到沿线的路径,直到它第一次与多边形相交?
How to find the path along a line until it first intersects a polygon?
我有一条路径作为与多边形相交的一系列有序点。我想提取第一个多边形交点之前的线部分。
我试图通过计算与多边形的差异来分割路径,但该线也在其自相交处分割(参见示例)。我需要从开始一直提取路径的完整部分,直到它第一次与多边形相交(示例中的蓝色方块)。
# A wonky line that intersects itself
l = sf::st_linestring(cbind(cos((0:100) * pi / 50), sin((0:100) * pi / 15 )))
# A polygon that intersects the line
p = sf::st_polygon(list(cbind(c(-.3, -.3, -.2, -.2, -.3), c(-.3, -.2, -.2, -.3, -.3))))
# Visualisation of the problem
plot(l)
plot(p, add = TRUE, col = "blue")
# Taking the first fragment of the difference does not work as the path intersects and divides itself
d = sf::st_difference(l, p)
plot(sf::st_linestring(d[[1]]), add = TRUE, col = "red")
在示例中,路径被所有交叉点(甚至在其自身上)分段,因此路径的第一部分不会一直延伸到多边形。我怀疑 sf 包中有一个函数专门用于我的目的 - 但我还没有找到它。
自相交线串不是 "simple"(参见 st_is_simple(l)
),尽管它是 "valid"(参见 st_is_valid(l)
),并且 sf
这里给大家介绍一个简单的功能。我们需要做的是使用简单的 LINESTRINGs 并重建更长的线特征...
首先将波浪线与多边形进行比较 - d
然后是一个多线串:
> d = st_difference(l,p)
如果我们将其转换为 sfc
,然后将其转换为 LINESTRING,我们将获得单独的 LINESTRING 几何体中的部分:
> dl = st_cast(st_sfc(d),"LINESTRING")
其中有 8 个:
> length(dl)
[1] 8
那么从第一个开始,我们需要跟随多少个才能到达多边形?让我们得到线段与多边形的交点——这是一个稀疏列表——如果没有交集,元素的长度为 0,如果有交集,则元素的长度大于 0:
> sint = st_intersects(dl,p)
该列表的第一个 不为零的元素 是第一个到达多边形的线串:
> min(which(lengths(sint)>0))
[1] 3
这意味着我们到多边形的线是前三个线串:
> dl[1:3]
Geometry set for 3 features
geometry type: LINESTRING
dimension: XY
bbox: xmin: -0.220294 ymin: -0.9945219 xmax: 1 ymax: 0.9945219
epsg (SRID): NA
proj4string: NA
LINESTRING (1 0, 0.9980267 0.2079117, 0.9921147...
LINESTRING (0.9510565 0.8660254, 0.9297765 0.95...
LINESTRING (0.309017 -0.8660254, 0.309017 -0.86...
您可以将这些组合成一个特征并绘制:
> plot(l)
> plot(p,add=TRUE,col="red")
> topoly = st_union(dl[1:3])
> plot(topoly, add=TRUE, lwd=3)
我有一条路径作为与多边形相交的一系列有序点。我想提取第一个多边形交点之前的线部分。
我试图通过计算与多边形的差异来分割路径,但该线也在其自相交处分割(参见示例)。我需要从开始一直提取路径的完整部分,直到它第一次与多边形相交(示例中的蓝色方块)。
# A wonky line that intersects itself
l = sf::st_linestring(cbind(cos((0:100) * pi / 50), sin((0:100) * pi / 15 )))
# A polygon that intersects the line
p = sf::st_polygon(list(cbind(c(-.3, -.3, -.2, -.2, -.3), c(-.3, -.2, -.2, -.3, -.3))))
# Visualisation of the problem
plot(l)
plot(p, add = TRUE, col = "blue")
# Taking the first fragment of the difference does not work as the path intersects and divides itself
d = sf::st_difference(l, p)
plot(sf::st_linestring(d[[1]]), add = TRUE, col = "red")
在示例中,路径被所有交叉点(甚至在其自身上)分段,因此路径的第一部分不会一直延伸到多边形。我怀疑 sf 包中有一个函数专门用于我的目的 - 但我还没有找到它。
自相交线串不是 "simple"(参见 st_is_simple(l)
),尽管它是 "valid"(参见 st_is_valid(l)
),并且 sf
这里给大家介绍一个简单的功能。我们需要做的是使用简单的 LINESTRINGs 并重建更长的线特征...
首先将波浪线与多边形进行比较 - d
然后是一个多线串:
> d = st_difference(l,p)
如果我们将其转换为 sfc
,然后将其转换为 LINESTRING,我们将获得单独的 LINESTRING 几何体中的部分:
> dl = st_cast(st_sfc(d),"LINESTRING")
其中有 8 个:
> length(dl)
[1] 8
那么从第一个开始,我们需要跟随多少个才能到达多边形?让我们得到线段与多边形的交点——这是一个稀疏列表——如果没有交集,元素的长度为 0,如果有交集,则元素的长度大于 0:
> sint = st_intersects(dl,p)
该列表的第一个 不为零的元素 是第一个到达多边形的线串:
> min(which(lengths(sint)>0))
[1] 3
这意味着我们到多边形的线是前三个线串:
> dl[1:3]
Geometry set for 3 features
geometry type: LINESTRING
dimension: XY
bbox: xmin: -0.220294 ymin: -0.9945219 xmax: 1 ymax: 0.9945219
epsg (SRID): NA
proj4string: NA
LINESTRING (1 0, 0.9980267 0.2079117, 0.9921147...
LINESTRING (0.9510565 0.8660254, 0.9297765 0.95...
LINESTRING (0.309017 -0.8660254, 0.309017 -0.86...
您可以将这些组合成一个特征并绘制:
> plot(l)
> plot(p,add=TRUE,col="red")
> topoly = st_union(dl[1:3])
> plot(topoly, add=TRUE, lwd=3)