首页 > 解决方案 > 将字符线串转换为 sf 中的几何图形

问题描述

基本问题,如何将类型character LINESTRING变量转换为geometry类型sf,然后分别将两个坐标分成不同的变量。例如

library(tidyverse)
library(sf)
df <- structure(list(geometry = c("LINESTRING (-85.76 38.34, -85.72 38.38)", 
                            "LINESTRING (-85.46 38.76, -85.42 38.76)", 
                            "LINESTRING (-85.89 38.31, -85.85 38.32)"
), var1 = c(4, 5, 6
), var2 = c(1, 2, 3
)), row.names = c(NA, -3L), class = c("tbl_df", "tbl", "data.frame"
))
df
# # A tibble: 3 x 3
#   geometry                                 var1  var2
#   <chr>                                   <dbl> <dbl>
# 1 LINESTRING (-85.76 38.34, -85.72 38.38)     4     1
# 2 LINESTRING (-85.46 38.76, -85.42 38.76)     5     2
# 3 LINESTRING (-85.89 38.31, -85.85 38.32)     6     3

期望的输出:

final
#                     geometry   start_lon start_lat end_lon end_lat var1 var2
# -85.76, -85.72, 38.34, 38.38      -85.76     38.34  -85.72   38.38    4    1
# -85.46, -85.42, 38.76, 38.76      -85.46     38.76  -85.42   38.76    5    2
# -85.89, -85.85, 38.31, 38.32      -85.89     38.31  -85.85   38.32    6    3


#so I can quickly plot lines between points
plot(final[, "var1"])

我认为某些组合 final <- st_as_sf(df) %>% st_geometry(geometry)会转换它,但我无法弄清楚。也许sfheaders在这里有用?

编辑

我想要一个sf类型的解决方案,而不是手动提取坐标。

有什么建议么?谢谢

标签: rsf

解决方案


library(sf)wkt =如果您告诉它使用参数,则可以直接读取 Well-known Text 。这给了你你的sf对象。

sf <- sf::st_as_sf( df, wkt = "geometry" )
sf
# Simple feature collection with 3 features and 2 fields
# geometry type:  LINESTRING
# dimension:      XY
# bbox:           xmin: -85.89 ymin: 38.31 xmax: -85.42 ymax: 38.76
# CRS:            NA
#                         geometry var1 var2
# 1 LINESTRING (-85.76 38.34, -...    4    1
# 2 LINESTRING (-85.46 38.76, -...    5    2
# 3 LINESTRING (-85.89 38.31, -...    6    3

然后有很多方法可以获取坐标并重塑它们。在这里,我sfheaders用于将 sf 对象转换为长 data.frame,然后library(data.table)用于重塑它。

library(sfheaders)
library(data.table)

dt <- sfheaders::sf_to_df( sf, fill = TRUE )
setDT( dt )

## In this example, every 2nd row is to be made into new columns

odds <- 1:nrow(dt) %% 2 == 1
evens <- !odds

dt <- dt[odds][
  dt[evens, .(end_lon = x, end_lat = y, linestring_id)]
  , on = "linestring_id"
]

setnames( dt, c("x","y"), c("start_lon", "start_lat"))

dt
#    var1 var2 sfg_id linestring_id start_lon start_lat end_lon end_lat
# 1:    4    1      1             1    -85.76     38.34  -85.72   38.38
# 2:    5    2      2             2    -85.46     38.76  -85.42   38.76
# 3:    6    3      3             3    -85.89     38.31  -85.85   38.32


推荐阅读