【问题标题】:Randomly select lines of given length in road network在路网中随机选择给定长度的线
【发布时间】:2018-10-03 13:42:24
【问题描述】:

我想从道路网络中随机选择路段。我认为这不会太难,但我没有得到任何地方。 这个想法是从线路网络中采样道路(线路)的延伸。我希望这些伸展具有一定的长度,并且我希望从网络中随机选择这些伸展。 我找到了将 SpatialLines 分割成给定长度HERE 的段的方法,但这不允许随机进行,也不允许组合不同线段。 我可以使用 sp 包中的 spsample 来沿线以均匀的距离间隔点。然后我就可以随机选择一个点作为起点。从理论上讲,我认为应该可以将相邻点添加到一条线上,但我不知道该怎么做,也不知道当道路分裂时我将如何处理随机选择一个方向(2条线相交) .

这是一些数据。

    data <- data.frame(
  x = c(1,2,3,3,3,3,1,2,3),
  y = c(1,2,2,3,4,5,4,4,4),
  id = c(rep("A",6), rep("B",3))
) 


#with Kyle Walker's functions I convert the points to lines
#https://rpubs.com/walkerke/points_to_line 

library(sp)
library(maptools)

points_to_line <- function(data, long, lat, id_field = NULL, sort_field = NULL) {

  # Convert to SpatialPointsDataFrame
  coordinates(data) <- c(long, lat)

  # If there is a sort field...
  if (!is.null(sort_field)) {
    if (!is.null(id_field)) {
      data <- data[order(data[[id_field]], data[[sort_field]]), ]
    } else {
      data <- data[order(data[[sort_field]]), ]
    }
  }

  # If there is only one path...
  if (is.null(id_field)) {

    lines <- SpatialLines(list(Lines(list(Line(data)), "id")))

    return(lines)

    # Now, if we have multiple lines...
  } else if (!is.null(id_field)) {  

    # Split into a list by ID field
    paths <- sp::split(data, data[[id_field]])

    sp_lines <- SpatialLines(list(Lines(list(Line(paths[[1]])), "line1")))

    # I like for loops, what can I say...
    for (p in 2:length(paths)) {
      id <- paste0("line", as.character(p))
      l <- SpatialLines(list(Lines(list(Line(paths[[p]])), id)))
      sp_lines <- spRbind(sp_lines, l)
    }

    return(sp_lines)
  }
}

lines <- points_to_line(data = data, 
                        long = "x", 
                        lat = "y", 
                        id_field = "id")

#plot it
ori.plot <- plot(lines, col = rep(c(1, 2), length.out = length(lines)), axes = T, main="original",
     ylim=c(0,5), xlim=c(0,5))

这给了我一个简单的两条线的情节。

我想要的是一种结果可能如下所示的方式:

或者

或者

我可以将它分割成给定长度的片段,就像上面提到的那样(长度 = 0.3):

但这些线段仅限于一条线,并且不会从随机点开始。

有什么想法吗?

【问题讨论】:

    标签: r gis spatial sampling


    【解决方案1】:

    我最终做了以下事情: 将线分成一定间距的点 正如我所知道的样带的长度,我知道一个样带中应该包含多少点。我也知道我需要多少条横断面。 所以我会缓冲一个点并随机选择缓冲区中的下一个点,直到我在样带中有足够的点,然后移动到下一个样带。 如果缓冲区中没有尚未分配给样带的点,我需要重置我正在构建的样带中包含的点,并通过随机选择一个新起点重新开始。

    代码还是有点乱,但在我这边工作:

    #Convert the SpatialLines into SpatialPoints with regularly spaced points
    points_spdf <- spsample(lines, n = 30, type = "regular")
    
    #In my case I would need to calculate the total distance of the road network, then divide that so that I get
    #a point for every XX meter
    
    #Convert the spatialpointsdataframe to dataframe
    
    points.df <- as.data.frame(points_spdf)
    #add an ID column
    points.df$ID <- seq(from=1, to=nrow(points.df), by=1)
    
    library(sf)
    #convert to an sf data.frame
    points_sf <- st_as_sf(x = points.df, 
                          coords = c("x", "y"),
                          crs = "+proj=utm +zone=32 +datum=WGS84")
    
    #add transect colum
    points_sf$transect <- 0 #adds transect column and fills those with zeroes
    th <- 4 #sets nr of points which are needed to form total distance of each transect
    
    library(dplyr) #for function sample_n
    
    plot(points_sf)
    
    i <-1 #counter for transects, these are used as transectIDs
    
    
    #####################################
    #function
    #This function resets transectIDs to 0 if there are no un-assigned points in the buffer and the number of 
    #points with the buffer aren't enough. It also then draws a new random point.
    #####################################
    
    reset_and_sample <- function() {
      points_sf$transect <- tryCatch(points_in_poly[sample_n(subset(points_in_poly, transect.x == 0 & transect.y == i),1),1], 
                                     error=function(e) ifelse(points_sf$transect==i, 
                                                              points_sf$transect[points_sf$transect == i] <-0, 
                                                              points_sf$transect <- points_sf$transect)) 
      points_sf <<- points_sf #to retun points_sf to global ennvironment
      pt <- points_sf[ sample_n(subset(points_sf, transect == 0),1 ) ,1 ] 
      pt <<- pt
    }
    #####################################
    pt <- NULL
    
    
    while(i < 5){ #to create 4 transects
    pt <- if(sum(points_sf$transect == i) < th) {
               tryCatch(points_in_poly[sample_n(subset(points_in_poly, transect.x == 0 & transect.y == i),1),1], 
                error=function(e) (reset_and_sample()))
      }else{
      pt <- (points_sf[ sample_n(subset(points_sf, transect == 0),1 ) ,1 ])
    }
    
    
    #put the transectID in the dataframe
    ifelse((sum(points_sf$transect == i) < th),
           points_sf$transect[points_sf$ID==pt[[1]]]<-i,
           points_sf$transect[points_sf$ID==pt[[1]]]<-i+1) #puts 1 in row where ID is from pt
    
    #this is the place where the counter for the transects is set
    ifelse((sum(points_sf$transect == i) < th),
           i <- i,
           i <- i+1)
    
    #buffers point with the ID of the selected point
    buf_poly <- st_buffer((points_sf[points_sf$ID[pt[[1]]],]), dist = 0.31) 
    
    plot(points_sf, add=TRUE)
    plot(buf_poly, add=TRUE)
    
    points_in_poly <- st_join(points_sf, buf_poly, join = st_intersects) #only points in polygons have polygon info in columns
    
    } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-18
      • 1970-01-01
      相关资源
      最近更新 更多