为什么用线条填充 SpatialLinesDataFrame 会引发错误?
Why does filling a SpatialLinesDataFrame with lines throw an error?
我在 SpatialLinesDataFrame(或类似的)中聚合由循环产生的线时遇到问题。
我遍历了一系列海岸线,以相等的间隔创建垂直横断面,最终喜欢存储这些横断面。对于每个样带,我将在稍后阶段 运行 进行一些计算,例如将其叠加在栅格上以计算特定特征的范围。所以最终的 SpatialLinesDataFrame 应该允许我访问循环中的各个行。
与 shapefile 中的形状 ID 相对应的可重现输出 table。
- Position 对应于唯一 ID 和距离 Line 起点的米数。
- CoordX和CoordY为直线上的坐标(样线起点)
Endx / EndY 是横断面的端点
Class 是我想保留的该行的元数据示例。
# for each coastline inside the shape:
position <- seq(0,3000, by=500)
coordX <- c(279501, 275678, 271002, 270944, 266825, 273316, 278284)
coordY <- c(983194.8, 981770.6, 975915.3, 975824.3, 968631.0, 963332.4, 963716.7)
endx <- c(279501.9, 275678.4, 271002.6, 270944.6, 266825.3, 273316.2, 278284.1)
endy <- c(983194.8, 981770.6, 975915.3, 975824.3, 968631.0, 963332.4, 963716.7)
class <- c(3,3,3,3,3,3,3)
out<- cbind(position, class, coordX, coordY, endx, endy)
beginpoint <- cbind(out[,3], out[,4])
endpoint <- cbind(out[,5], out[,6])
lines <- vector('list', nrow(out)) # empty line vector
# loop over starting points on the line segment and create transects
for(n in seq_along(lines_sf)){
# n = 1
col_names <- list('lon', 'lat')
row_names <- list('begin', 'end')
# dimnames < list(row_names, col_names)
x <- as.matrix(rbind(beginpoint[n], endpoint[n,]))
dimnames(x) <- list(row_names, col_names)
# Sl <- Line(x) # line based on begin & end coordinates
# S1 <- Lines(list(Sl), ID = output$pos[n])
lines[[n]] <- SpatialLines(list(Lines(list(Line(x)), as.character(out[n,1]))),
proj4string = CRS(as.character(kustlijn2001@proj4string)))
}
df <- SpatialLinesDataFrame(lines_sf, data.frame(out))
抛出错误:
Error in slot(sl, "lines") : cannot get a slot ("lines") from an
object of type "list"
最终可能归结为我不完全理解 SpatialDataFrame 的工作原理和 SpatialLines 的 属性,我通读了文档等,我在想 [= 之间的相应 ID 32=] 和 out 不匹配。但错误提示并非如此?
提前致谢!
您的 lines
是一个列表,而不是 SpatialLines 对象。您可以通过在控制台中输入 class(lines)
来验证这一点。
要使 lines
中的每个项目成为 Lines 对象,请尝试将循环中的最后一行代码替换为:
lines[[n]] <- Lines(list(Line(x)), ID = as.character(out[n, 1]))
一旦我们退出循环,我们就有了 lines
作为 Lines 对象的列表,但它本身不是 SpatialLines 对象。幸运的是,从 Lines 对象列表中创建 SpatialLines 对象非常简单:
lines <- SpatialLines(lines,
proj4string = CRS(as.character(kustlijn2001@proj4string)))
要创建 df
,lines
中的 ID 需要与 data.frame(out)
中的行名称匹配。我们可以明确指定它们:
df <- SpatialLinesDataFrame(lines,
data.frame(out, row.names = out[, 1]))
这就是 df
的样子。是你期待的吗?
> df
An object of class "SpatialLinesDataFrame"
Slot "data":
position class coordX coordY endx endy
0 0 3 279501 983194.8 279501.9 983194.8
500 500 3 275678 981770.6 275678.4 981770.6
1000 1000 3 271002 975915.3 271002.6 975915.3
1500 1500 3 270944 975824.3 270944.6 975824.3
2000 2000 3 266825 968631.0 266825.3 968631.0
2500 2500 3 273316 963332.4 273316.2 963332.4
3000 3000 3 278284 963716.7 278284.1 963716.7
Slot "lines":
[[1]]
An object of class "Lines"
Slot "Lines":
[[1]]
An object of class "Line"
Slot "coords":
lon lat
begin 279501.0 279501.0
end 279501.9 983194.8
Slot "ID":
[1] "0"
... #omitted for brevity
我在 SpatialLinesDataFrame(或类似的)中聚合由循环产生的线时遇到问题。
我遍历了一系列海岸线,以相等的间隔创建垂直横断面,最终喜欢存储这些横断面。对于每个样带,我将在稍后阶段 运行 进行一些计算,例如将其叠加在栅格上以计算特定特征的范围。所以最终的 SpatialLinesDataFrame 应该允许我访问循环中的各个行。
与 shapefile 中的形状 ID 相对应的可重现输出 table。
- Position 对应于唯一 ID 和距离 Line 起点的米数。
- CoordX和CoordY为直线上的坐标(样线起点) Endx / EndY 是横断面的端点
Class 是我想保留的该行的元数据示例。
# for each coastline inside the shape:
position <- seq(0,3000, by=500)
coordX <- c(279501, 275678, 271002, 270944, 266825, 273316, 278284)
coordY <- c(983194.8, 981770.6, 975915.3, 975824.3, 968631.0, 963332.4, 963716.7)
endx <- c(279501.9, 275678.4, 271002.6, 270944.6, 266825.3, 273316.2, 278284.1)
endy <- c(983194.8, 981770.6, 975915.3, 975824.3, 968631.0, 963332.4, 963716.7)
class <- c(3,3,3,3,3,3,3)
out<- cbind(position, class, coordX, coordY, endx, endy)
beginpoint <- cbind(out[,3], out[,4])
endpoint <- cbind(out[,5], out[,6])
lines <- vector('list', nrow(out)) # empty line vector
# loop over starting points on the line segment and create transects
for(n in seq_along(lines_sf)){
# n = 1
col_names <- list('lon', 'lat')
row_names <- list('begin', 'end')
# dimnames < list(row_names, col_names)
x <- as.matrix(rbind(beginpoint[n], endpoint[n,]))
dimnames(x) <- list(row_names, col_names)
# Sl <- Line(x) # line based on begin & end coordinates
# S1 <- Lines(list(Sl), ID = output$pos[n])
lines[[n]] <- SpatialLines(list(Lines(list(Line(x)), as.character(out[n,1]))),
proj4string = CRS(as.character(kustlijn2001@proj4string)))
}
df <- SpatialLinesDataFrame(lines_sf, data.frame(out))
抛出错误:
Error in slot(sl, "lines") : cannot get a slot ("lines") from an object of type "list"
最终可能归结为我不完全理解 SpatialDataFrame 的工作原理和 SpatialLines 的 属性,我通读了文档等,我在想 [= 之间的相应 ID 32=] 和 out 不匹配。但错误提示并非如此?
提前致谢!
您的 lines
是一个列表,而不是 SpatialLines 对象。您可以通过在控制台中输入 class(lines)
来验证这一点。
要使 lines
中的每个项目成为 Lines 对象,请尝试将循环中的最后一行代码替换为:
lines[[n]] <- Lines(list(Line(x)), ID = as.character(out[n, 1]))
一旦我们退出循环,我们就有了 lines
作为 Lines 对象的列表,但它本身不是 SpatialLines 对象。幸运的是,从 Lines 对象列表中创建 SpatialLines 对象非常简单:
lines <- SpatialLines(lines,
proj4string = CRS(as.character(kustlijn2001@proj4string)))
要创建 df
,lines
中的 ID 需要与 data.frame(out)
中的行名称匹配。我们可以明确指定它们:
df <- SpatialLinesDataFrame(lines,
data.frame(out, row.names = out[, 1]))
这就是 df
的样子。是你期待的吗?
> df
An object of class "SpatialLinesDataFrame"
Slot "data":
position class coordX coordY endx endy
0 0 3 279501 983194.8 279501.9 983194.8
500 500 3 275678 981770.6 275678.4 981770.6
1000 1000 3 271002 975915.3 271002.6 975915.3
1500 1500 3 270944 975824.3 270944.6 975824.3
2000 2000 3 266825 968631.0 266825.3 968631.0
2500 2500 3 273316 963332.4 273316.2 963332.4
3000 3000 3 278284 963716.7 278284.1 963716.7
Slot "lines":
[[1]]
An object of class "Lines"
Slot "Lines":
[[1]]
An object of class "Line"
Slot "coords":
lon lat
begin 279501.0 279501.0
end 279501.9 983194.8
Slot "ID":
[1] "0"
... #omitted for brevity