I have a series of steps I need to complete on a list of SpatialLinesDataFrame
('lines' herein) objects based on their relationships with individual features within a multi-feature SpatialPolygonsDataFrame
('polygons') object. In short, each line list element originates inside a single polygon feature, and may or may not pass through one or more other polygon features. I want to update each line element to connect origin polygons to the first point of contact for each individual polygon intersected by the line element. So, each line element may become multiple new line features (n=number of intersected polygons).
I would like to do this efficiently as my lines lists and polygon features are numerous. I have provided example data and STEP-wise description of what I am trying to do below. I am new to R and not a programmer, so I don't know if any of what I propose is valid.
library(sp)
library(rgdal)
library(raster)
###example data prep START
#example 'RDCO Regional Parks' data can be downloaded here:
https://data-rdco.opendata.arcgis.com/datasets group_ids=1950175c56c24073bb5cef3900e19460
parks <- readOGR("/path/to/example/data/RDCO_Regional_Parks/RDCO_Regional_Parks.shp")
plot(parks)
#subset watersheds for example
parks_sub <- parks[parks@data$Shapearea > 400000,]
plot(parks_sub, col='green', axes = T)
#create SpatialLines from scratch
pts_line1 <- cbind(c(308000, 333000), c(5522000, 5530000))
line1 <- spLines(pts_line1, crs = crs(parks_sub))
plot(line1, axes=T, add=T) #origin polygon = polyl[[4]] = OBJECTID 181
pts_line2 <- cbind(c(308000, 325000), c(5524000, 5537000))
line2 <- spLines(pts_line2, crs = crs(parks_sub))
plot(line2, axes=T, add=T) #origin polygon = polyl[[8]] = OBJECTID 1838
linel <- list()
linel[[1]] <- line1
linel[[2]] <- line2
#convert to SpatialLinesDataFrame objects
lineldf <- lapply(1:length(linel), function(i) SpatialLinesDataFrame(linel[[i]], data.frame(id=rep(i, length(linel[[i]]))), match.ID = FALSE))
#match id field value with origin polygon
lineldf[[1]]@data$id <- 181
lineldf[[2]]@data$id <- 1838
###example data prep END
#initiate nested for loop
for (i in 1:length(lineldf)) {
for (j in 1:length(parks_sub[j,])) {
#STEP 1:for each line list feature (NB: with ID matching origin polygon ID)
#identify whether it intersects with a polygon list feature
if (tryCatch(!is.null(intersect(lineldf[[i]], parks_sub[j,])), error=function(e) return(FALSE)) == 'FALSE'){
next
}
#if 'FALSE', go on to check intersect with next polygon in list
#if 'TRUE', go to STEP 2
#STEP 2: add intersected polygon OBJECTID value to SLDF new column in attribute table
#i.e., deal with single intersected polygon at a time
else {
lineldf[[i]]@data["id.2"] = parks_sub[j,]@data$OBJECTID
#STEP 3: erase portion of line overlapped by intersected SPDF
line_erase <- erase(lineldf[[i]],parks_sub[j,])
#STEP 4: erase line feature(s) that no longer intersect with the origin polygon
#DO NOT KNOW HOW TO SELECT feature (i.e., line segment) within 'line_erase' object
if (tryCatch(!is.null(intersect(line_erase[???], parks_sub[j,])), error=function(e) return(FALSE)) == 'FALSE'){
line_erase[???] <- NULL}
else {
#STEP 5: erase line features that only intersect with origin polygon
if (line_erase[???]@data$id.2 = parks_sub[j,]@data$OBJECTID){
line_erase[???] <- NULL
}
else {
#STEP 6: write valid line files to folder
writeOGR(line_erase,
dsn = paste0("path/to/save/folder", i, ".shp"),
layer = "newline",
driver = 'ESRI Shapefile',
overwrite_layer = T)
}}}}}
sf
spatial classes rather than thesp
ones. Conversion is possible both ways so that should be okay... – Spacedman