You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何计算带时间戳的连续GPS点位间距离(含缺失值处理)

解决方案

依赖包

首先安装并加载所需工具包:

# 首次使用先执行安装
install.packages(c("dplyr", "lubridate", "geosphere"))
# 加载依赖
library(dplyr)
library(lubridate)
library(geosphere)

处理逻辑与代码

步骤1:定义时间规则校验函数

首先封装函数判断连续两个点位的时间间隔是否符合采集规则:

check_time_rule <- function(prev_time, curr_time) {
  # 计算时间差(单位:小时)
  gap_hour <- as.duration(curr_time - prev_time) / dhours(1)
  prev_h <- hour(prev_time)
  curr_h <- hour(curr_time)
  
  # 3种合法间隔场景
  # 场景1:14:00~次日04:00区间内的每小时采集
  scene1 <- gap_hour == 1 && curr_h %in% c(14:23, 0:4)
  # 场景2:前一个点位是04:00,下一个是当日10:00,间隔6小时
  scene2 <- gap_hour == 6 && prev_h == 4 && curr_h == 10
  # 场景3:前一个点位是10:00,下一个是当日14:00,间隔4小时
  scene3 <- gap_hour == 4 && prev_h == 10 && curr_h == 14
  
  return(scene1 | scene2 | scene3)
}

步骤2:数据清洗与距离计算

对原始数据分组、校验后计算距离:

# df替换为你的原始数据框
result <- df %>%
  # 标记无效行:采集异常、经纬度为空都判定为无效
  mutate(valid_row = Info == "3D" & !is.na(Latitude) & !is.na(Longitude)) %>%
  # 生成连续有效序列分组ID:遇到无效行则分组ID+1,跨错误点位不会合并计算
  mutate(group_id = cumsum(!valid_row)) %>%
  # 过滤无效行,仅保留有效点位参与计算
  filter(valid_row) %>%
  # 确保数据按时间升序排列
  arrange(DateTime) %>%
  # 按分组独立计算每组内的相邻距离
  group_by(group_id) %>%
  mutate(
    # 校验和前一个点位的时间间隔是否符合规则
    conform_rule = mapply(check_time_rule, lag(DateTime), DateTime),
    # 计算哈弗辛距离(单位:米),不符合规则/组内第一个点位的距离为NA
    distance_m = ifelse(
      conform_rule,
      distHaversine(
        cbind(lag(Longitude), lag(Latitude)),
        cbind(Longitude, Latitude)
      ),
      NA_real_
    )
  ) %>%
  ungroup() %>%
  # 按需删除中间辅助列
  select(-valid_row, -conform_rule)

结果说明

输出的result数据框中:

  • group_id标记了点位所属的连续有效序列,相同ID的点位属于同一段没有采集中断的有效数据
  • distance_m为和前一个相邻有效点位的距离,单位为米;取值为NA代表该点位是当前序列的第一个点,或和前一个点位的时间间隔不符合采集规则
  • 采集错误的点位会被自动过滤,前后有效点位不会跨错误点位计算距离

内容的提问来源于stack exchange,提问作者Sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 07:15:04