与SpatialPolygonsDataFrame对象相交的SpatialLinesDataFrame列表的R嵌套循环

与SpatialPolygonsDataFrame对象相交的SpatialLinesDataFrame列表的R嵌套循环,r,for-loop,spatial,sp,rgdal,R,For Loop,Spatial,Sp,Rgdal,我有一系列的步骤需要在一个SpatialLinesDataFrame(“线”)对象列表上完成,这些对象基于它们与多功能SpatialPolygonsDataFrame(“多边形”)对象中的各个特征的关系。简言之,每个线列表元素起源于单个多边形特征内部,可能会也可能不会通过一个或多个其他多边形特征。我想更新每个线元素,以将原始多边形连接到与线元素相交的每个多边形的第一个接触点。因此,每个线元素可能成为多个新的线特征(n=相交多边形的数量) 我希望能有效地完成这项工作,因为我的线列表和多边形特征非常

我有一系列的步骤需要在一个
SpatialLinesDataFrame
(“线”)对象列表上完成,这些对象基于它们与多功能
SpatialPolygonsDataFrame
(“多边形”)对象中的各个特征的关系。简言之,每个线列表元素起源于单个多边形特征内部,可能会也可能不会通过一个或多个其他多边形特征。我想更新每个线元素,以将原始多边形连接到与线元素相交的每个多边形的第一个接触点。因此,每个线元素可能成为多个新的线特征(n=相交多边形的数量)

我希望能有效地完成这项工作,因为我的线列表和多边形特征非常多。我在下面提供了示例数据和我尝试做的逐步描述。我是R新手,不是程序员,所以我不知道我的建议是否有效

库(sp)
图书馆(rgdal)
图书馆(光栅)
###示例数据准备开始
#示例“RDCO区域公园”数据可在此处下载:
https://data-rdco.opendata.arcgis.com/datasets 组ID=1950175c56c24073bb5cef3900e19460

parks这里有一个使用
sf
包的解决方案。我将使用您创建的对象并将它们转换为
sf
,尽管您可以将shapefile读入
sf
对象并从头开始创建它们,因此如果没有其他理由使用
sp
对象,我建议您这样做

使用以下软件包:

library(sf)
library(dplyr)
转换多边形。我正在从
parks\u sub
中删除一堆列,以便它可以更整洁地打印-如果需要,请不要删除它们:

p = st_as_sf(parks_sub)
p = p[,c("OBJECTID","PARK_NAME")]
转换行。我只打算使用第一行对象,在列表上写一个循环来完成整个集合:

l1 = st_as_sf(lineldf[[1]])
下一步是计算直线和多边形之间的所有交点。必须:a)将多边形转换为线串,否则多边形和线的交点就是线;b)使用
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...

所以现在将所有这些都封装到一个函数中,并循环到您的行和完成的工作上

是否希望以不与多边形相交的线结束?他们停在任何多边形的第一个边上,然后从远边开始有一条新线?如果一条线两次穿过同一个多边形,就像你的两个例子中那样,会怎么样?这个URL让我进入一个404未找到的页面-它有一个空格。从这里下载?好的,我想我现在明白了-线会重叠。我有一些想法,但我宁愿使用新的
sf
空间类,而不是
sp
类。两种方式都可以进行转换,这样就可以了……此处创建的直线不符合“每个直线列表元素源自单个多边形要素内部”——第一个坐标位于左下角,位于任何多边形的外部,第二个坐标位于多边形的内部。我现在有一个解决方案,假设你知道你想从哪一端开始…好吧,如果我翻转测试线中点的顺序,使第一个点始终是多边形内更准确描述数据的点?非常感谢你花时间帮助我。一些问题:(1)当我尝试像您那样向绘图中添加nlines时,我收到以下错误消息:绘图中出错。窗口(…):需要有限的“xlim”值。此外:警告消息:1:未知或未初始化列:“geom”…(2)我也不确定如何“将所有这些内容包装到函数中,并在[my]行上循环”。请您总结一下如何使用您创建的代码来执行此操作?(3)请参阅我对您上述评论的回复:源自多边形内部的线条。如果这改变了你的答案,也请让我知道。我不能在这里教你关于R编程的所有知识,所以你应该先学习一些教程,直到你知道如何做列表循环和编写函数。
> 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...