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

如何计算同一FieldID下所有点组合的距离(含对角线)

问题分析

你的代码之所以无法得到6个目标结果,是因为当前逻辑存在两个核心问题:

  • 逐个遍历每个点,计算该点与同FieldID下所有4个点的距离,导致重复计算点对(比如点A→点B和点B→点A会被算两次),还包含了点到自身的无效距离(值为0)
  • 最终每个FieldID会生成16条记录(4×4),但你需要的是不重复的两两不同点对,也就是组合数C(4,2)=6个结果
解决方案

我们可以通过按FieldID分组,生成每组内所有唯一的点对组合,再针对性计算距离,避免无效计算。以下是两种高效的实现方式:

方法1:分组+组合函数处理

library(sf)
library(dplyr)

# 按FieldID分组,生成每组内唯一点对并计算距离
distance_df <- raps_filtered_sf %>%
  group_by(FieldID) %>%
  group_modify(function(group_data, group_key) {
    # 生成当前组内所有点的索引组合(不重复、不含自身)
    point_pairs <- combn(nrow(group_data), 2)
    
    # 遍历组合计算距离并整理结果
    dist_results <- lapply(seq(ncol(point_pairs)), function(i) {
      idx1 <- point_pairs[1, i]
      idx2 <- point_pairs[2, i]
      tibble(
        SchlagID_1 = group_data$SchlagID[idx1],
        SchlagID_2 = group_data$SchlagID[idx2],
        distance = as.numeric(st_distance(group_data[idx1, ], group_data[idx2, ]))
      )
    }) %>%
      bind_rows()
    
    return(dist_results)
  }) %>%
  ungroup()

方法2:向量化简洁处理

library(sf)
library(dplyr)
library(tidyr)

distance_df <- raps_filtered_sf %>%
  # 为每个FieldID生成所有SchlagID的两两组合
  group_by(FieldID) %>%
  mutate(pairs = list(combn(SchlagID, 2, simplify = FALSE))) %>%
  unnest(pairs) %>%
  # 拆分组合为两个独立的SchlagID列
  mutate(
    s1 = map_chr(pairs, ~ .x[1]),
    s2 = map_chr(pairs, ~ .x[2])
  ) %>%
  # 匹配对应点的几何信息
  left_join(raps_filtered_sf, by = c("FieldID", "s1" = "SchlagID"), suffix = c("", "_1")) %>%
  left_join(raps_filtered_sf, by = c("FieldID", "s2" = "SchlagID"), suffix = c("", "_2")) %>%
  # 计算点对距离
  mutate(distance = as.numeric(st_distance(geometry, geometry_2, by_element = TRUE))) %>%
  # 保留所需列并去重
  select(FieldID, s1, s2, distance) %>%
  distinct() %>%
  ungroup()
结果说明

运行上述任意代码后,每个FieldID下会得到6条记录,对应4个点之间所有不重复的两两距离,其中自然包含你所说的正方形对角线距离(只要四个点的位置符合正方形顶点)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 10:20:36