这是一个使用以下解决方案sf
包裹。我将使用您创建的对象并将它们转换为sf
,尽管您可以将 shapefile 读入sf
对象并从头开始创建它们,所以如果没有其他原因需要使用sp
我推荐的对象。
使用这些包:
library(sf)
library(dplyr)
转换多边形。我正在删除大量列parks_sub
只是为了它可以打印得更整齐 - 如果您需要它们,请不要丢弃它们:
p = st_as_sf(parks_sub)
p = p[,c("OBJECTID","PARK_NAME")]
转换线。我只会使用你的第一行对象,在你的列表上写一个循环来完成一整套:
l1 = st_as_sf(lineldf[[1]])
下一步是计算直线和多边形之间的所有交点。您必须:a)将多边形转换为线串,否则多边形和线的交点是一条线,b)当一条线多次穿过多边形时,将“MULTIPOINT”交点转换为一组 POINT 对象,使用st_cast
:
pts = st_cast(st_cast(st_intersection(l1,
st_cast(p,"MULTILINESTRING")
),"MULTIPOINT"),"POINT")
接下来我们需要直线的第一个点。对于您在示例中创建的数据,多边形中的线端实际上是第二个点,因此我将在此处提取它。
first_point = st_cast(l1$geom,"POINT")[2]
如果在你的真实数据中它是第一点,那么就把[1]
在那里。如果要看情况的话那就是另一个小问题了。
现在计算从第一个点到所有交点的距离:
pts$d_first = st_distance(first_point, pts)[1,]
所以我们现在想要的是同一个多边形ID定义的每组点中最近的交点。
near_pts = pts %>% group_by(OBJECTID) %>% filter(d_first==min(d_first))
然后从第一个点到最近的点构建所需的线:
nlines = st_cast(st_union(near_pts, first_point),"LINESTRING")
以宽度递减的方式绘制多边形和线条以显示重叠:
plot(p$geom)
plot(nlines$geom, lwd=c(10,7,4), col=c("black","grey","white"), add=TRUE)
请注意,这三条线包括从第一个点到其所在多边形边界的一条短线(白色) - 如果您不希望这样,您可以在构建之前过滤掉距数据框最近距离的点线 - 但这假设第一个点位于多边形内部......
nlines
保留线相交的多边形的属性以及线的 ID:
> nlines
Simple feature collection with 3 features and 4 fields
geometry type: LINESTRING
dimension: XY
bbox: xmin: 310276 ymin: 5522728 xmax: 333000 ymax: 5530000
epsg (SRID): 26911
proj4string: +proj=utm +zone=11 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs
id OBJECTID PARK_NAME d_first geometry
1 181 2254 Mission Creek 6794.694 m LINESTRING (326528.6 552792...
2 181 1831 Glen Canyon 23859.161 m LINESTRING (310276 5522728,...
3 181 1838 Black Mountain 1260.329 m LINESTRING (331799.6 552961...
所以现在将所有这些包装到一个函数中并在您的线路上循环并完成工作!?