如何在 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 缓冲区,与椭球面上的严格等距圆仍有投影误差。用于其他地区时,应选择合适的当地投影;若业务要求严格的测地距离,应改用测地线方法生成圆周坐标。
- 经纬度地图上的圆形范围可能看起来略扁,这是显示投影造成的。不要通过调整像素宽高来修正地理边界。
示例只画轮廓。若需要半透明填充,应使用支持地理坐标的多边形绘制方案,并复用这里生成的缓冲区几何。
备注:内容仅供参考。
