Skip to content

r-sig-geo@r-project.org

4 messages · Ben Tupper, David Romero, Edzer Pebesma

#
Hello,
How can I construct an sf polyline object directly in sf? I have a data
frame with 3 pairs of coordinates and need for each row a 2 segment line.

I did it with sp but would like to migrate to sf:

base$ID<-seq(1,nrow(base),1)
base_lines <- apply(base,1,function(x){
  points <- data.frame(lng=as.numeric(c(x["LONG1"],x["LONG2"],x["LONG3"])),

 lat=as.numeric(c(x["LAT1"],x["LAT2"],x["LAT3"])),stringsAsFactors = F)
  coordinates(points) <- c("lng","lat")
  Lines(Line(points),ID=as.numeric(x["ID"]))})
row.names(base) <- base$ID
base_lines <- SpatialLinesDataFrame(SpatialLines(base_lines),base)
sflines<-st_as_sf(base_lines)
#
Hi,

Hmmm... I think I can see what you are trying, but the mailing list
mangles HTML messages (switch your email to client to plain text mode
for this list).  Mifght you share what you get when you run,

dput(head(base))

in R?  That way each of us would have a small sample of your data.
And also resend the code to the list in plain text so we don't have to
to yoga moves to read the code?

Best wishes,
Ben
On Thu, Jun 30, 2022 at 9:30 AM David Romero <rodaromero at gmail.com> wrote:

  
    
#
Here it is:

Hello,
How can I construct an sf polyline object directly in sf? I have a
data frame with 3 pairs of coordinates and need for each row a 2
segment line.
I did it with sp but would like to migrate to sf:

dput(head(base))
structure(list(Cuenca = c("NA", "NA", "NA", "NA", "NA", "NA"),IDH =
c("AL011851", "AL011851", "AL011851", "AL011851",
"AL011851","AL011851"), W = c(80L, 80L, 80L, 80L, 70L, 60L), LAT1 =
c(28,28, 28.05, 28.15, 28.2, 28.25), LONG1 = c(-95.1, -95.7,
-96.25,-96.65, -96.9, -97.3), LAT3 = c(28, 28.05, 28.15, 28.2,
28.25,28.35), LONG3 = c(-95.7, -96.25, -96.65, -96.9, -97.3, -97.95),
LAT2 = c(28, 28, 28.1, 28.2, 28.2, 28.3), LONG2 = c(-95.4,-96, -96.5,
-96.8, -97, -97.6), Resid = c(6, 6, 4.5, 3, 4.5,6)),row.names = c(NA,
6L), class = "data.frame")

base$ID<-seq(1,nrow(base),1)
base_lines <- apply(base,1,function(x){
  points <- data.frame(lng=as.numeric(c(x["LONG1"],x["LONG2"],x["LONG3"])),lat=as.numeric(c(x["LAT1"],x["LAT2"],x["LAT3"])),stringsAsFactors
= F)
  coordinates(points) <- c("lng","lat")
  Lines(Line(points),ID=as.numeric(x["ID"]))})
row.names(base) <- base$ID
base_lines <- SpatialLinesDataFrame(SpatialLines(base_lines),base)
sflines<-st_as_sf(base_lines)


Le jeu. 30 juin 2022 ? 08:51, Ben Tupper <btupper at bigelow.org> a ?crit :
#
Here is a way to do this:

base = structure(list(Cuenca = c("NA", "NA", "NA", "NA", "NA", "NA"),IDH =
c("AL011851", "AL011851", "AL011851", "AL011851",
"AL011851","AL011851"), W = c(80L, 80L, 80L, 80L, 70L, 60L), LAT1 =
c(28,28, 28.05, 28.15, 28.2, 28.25), LONG1 = c(-95.1, -95.7,
-96.25,-96.65, -96.9, -97.3), LAT3 = c(28, 28.05, 28.15, 28.2,
28.25,28.35), LONG3 = c(-95.7, -96.25, -96.65, -96.9, -97.3, -97.95),
LAT2 = c(28, 28, 28.1, 28.2, 28.2, 28.3), LONG2 = c(-95.4,-96, -96.5,
-96.8, -97, -97.6), Resid = c(6, 6, 4.5, 3, 4.5,6)),row.names = c(NA,
6L), class = "data.frame")

base$ID <- seq(1,nrow(base),1)

library(sf)
# Linking to GEOS 3.10.2, GDAL 3.4.3, PROJ 8.2.0; sf_use_s2() is TRUE

base_lines <- lapply(1:nrow(base), function(i){
   x = base[i,,drop=FALSE] # row i
   points <- 
cbind(lng=as.numeric(c(x["LONG1"],x["LONG2"],x["LONG3"])),lat=as.numeric(c(x["LAT1"],x["LAT2"],x["LAT3"])))
   st_linestring(points)
})
lines = st_sfc(base_lines)
names(lines) = NULL
(sflines = st_sf(base, geometry = lines))
# Simple feature collection with 6 features and 11 fields
# Geometry type: LINESTRING
# Dimension:     XY
# Bounding box:  xmin: -97.95 ymin: 28 xmax: -95.1 ymax: 28.35
# CRS:           NA
#   Cuenca      IDH  W  LAT1  LONG1  LAT3  LONG3 LAT2 LONG2 Resid ID
# 1     NA AL011851 80 28.00 -95.10 28.00 -95.70 28.0 -95.4   6.0  1
# 2     NA AL011851 80 28.00 -95.70 28.05 -96.25 28.0 -96.0   6.0  2
# 3     NA AL011851 80 28.05 -96.25 28.15 -96.65 28.1 -96.5   4.5  3
# 4     NA AL011851 80 28.15 -96.65 28.20 -96.90 28.2 -96.8   3.0  4
# 5     NA AL011851 70 28.20 -96.90 28.25 -97.30 28.2 -97.0   4.5  5
# 6     NA AL011851 60 28.25 -97.30 28.35 -97.95 28.3 -97.6   6.0  6
#                         geometry
# 1 LINESTRING (-95.1 28, -95.4...
# 2 LINESTRING (-95.7 28, -96 2...
# 3 LINESTRING (-96.25 28.05, -...
# 4 LINESTRING (-96.65 28.15, -...
# 5 LINESTRING (-96.9 28.2, -97...
# 6 LINESTRING (-97.3 28.25, -9...

# reference:
library(sp)
base_lines <- apply(base,1,function(x){
   points <- 
data.frame(lng=as.numeric(c(x["LONG1"],x["LONG2"],x["LONG3"])),lat=as.numeric(c(x["LAT1"],x["LAT2"],x["LAT3"])),stringsAsFactors
= F)
   coordinates(points) <- c("lng","lat")
   Lines(Line(points),ID=as.numeric(x["ID"]))})
row.names(base) <- base$ID
base_lines <- SpatialLinesDataFrame(SpatialLines(base_lines),base)
sflines_ref <- st_as_sf(base_lines)
sflines_ref
# Simple feature collection with 6 features and 11 fields
# Geometry type: LINESTRING
# Dimension:     XY
# Bounding box:  xmin: -97.95 ymin: 28 xmax: -95.1 ymax: 28.35
# CRS:           NA
#   Cuenca      IDH  W  LAT1  LONG1  LAT3  LONG3 LAT2 LONG2 Resid ID
# 1     NA AL011851 80 28.00 -95.10 28.00 -95.70 28.0 -95.4   6.0  1
# 2     NA AL011851 80 28.00 -95.70 28.05 -96.25 28.0 -96.0   6.0  2
# 3     NA AL011851 80 28.05 -96.25 28.15 -96.65 28.1 -96.5   4.5  3
# 4     NA AL011851 80 28.15 -96.65 28.20 -96.90 28.2 -96.8   3.0  4
# 5     NA AL011851 70 28.20 -96.90 28.25 -97.30 28.2 -97.0   4.5  5
# 6     NA AL011851 60 28.25 -97.30 28.35 -97.95 28.3 -97.6   6.0  6
#                         geometry
# 1 LINESTRING (-95.1 28, -95.4...
# 2 LINESTRING (-95.7 28, -96 2...
# 3 LINESTRING (-96.25 28.05, -...
# 4 LINESTRING (-96.65 28.15, -...
# 5 LINESTRING (-96.9 28.2, -97...
# 6 LINESTRING (-97.3 28.25, -9...

all.equal(sflines, sflines_ref, check.attributes = FALSE)
# [1] TRUE
On 30/06/2022 16:19, David Romero wrote: