Jobbo90
Jobbo90

Reputation: 175

Why does filling a SpatialLinesDataFrame with lines throw an error?

I'm having trouble aggregating lines, resulting from a loop, in a SpatialLinesDataFrame (or similar).

I have a range of coastlines which I itirate over, create perpendicular transects at equal intervals and ultimately like to store those transects. For each transect I will in a later stage run some calculations, like overlaying it on a raster to calculate the extent of a certain feature. So the final SpatialLinesDataFrame should allow me to access individual lines in a loop.

Reproducable output table that corresponds to a shape ID in a shapefile.

Class is an example of metadata for that line I'd like to keep.

# 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))

Throws an eror:

Error in slot(sl, "lines") : cannot get a slot ("lines") from an object of type "list"

Ultimately it probably boils down to the fact I don't fully understand the working of SpatialDataFrame and the property of the SpatialLines, I read through documentation etc. and I was thinking the corresponding ID's between lines_sf and out are not matching. But the error suggests otherwise?

Thanks in advance!

Upvotes: 0

Views: 756

Answers (1)

Z.Lin
Z.Lin

Reputation: 29085

Your lines is a list, not a SpatialLines object. You can verify this by entering class(lines) in the console.

To make each item in lines a Lines object, try replacing the last line of code in your loop with:

lines[[n]] <- Lines(list(Line(x)), ID = as.character(out[n, 1]))

Once we get out of the loop, we have lines as a list of Lines objects, but it is not a SpatialLines object itself. Fortunately, creating a SpatialLines object out of a list of Lines objects is very straightforward:

lines <- SpatialLines(lines, 
                      proj4string = CRS(as.character(kustlijn2001@proj4string)))

To create df, the IDs in lines need to match the row names in data.frame(out). We can specify them explicitly:

df <- SpatialLinesDataFrame(lines, 
                            data.frame(out, row.names = out[, 1]))

This is what df looks like. Is it what you expect?

> 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

Upvotes: 2

Related Questions