R - how to write nested for-loop with different spatial data.frames

放肆的年华 提交于 2019-12-11 06:49:08

问题


I need to iterate thru a multi-feature SpatialPolygonsDataFrame (SPDF herein) and erase where each polygon intersects with SpatialLines contained in a list of single-feature SpatialLinesDataFrames (SLDF) and save the updated 'erased' SLDFs to a new list. If a line intersects with two different polygon features, I want two updated 'erased' SLDF to be created and added to the new SLDF list. In the sample I provide below, the SLDFs intersect with exactly one SPDF, except one of the SLDF intersects with two different SPDF polygon features. Therefore, the updated list should contain an additional SLDF element.

However, when I run a nested for-loop, the resulting 'erased' SLDF list contains the same number of elements as the original SLDF list. I think there is a problem with my loop structure, but I cannot figure it out.

library(rgdal)
library(raster)
library(rgeos)
library(sp) 
library(gdistance)

#Reproducible example data prep:
#'RDCO Regional Parks' data can be downloaded here: https://data- 
rdco.opendata.arcgis.com/datasets? 
group_ids=1950175c56c24073bb5cef3900e19460 
parks <- readOGR("/Users/rachelfield/Documents/UBC/Data/Regional 
Districts/RDCO/RDCO_Regional_Parks/RDCO_Regional_Parks.shp")

#DEM data downloaded here: https://pub.data.gov.bc.ca/datasets/175624/82e/ 
(files for '082e14_w.dem')
dem <- raster("/path/to/example/data/082e14_w.dem")
demproj <- "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs"

#reproject parks to match dem
p <- spTransform(parks, demproj)

#subset of parks data to reduce for example
e <- extent(dem)
p_crop <- crop(p, e)
p_sub <- p_crop[p_crop@data$Shapearea > 100000,]
p_sub2 <- p_sub[p_sub@data$CommonName != "Mission Creek Greenway Regional 
Park",]
#fyi I delete polygon [7,] because violates rules of my actual data 
(polygons do not touch)

#create polygon centroids and convert to SpatialPointsDataFrame using data 
from each 'origin' polygon data.frame
p_cent <- gCentroid(p_sub, byid = TRUE)
p_centdf <- SpatialPointsDataFrame(p_cent, data = data.frame(p_sub), 
match.ID = FALSE)

#manually create approx location of lowest elevation cell
lowest <- SpatialPoints(coords = cbind(-119.47,49.86), proj4string = 
CRS("+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs"))

#find LCPs from 'origin' polygon centroids to lowest elevation cell
tr <- transition(dem, transitionFunction=function(x) 1/min(x), 
directions=8) 
trCost <- geoCorrection(tr, type="c")
#run shortestPath (LCP) analysis for all polygon centroids
lcp_list <- list()
for(i in 1:nrow(p_centdf)){
  origin <- p_centdf[i,]
  #find LCP from each centroid
  lcp <- shortestPath(trCost, origin, goal = lowest, 
output="SpatialLines")
  #convert LCP SpatialLines to SpatialLinesDataFrame object type, and 
preserve ID from original centroid 
  lcp_list[[i]] <- SpatialLinesDataFrame(lcp, data = 
data.frame(p_centdf[i,]), match.ID = FALSE)
}

#my nested for-loop attempt to get resulting SLDF list 
line_erasel <- list()
#iterate thru all SPDF features
for (i in seq_along(p_sub2)) {
#iterate thru all SLDF list elements
  for (j in seq_along(lcp_list)) {
#if a SLDF intersects with a SPDF feature, execute erase function
    if (tryCatch(!is.null(raster::intersect(lcp_list[[j]], p_sub2[i,])), 
error=function(e) return(FALSE)) == 'TRUE'){
      #erase part of line overlapped by intersected polygon and add to new list
      line_erasel[[i]] <- erase(lcp_list[[j]],p_sub2[i,])
}}

来源:https://stackoverflow.com/questions/55445882/r-how-to-write-nested-for-loop-with-different-spatial-data-frames

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!