5

I want to create X random lines (not polylines) inside an area. I have managed to do so, however the output shapefile i get has only one linear object that includes all the random lines. I want X separate lines, but i have trouble getting them. I have implemented my code in R. Any suggestions?

library(sp)
library(raster)
library(rgdal)
library(maptools)
d <- structure(list(x = c(0.08394638623612, 0.0758558910509947, 0.197213318827875, 
                          0.209349061605562, 0.268005151697721, 0.280140894475409, 0.08394638623612, 
                          0.08394638623612, 0.112263119384059, 0.120353614569184, 0.112263119384059, 
                          0.100127376606371, 0.090014257624964, 0.0920368814212453, 0.41767931262254, 
                          0.454086540955604, 0.454086540955604, 0.462177036140729, 0.504652135862637, 
                          0.520833126232887, 0.545104611788263, 0.551172483177108, 0.553195106973389, 
                          0.852543428823026, 0.959742490025936, 0.963787737618499, 0.907154271322622, 
                          0.909176895118903, 0.937493628266842, 0.955697242433374, 0.941538875859404, 
                          0.931425756877998, 0.927380509285435, 0.911199518915184, 0.899063776137496, 
                          0.0859690100324013, 0.08394638623612), y = c(0.0984799434209303, 
                                                                       0.184633290921423, 0.173297324145043, 0.218641191250565, 0.218641191250565, 
                                                                       0.352405599211856, 0.356939985922409, 0.522445100857566, 0.529246680923394, 
                                                                       0.547384227765603, 0.567788967963088, 0.579124934739469, 0.585926514805297, 
                                                                       0.789973916780149, 0.862524104148985, 0.837584977240947, 0.801309883556529, 
                                                                       0.767301983227388, 0.751431629740455, 0.762767596516835, 0.776370756648492, 
                                                                       0.833050590530395, 0.867058490859537, 0.871592877570089, 0.864791297504261, 
                                                                       0.497505973949529, 0.474834040396767, 0.440826140067625, 0.418154206514864, 
                                                                       0.418154206514864, 0.313863312172162, 0.273053831777192, 0.216373997895289, 
                                                                       0.184633290921423, 0.141556617171177, 0.0962127500656542, 0.0984799434209303
                          )), .Names = c("x", "y"), row.names = c(NA, -37L), class = "data.frame")

## polygon

sp <- raster::spPolygons(cbind(d$x, d$y), attr = data.frame(p = 1))

pts <- spsample(sp, n = 500, type = "random")

l <- split(as.data.frame(coordinates(pts)), rep(seq(length(pts)/2), each = 2))

lp <- raster::spLines(lapply(l, as.matrix))
op <- par(bg = "black")
plot(sp, border = "yellow", lwd =2 )
plot(lp, add = TRUE, col = "yellow", lty = 2)
df<-SpatialLinesDataFrame(lp, data.frame(id=1:length(lp)))
writeOGR(df, dsn="c:/Ouputs" ,layer="synth_data",driver="ESRI Shapefile")
0

1 Answer 1

4

The way to construct multiple SpatialLines features with spLines from a set of matrices is something like:

ML = spLines(m1, m2, m3, m4, m5)

Since you have a list you want to use do.call, which feeds the elements of a list to a function in the same way as above. For example, this is equivalent to that:

L = list(m1,m2,m3,m4,m5)
ML = do.call(spLines, L)

So in your case, after creating the list of data frames, l:

> l <- split(as.data.frame(coordinates(pts)), rep(seq(length(pts)/2), each = 2))

It should be a case of using do.call on the list of data frames converted to matrices, but this throws an error:

> lp = do.call(spLines,lapply(l, as.matrix))
Error in (function (x, ..., attr = NULL, crs = "")  : 
  argument "x" is missing, with no default

Which I've tracked down to something odd in spLines that fails because of the names of the list items. Drop those names:

> names(l)=NULL

and it works:

> lp = do.call(spLines,lapply(l, as.matrix))

lp is now 250 separate features which you can combine with a 250 row data frame to create a SpatialLinesDataFrame with 250 features:

> lp
class       : SpatialLines 
features    : 250 
extent      : 0.07946532, 0.9612992, 0.1066574, 0.8623224  (xmin, xmax, ymin, ymax)
crs         : NA 
1
  • Great answer! Wish there was a visualization with this
    – stats_noob
    Mar 27, 2023 at 7:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.