R语言 如何计算沿着sf线到给定点的距离?

htzpubme  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(143)

使用R和sf包,我研究了lat/lon路径,但找不到一个看起来很明显的函数。
给定行程A->B的情况,它可以具有任何连续的几何形状,并且由st_line描述,点X(或圆,通过添加st_buffer)位于路径的沿着。我如何计算从A到X的距离?x1c 0d1x
我只能对一部分路径使用st_length函数。

jvidinwx

jvidinwx1#

我们可以使用{sf}来完成这个任务。我猜你指的是sf::st_linestring()而不是st_line()

**(1)**对于“直”LINESTRING,如草图所示:

library(sf)
#> Linking to GEOS 3.11.0, GDAL 3.5.3, PROJ 9.1.0; sf_use_s2() is TRUE
ls = st_linestring(rbind(st_point(c(0L, 0L)), # point A
                         st_point(c(10L, 0L)))) # point B 
X = st_point(c(3L, 0L)) 
plot(ls); plot(X, col = "red", add = TRUE)
pnts = st_cast(st_sfc(ls), to = "POINT") # plot endpoints
plot(pnts,  col = "blue", add = TRUE)
segments(0L, 0L, 3L, 0L, col = "red")

字符串


的数据

st_distance(x = pnts[[1L]], y = X, by_element = TRUE) # pnts[[1L]] = A
#> X 
#> 3


返回[1] "XY" "LINESTRING" "sfg"类对象端点的替代方法:

st_line_sample(ls, sample = 0L) 
#> Geometry set for 1 feature 
#> Geometry type: MULTIPOINT
#> Dimension:     XY
#> Bounding box:  xmin: 0 ymin: 0 xmax: 0 ymax: 0
#> CRS:           NA
#> MULTIPOINT ((0 0))
st_line_sample(ls, sample = 1L)
#> Geometry set for 1 feature 
#> Geometry type: MULTIPOINT
#> Dimension:     XY
#> Bounding box:  xmin: 10 ymin: 0 xmax: 10 ymax: 0
#> CRS:           NA
#> MULTIPOINT ((10 0))

**(2)**对于一个“弯曲的”LINESTRING,一个选择可能是将LINESTRING分解成它的底层点。然后我们从这些点的子集中创建一个新的子LINESTRING并计算它的长度:

# library(sf)
X1 = st_point(c(3L, 1L)) 
x = 0L:10L
ls_sin = st_linestring(cbind(x, sin(x)))
# assuming we start with a LINESTRING, we need to get out the points:
mx = matrix(unlist(st_geometry(ls_sin)), ncol = 2L)
(idx = mx[which.min(st_distance(st_as_sf(as.data.frame(mx), coords = c(1L, 2L)), X1)), ])
#> [1] 3.00000 0.14112
ls_sin_sup = st_linestring(cbind(x[1L:idx[1L]], sin(x[1L:idx[1L]]))) 
plot(ls_sin, col = "black")
plot(ls_sin_sup, col = "red", add = TRUE)
plot(ls, col = "blue", add = TRUE) # from  straight line example


sapply(list(ls_sin, ls_sin_sup), st_length)
#> [1] 12.10540  2.30923

**(3)**通过{sfnetworks}的替代方案。我们创建一个网络,添加新点,并计算子LINESTRINGS的长度:

# library(sf)
library(sfnetworks)
library(dplyr, warn.conflicts = FALSE)
net = as_sfnetwork(st_as_sf(st_sfc(ls_sin)), directed = FALSE)
X1adj = st_point(mx[idx[1L], ]) # index shifting 
netX = st_network_blend(net, X1adj) # add point to sfnetwork 
plot(net)
plot(netX |> activate("edges") |> st_as_sf() |> {\(.) .[1L, "x"]}(), 
     col = "red", add = TRUE)

netX |>
  activate("edges") |>
  st_as_sf() |>
  mutate(Length = st_length(x))
#> Simple feature collection with 2 features and 3 fields
#> Geometry type: LINESTRING
#> Dimension:     XY
#> Bounding box:  xmin: 0 ymin: -0.9589243 xmax: 10 ymax: 0.9893582
#> CRS:           NA
#> # A tibble: 2 × 4
#>    from    to                                                           x Length
#> * <int> <int>                                                <LINESTRING>  <dbl>
#> 1     1     3                              (0 0, 1 0.841471, 2 0.9092974)   2.31
#> 2     2     3 (2 0.9092974, 3 0.14112, 4 -0.7568025, 5 -0.9589243, 6 -0.…   9.80

标签:有look

**(4)**还没有找到从{sf}导出的显式函数,该函数可以精确地将LINESTRING缩短到新的端点。

相关问题