【问题标题】:R OSRM calculate travel distance within data.frameR OSRM 计算 data.frame 内的行进距离
【发布时间】:2021-11-08 21:17:32
【问题描述】:

使用 osrm 包,我想计算存储在数据帧的两个不同列中的两个点之间的距离,并将其放入一个新列中。

但是,执行以下操作不起作用并引发错误:找不到对象“lon”。这里出了什么问题?

pacman::p_load(
  tidyverse,
  sf,
  osrm
)


test_1 <- data.frame(name_1 = c("a", "b"), long = c(13.371871012201932, 13.445856720780322), lat = c(52.5212875734526, 52.503693991115206)) %>%
    st_as_sf(coords = c("long", "lat"), crs = 4326) %>%
    rename(geom_1 = "geometry")

test_2 <- data.frame(name_2 = c("c", "d"), long = c(13.401224766110927, 13.349212418670756), lat = c(52.51946945798967, 52.5149481833963)) %>%
    st_as_sf(coords = c("long", "lat"), crs = 4326) %>%
    rename(geom_2 = "geometry")

comb <- expand_grid(test_1, test_2)


routes <- comb %>%
    mutate(distances = osrmRoute(
        src = geom_1,
        dst = geom_2,
        returnclass = "sf"
    )$distance)

【问题讨论】:

    标签: r sf


    【解决方案1】:

    问题是sf 对象一次只能有一个geom 列处于活动状态。要解决这个问题,只需调用 sf 对象 test1test2 就可以了。

    请在下面找到修改后的代码和相应的输出。

    • 代码
    routes <- comb %>%
      mutate(distances = osrmRoute(
        src = test_1,
        dst = test_2,
        returnclass = "sf"
      )$distance)
    
    • 输出:
    routes
    # A tibble: 4 x 5
      name_1              geom_1 name_2              geom_2 distances
      <chr>          <POINT [°]> <chr>          <POINT [°]>     <dbl>
    1 a      (13.37187 52.52129) c      (13.40122 52.51947)      4.35
    2 a      (13.37187 52.52129) d      (13.34921 52.51495)      4.35
    3 b      (13.44586 52.50369) c      (13.40122 52.51947)      4.35
    4 b      (13.44586 52.50369) d      (13.34921 52.51495)      4.35
    

    或者,您可以在sf 对象comb 中指定哪个geom 列处于活动状态,您将获得与上述相同的结果。

    • 替代代码
    routes <- comb %>% mutate(distances = osrmRoute(
      src = st_sf(.,sf_column_name = "geom_1"),
      dst = st_sf(.,sf_column_name = "geom_2"),
      returnclass = "sf"
    )$distance)
    

    编辑

    作为我与@Jindra Lacko(参见下面的 cmets)交流的后续行动,我提出了一个 computeDistances() 函数,它可以帮助你得到你想要的。请使用您的对象comb在下面找到函数的代码及其输出

    • 函数代码computeDistances
    computeDistances <- function(x){  
      
      distances <- data.frame(Distances = numeric())
      
      for (i in seq(x)){
        distances[i,"Distances"]  <- osrmRoute(
          src = st_sf(x,sf_column_name = "geom_1")[i,],
          dst = st_sf(x,sf_column_name = "geom_2")[i,],
          returnclass = "sf"
        )$distance
      }
      
      results <- st_sf(cbind(x, distances))
      
      return(results)
    }
    
    • 使用 comb 对象测试函数
    computeDistances(comb)
    
    Simple feature collection with 4 features and 3 fields
    Active geometry column: geom_1
    Geometry type: POINT
    Dimension:     XY
    Bounding box:  xmin: 13.37187 ymin: 52.50369 xmax: 13.44586 ymax: 52.52129
    Geodetic CRS:  WGS 84
      name_1 name_2 Distances                    geom_1                    geom_2
    1      a      c    4.3543 POINT (13.37187 52.52129) POINT (13.40122 52.51947)
    2      a      d    2.6576 POINT (13.37187 52.52129) POINT (13.34921 52.51495)
    3      b      c    4.4650 POINT (13.44586 52.50369) POINT (13.40122 52.51947)
    4      b      d    8.1611 POINT (13.44586 52.50369) POINT (13.34921 52.51495)
    

    【讨论】:

    • 我不认为这是一个正确的答案 - 看看距离如何保持不变(4.35 公里),尽管起点和终点预计会发生变化
    • 你好@Jindra Lacko。是的,我注意到你自己也注意到了。但我正在等待 OP 的反馈,因为它可能是点等距的测试数据集。无论如何,如果这不是正确的解决方案,我将删除我的帖子。
    • 嗨@lovalery,我已经绘制了位置,它们看起来像是柏林市中心的四个半随机位置。我强烈怀疑osrmRoute 调用未矢量化,并且默认为第一个位置对(始终)。但是话虽如此 - 请不要删除您的答案,因为您在诊断无效 {sf} 对象的问题时是正确的(由于两个几何列)。这是 OP 提出的关键问题。
    • 非常感谢您的反馈@Jindra Lacko。你是绝对正确的:实际上osmRoutes() 函数创建的distances 对象只包含一个值(即4.35),它被mutate 函数回收。由于它没有矢量化,我认为 osmRoutes() 函数不是用于 OP 的合适工具。我认为sf 包中的 st_distance() 函数将是正确的解决方案。
    • 最后,我感谢您评论的第二部分,因此请保留我的“技术上”回答请求的帖子。干杯。
    猜你喜欢
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-15
    相关资源
    最近更新 更多