PAYATHON 2026

如何在 echarts4r 地图上为点添加半径为 50 km 的圆?

数据小陈

可以先计算缓冲区,再把圆形边界叠加到地图上

对于示例中的荷兰城市,可以先用 sf 将位置点转换到以米为单位的当地投影坐标系,调用 st_buffer(dist = 50000) 计算缓冲区,再转换回经纬度,用 e_lines() 在地图上绘制边界。

得到的边界是点周围半径 50 km 范围的圆周轮廓,范围按地理位置计算,边界会随地图缩放。

为什么不能直接设置圆的大小?

散点的 symbol_size 控制显示尺寸,不能直接表达地面距离。e_polygon_g() 属于底层 Graphic 接口,不会自动将经纬度和公里数转换成地图上的多边形。直接传入地理坐标,无法完成所需的距离计算和地图定位。参见 echarts4r Graphic 文档。

因此,需要先算出圆周上的地理坐标,再交给地图坐标系绘制。

在原有代码后添加缓冲区和边界

保留原问题中获取 geo_data、创建 locations 的代码,用下面的代码替换最后的绘图部分:

# EPSG:28992 为荷兰当地的投影坐标系,距离单位为米
buffers <- locations |>
  st_as_sf(coords = c("lon", "lat"), crs = 4326) |>
  st_transform(28992) |>
  st_buffer(dist = 50000, nQuadSegs = 90) |>
  st_transform(4326)

# 每个点的缓冲区分别拆成相邻顶点之间的线段
# 点缓冲区的外环首尾闭合,因此最后一段也会被保留
segments <- lapply(seq_len(nrow(buffers)), function(i) {
  xy <- st_coordinates(st_geometry(buffers)[[i]])[, c("X", "Y")]
  n <- nrow(xy)

  data.frame(
    source_lon = xy[-n, 1],
    source_lat = xy[-n, 2],
    target_lon = xy[-1, 1],
    target_lat = xy[-1, 2],
    city = buffers$name[i],
    radius_km = 50
  )
}) |>
  dplyr::bind_rows()

locations |>
  e_charts(lon) |>
  e_map_register("NL", geo_data) |>
  e_geo(
    map = "NL",
    nameProperty = "statnaam",
    roam = TRUE
  ) |>
  e_scatter(
    lat,
    name = "City",
    coord_system = "geo",
    symbol_size = 8
  ) |>
  e_data(segments, source_lon) |>
  e_lines(
    source_lon,
    source_lat,
    target_lon,
    target_lat,
    source_name = city,
    target_name = city,
    value = radius_km,
    name = "50 km radius",
    coord_system = "geo",
    symbol = c("none", "none"),
    lineStyle = list(
      color = "#d95f02",
      width = 2,
      opacity = 0.8,
      curveness = 0
    ),
    effect = list(show = FALSE),
    silent = TRUE
  )

e_data() 为后续图层切换数据,已经添加的城市散点仍保留原来的数据。e_lines() 根据每段边界起点和终点的经纬度,在同一个 geo 坐标系中绘制线段。对应接口见 e_data 文档和 e_lines 文档。

每个缓冲区都单独拆成线段,避免把 Amsterdam 的圆周末端错误地连接到 Utrecht 的圆周起点。

距离和精度需要注意什么?

  • 50000 表示 50,000 米,即半径 50 km;直径为 100 km。
  • st_transform() 会实际转换坐标。不能只修改 CRS 标签,否则坐标数值不会改变,距离计算仍会出错。
  • nQuadSegs = 90 表示每个四分之一圆使用 90 条线段。增大该值可以让轮廓更平滑,也会增加传给浏览器的数据量。该参数在这里使用的投影坐标缓冲计算中生效,详见 sf 的 st_buffer 文档。
  • EPSG
    适用于这个荷兰示例。它计算的是投影平面上的 50 km 缓冲区,与椭球面上的严格等距圆仍有投影误差。用于其他地区时,应选择合适的当地投影;若业务要求严格的测地距离,应改用测地线方法生成圆周坐标。
  • 经纬度地图上的圆形范围可能看起来略扁,这是显示投影造成的。不要通过调整像素宽高来修正地理边界。

示例只画轮廓。若需要半透明填充,应使用支持地理坐标的多边形绘制方案,并复用这里生成的缓冲区几何。

备注:内容仅供参考。