Highcharter:地图线未在 R 中的 Highcharts 地图上显示连接

问题描述 投票:0回答:1

我正在尝试使用 Highcharter 包在 R 中创建世界地图。目标是绘制圣保罗与前 10 个出口目的地之间的连接(线),每个连接由地图上的一条线(地图线类型)表示。但是,线条未显示。

我尝试了多种方式格式化数据,但线条仍然没有显示在地图上。下面是我正在使用的代码,以及数据集结构和我的预期输出的描述。

plot with highchart example with the lines, but it's not the package I want

# df
top_destinations <- tibble(
  Cidade = rep("São Paulo - SP", 10),
  Nome_Pais = c("China", "Canadá", "Estados Unidos", "Itália", "Bélgica", 
                "Emirados Árabes Unidos", "Suíça", "Argentina", "Índia", "Argélia"),
  Lat_Municipio = rep(-23.6, 10),
  Long_Municipio = rep(-46.6, 10),
  Lat_PAIS = c(33.4, 59.1, 39.6, 42.7, 50.6, 23.5, 46.9, -35.4, 21.0, 28.2),
  Long_PAIS = c(107.0, -109.0, -98.6, 12.8, 4.66, 54.2, 7.91, -65.2, 78.5, 2.63),
  US_FOB = c(1e9, 3.46e8, 3.08e8, 2.26e8, 2.04e8, 1.63e8, 1.14e8, 1.08e8, 9.3e7, 8.12e7)
)

# Packages
library(highcharter)
library(dplyr)

# Load world map data
worldgeojson <- get_data_from_map(download_map_data("https://code.highcharts.com/mapdata/custom/world.geo.json"))

# Prepare data for destination points
dest_points <- data.frame(
  lat = top_destinations$Lat_PAIS,
  lon = top_destinations$Long_PAIS,
  name = top_destinations$Nome_Pais,
  US_FOB = top_destinations$US_FOB
)

# Prepare data for connections (maplines)
connections <- lapply(1:nrow(top_destinations), function(i) {
  list(
    from = list(lat = top_destinations$Lat_Municipio[i], lon = top_destinations$Long_Municipio[i]),
    to = list(lat = top_destinations$Lat_PAIS[i], lon = top_destinations$Long_PAIS[i])
  )
})

# Create the map with Highcharts
highchart(type = "map") %>%
  # Add base map
  hc_add_series(
    mapData = worldgeojson,
    showInLegend = FALSE,
    nullColor = "#E0E0E0",
    borderWidth = 0
  ) %>%
  hc_mapNavigation(enabled = TRUE) %>%
  # Add São Paulo as the origin point
  hc_add_series(
    type = "mappoint",
    data = data.frame(
      lat = top_destinations$Lat_Municipio[1],
      lon = top_destinations$Long_Municipio[1],
      name = "São Paulo",
      color = "#3d9970",
      US_FOB = sum(top_destinations$US_FOB)
    ),
    marker = list(symbol = "circle", radius = 4),
    tooltip = list(pointFormat = "City: {point.name}<br>Export Value: {point.US_FOB}")
  ) %>%
  # Add destination points
  hc_add_series(
    type = "mappoint",
    name = "Destinations",
    data = dest_points,
    color = "#d35400",
    marker = list(symbol = "circle", radius = 3),
    tooltip = list(pointFormat = "Country: {point.name}<br>Export Value: {point.US_FOB}")
  ) %>%
  # Add connections between São Paulo and destinations
  hc_add_series(
    type = "mapline",
    data = connections,
    lineWidth = 1.5,
    opacity = 0.8,
    showInLegend = FALSE,
    enableMouseTracking = FALSE
  ) %>%
  # Title and tooltip settings
  hc_title(text = "Main Export Destinations from São Paulo") %>%
  hc_tooltip(useHTML = TRUE)
r highcharts mapping maps
1个回答
0
投票

我相信您只能将

mapline
类型与
geo_json
geo_list
{geojsonio}
对象一起使用(参考:
hc_add_series
用于
geo_json
geo_list
对象
)。

我正在使用

sf
构建一组线串,这些线串将使用
highcharter
转换为
geojson_list()
。由于我无论如何都需要源点和目标点为
sf
/
sfc
对象,因此我为所有数据对象切换到
sf
的空间数据框。

无论出于何种原因,highcharts.com都没有为我切断world.geo.json,因此使用来自

{giscoR}
的底图。

library(highcharter)
library(geojsonio)
library(dplyr)
library(sf)
#> Linking to GEOS 3.12.1, GDAL 3.8.4, PROJ 9.3.1; sf_use_s2() is TRUE

worldgeojson <-
  giscoR::gisco_countries %>%
  geojsonio::geojson_json()

# sf object with a source point
src_point_sf <- 
  top_destinations %>%
  summarise(
    name = "São Paulo", 
    US_FOB = sum(US_FOB),
    lat = first(Lat_Municipio),
    lon = first(Long_Municipio)
  ) |> 
  st_as_sf(coords = c("lon", "lat"), crs = "WGS84")

# Prepare data for destination points
dest_points_sf <- 
  top_destinations %>%
  st_as_sf(coords = c("Long_PAIS", "Lat_PAIS"), crs = "WGS84") %>%
  select(name = Nome_Pais, US_FOB)

# sf object with connection lines (generate point pair, union, cast to line)
connections_sf <- 
  lapply(
    st_geometry(dest_points_sf), 
    \(to) st_union(c(st_geometry(src_point_sf)[[1]], to)) %>% st_cast("LINESTRING") ) %>% 
  st_as_sfc(crs = st_crs(dest_points_sf)) %>% 
  st_sf(geometry = _) %>% 
  # with just 2 endpoints we'd get straight lines,
  # adding a vertex at every 1000km introduces curves once linestrings are projected
  st_segmentize(dfMaxLength = 1000*1000)

# Create the map with Highcharts
highchart(type = "map") %>%
  # Add base map
  hc_add_series(
    mapData = worldgeojson, 
    showInLegend = FALSE,
    nullColor = "#E0E0E0",
    borderWidth = 0
  ) %>%
  hc_mapNavigation(enabled = TRUE) %>%
  # Add São Paulo as the origin point
  hc_add_series(
    data = geojson_list(src_point_sf),
    type = "mappoint",
    marker = list(symbol = "circle", radius = 4),
    color = "#3d9970" ,
    tooltip = list(pointFormat = "City: {point.properties.name}<br>Export Value: {point.properties.US_FOB}")
  ) %>%
  # Add destination points
  hc_add_series(
    data = geojson_list(dest_points_sf),
    type = "mappoint",
    name = "Destinations",
    color = "#d35400",
    marker = list(symbol = "circle", radius = 3),
    tooltip = list(pointFormat = "Country: {point.properties.name}<br>Export Value: {point.properties.US_FOB}")
  ) %>%  
  # Add connections between São Paulo and destinations
  hc_add_series(
    data = geojson_list(connections_sf),
    type = "mapline",
    lineWidth = 1.5,
    opacity = 0.8,
    showInLegend = FALSE,
    enableMouseTracking = FALSE
  ) %>%
  # Title and tooltip settings
  hc_title(text = "Main Export Destinations from São Paulo") %>%
  hc_tooltip(useHTML = TRUE)

示例数据:

# df
top_destinations <- tibble(
  Cidade = rep("São Paulo - SP", 10),
  Nome_Pais = c("China", "Canadá", "Estados Unidos", "Itália", "Bélgica", 
                "Emirados Árabes Unidos", "Suíça", "Argentina", "Índia", "Argélia"),
  Lat_Municipio = rep(-23.6, 10),
  Long_Municipio = rep(-46.6, 10),
  Lat_PAIS = c(33.4, 59.1, 39.6, 42.7, 50.6, 23.5, 46.9, -35.4, 21.0, 28.2),
  Long_PAIS = c(107.0, -109.0, -98.6, 12.8, 4.66, 54.2, 7.91, -65.2, 78.5, 2.63),
  US_FOB = c(1e9, 3.46e8, 3.08e8, 2.26e8, 2.04e8, 1.63e8, 1.14e8, 1.08e8, 9.3e7, 8.12e7)
)

© www.soinside.com 2019 - 2024. All rights reserved.