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

基于船速与同航次上次捕捞时间判断鱼类捕捞坐标合理性

用时间间隔+船速检测捕捞坐标错误的方法

嘿,这个问题在渔业数据清洗里太常见了——人工转录坐标很容易手抖输错,咱们用同航次的时间差+渔船最大船速就能快速揪出这些离谱的错误。核心逻辑很简单:渔船在两个捕捞点之间的航行时间里,最多能跑「时间间隔×船速」的距离,如果实际两点的地理距离超过这个值,那这个坐标大概率有问题。

下面我用你提到的R包(sf/dplyr/lubridate/ggplot2),结合你给的示例场景一步步实现:

第一步:准备示例数据(补全你的模拟数据集)

先构造一个带故意错误的数据集——比如第二个航次的第二个点,我把经度设成了离谱的125.0,方便后续检测:

library(sf)
library(ggplot2)
library(dplyr)
library(lubridate)

set.seed(123) # 保证结果可复现
fishing_data <- tibble(
  voyage_id = rep(c("V001", "V002"), each = 2),
  datetime = ymd_hms(c(
    "2017-05-13 14:00:00", 
    "2017-05-13 15:30:00", # 同航次间隔1.5小时
    "2017-06-01 09:00:00", 
    "2017-06-01 09:45:00"  # 同航次间隔0.75小时
  ), tz = "UTC"),
  lon = c(120.1, 120.2, 121.0, 125.0), # 最后一个是故意设置的错误值
  lat = c(30.5, 30.6, 29.8, 30.0)
)

第二步:计算时间间隔与理论最大航行距离

按航次分组,计算每个捕捞点和前一个点的时间差,再结合假设的船速(比如10km/h)算出理论上能跑的最大距离:

fishing_analysis <- fishing_data %>%
  # 按航次分组,保证只对比同航次的点
  group_by(voyage_id) %>%
  # 计算与上一个捕捞点的时间间隔(转成小时)
  mutate(
    time_since_last = as.numeric(difftime(datetime, lag(datetime), units = "hours")),
    # 计算理论最大航行距离:时间间隔×船速(这里用10km/h)
    max_possible_distance = time_since_last * 10
  ) %>%
  ungroup()

第三步:计算实际地理距离并标记错误

用sf把坐标转成地理对象,计算两点间的实际球面距离,再和理论最大距离对比:

# 转成sf对象(WGS84坐标系,EPSG:4326)
fishing_sf <- fishing_analysis %>%
  st_as_sf(coords = c("lon", "lat"), crs = 4326) %>%
  # 按航次分组,计算与前一个点的实际距离(转成公里)
  group_by(voyage_id) %>%
  mutate(
    actual_distance = as.numeric(st_distance(geometry, lag(geometry)))/1000,
    # 标记可疑错误:实际距离>理论最大距离(可以加个小缓冲,比如1.1倍,允许小误差)
    is_suspicious = ifelse(actual_distance > max_possible_distance * 1.1, TRUE, FALSE)
  ) %>%
  ungroup()

# 查看结果
fishing_sf %>%
  select(voyage_id, datetime, actual_distance, max_possible_distance, is_suspicious) %>%
  st_drop_geometry()

运行后你会看到,第二个航次的最后一个点is_suspicious是TRUE——因为它的实际距离(约444公里)远大于0.75小时能跑的7.5公里,明显是错误。

第四步:可视化验证(可选但实用)

用ggplot2把航次轨迹画出来,把可疑点标红,直观确认错误:

ggplot() +
  # 画航次轨迹线
  geom_sf(data = fishing_sf, aes(group = voyage_id), color = "gray") +
  # 画捕捞点,可疑点标红
  geom_sf(data = fishing_sf, aes(color = is_suspicious), size = 3) +
  scale_color_manual(values = c("black", "red")) +
  labs(title = "捕捞坐标可疑错误标记", color = "是否可疑") +
  theme_minimal()

一些注意事项

  • 船速的合理性:别随便用10km/h,最好用你渔船的实际最大巡航速度,或者行业通用的合理范围(比如小型渔船可能8-12km/h,大型拖网船可能15-20km/h)。
  • 时间统一:一定要确保所有datetime的时区一致,不然时间差计算会出错。
  • 缓冲阈值:可以给理论距离加个10%-20%的缓冲,因为渔船可能绕路、记录时间有小偏差,避免误判。
  • 第一个点处理:每个航次的第一个点没有前一个点,time_since_last会是NA,可以用replace_na把is_suspicious设为FALSE。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:07:48