简体   繁体   English

行与sf之间的点距离

[英]Distances of points between rows with sf

I have multiple trajectories saved in simple feature ( sf ) of the type POINT . 我在POINT类型的简单特征( sf )中保存了多个轨迹。 I'd like to calculate the Euclidean distances between subsequent locations (ie rows). 我想计算后续位置(即行)之间的欧几里德距离。 Until now, I've "manually" calculated distances using the Pythagorean formula for calculating Euclidean Distances in 2D space . 到目前为止,我使用毕达哥拉斯公式 “手动”计算距离, 用于计算2D空间中的欧几里德距离 I was wondering if I could do the same using the function sf::st_distance() . 我想知道我是否可以使用函数sf::st_distance()来做同样的sf::st_distance() Here's a quick example: 这是一个简单的例子:

library(sf)
library(dplyr)

set.seed(1)

df <- data.frame(
  gr = c(rep("a",5),rep("b",5)),
  x  = rnorm(10),
  y = rnorm(10)
 )

df <- st_as_sf(df,coords = c("x","y"),remove = F)


df %>%
  group_by(gr) %>%
  mutate(
    dist = sqrt((lead(x)-x)^2+(lead(y)-y)^2)
  )
#> Simple feature collection with 10 features and 4 fields
#> geometry type:  POINT
#> dimension:      XY
#> bbox:           xmin: -0.8356286 ymin: -2.2147 xmax: 1.595281 ymax: 1.511781
#> epsg (SRID):    NA
#> proj4string:    NA
#> # A tibble: 10 x 5
#> # Groups:   gr [2]
#>    gr         x       y   dist                 geometry
#>    <fct>  <dbl>   <dbl>  <dbl>                  <POINT>
#>  1 a     -0.626  1.51    1.38     (-0.6264538 1.511781)
#>  2 a      0.184  0.390   1.44     (0.1836433 0.3898432)
#>  3 a     -0.836 -0.621   2.91   (-0.8356286 -0.6212406)
#>  4 a      1.60  -2.21    3.57        (1.595281 -2.2147)
#>  5 a      0.330  1.12   NA         (0.3295078 1.124931)
#>  6 b     -0.820 -0.0449  1.31  (-0.8204684 -0.04493361)
#>  7 b      0.487 -0.0162  0.992  (0.4874291 -0.01619026)
#>  8 b      0.738  0.944   0.204    (0.7383247 0.9438362)
#>  9 b      0.576  0.821   0.910    (0.5757814 0.8212212)
#> 10 b     -0.305  0.594  NA       (-0.3053884 0.5939013)

I would like to calculate dist with sf::st_distance() . 我想用sf::st_distance()来计算dist How would I go about this? 我该怎么做?

The first thing to know about sf is that the geometry column (the one of class sfc ) is stored as a list-column inside the dataframe. 关于sf的第一件事是几何列(类sfc )作为列表列存储在数据帧内。 The key to usually do anything with a list-column is to either use purrr::map and friends or to use a function that accepts list-cols as arguments. 通常使用list-column执行任何操作的关键是使用purrr::map和friends,或者使用接受list-cols作为参数的函数。 In the case of st_distance its arguments can be an object of sf (a dataframe), sfc (the geometry column), or even an sfg (a single geom row), so there's no need for map and friends. st_distance的情况下,它的参数可以是sf (数据帧), sfc (几何列)或sfg (单个geom行)的对象,因此不需要map和朋友。 The solution should look something like this: 解决方案看起来应该是这样的:

df %>%
  group_by(gr) %>%
  mutate(
    dist = st_distance(geometry)
  )

However, this doesn't work. 但是,这不起作用。 After some investigating, we find two problems. 经过一番调查,我们发现了两个问题。 First, st_distance returns a distance matrix and not a single value. 首先, st_distance返回距离矩阵而不是单个值。 To solve this, we make use of the by_element = T argument of st_distance . 为了解决这个问题,我们利用的by_element = T的说法st_distance

Next, we can't just do dist = st_distance(geometry, lead(geometry), by_element = T) because lead only works on vector columns, not list columns. 接下来,我们不能只做dist = st_distance(geometry, lead(geometry), by_element = T)因为lead只适用于矢量列,而不适用于列列。

To solve this second problem, we create the lead column ourselves using geometry[row_number() + 1] . 为了解决第二个问题,我们使用geometry[row_number() + 1]自己创建了前导列。

Here's the full solution: 这是完整的解决方案:

library(sf)
library(dplyr)

df %>%
  group_by(gr) %>%
  mutate(
    lead = geometry[row_number() + 1],
    dist = st_distance(geometry, lead, by_element = T),
  )
#> Simple feature collection with 10 features and 4 fields
#> Active geometry column: geometry
#> geometry type:  POINT
#> dimension:      XY
#> bbox:           xmin: -0.8356286 ymin: -2.2147 xmax: 1.595281 ymax: 1.511781
#> epsg (SRID):    4326
#> proj4string:    +proj=longlat +datum=WGS84 +no_defs
#> # A tibble: 10 x 6
#> # Groups:   gr [2]
#>    gr         x       y  dist                       geometry
#>    <fct>  <dbl>   <dbl> <dbl>         <sf_geometry [degree]>
#>  1 a     -0.626  1.51   1.38     POINT (-0.6264538 1.511781)
#>  2 a      0.184  0.390  1.44     POINT (0.1836433 0.3898432)
#>  3 a     -0.836 -0.621  2.91   POINT (-0.8356286 -0.6212406)
#>  4 a      1.60  -2.21   3.57        POINT (1.595281 -2.2147)
#>  5 a      0.330  1.12   0         POINT (0.3295078 1.124931)
#>  6 b     -0.820 -0.0449 1.31  POINT (-0.8204684 -0.04493361)
#>  7 b      0.487 -0.0162 0.992  POINT (0.4874291 -0.01619026)
#>  8 b      0.738  0.944  0.204    POINT (0.7383247 0.9438362)
#>  9 b      0.576  0.821  0.910    POINT (0.5757814 0.8212212)
#> 10 b     -0.305  0.594  0       POINT (-0.3053884 0.5939013)
#> # ... with 1 more variable: lead <sf_geometry [degree]>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM