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

基于R的mapboxapi与mapboxer实现Mapbox hover信息窗动态更新

R实现Mapbox缩放切换图层+Hover信息窗口(纯HTML)

以下是完整的实现代码,无需上传Mapbox样式,完全通过R+HTML/JS在本地实现缩放图层切换和鼠标hover动态更新信息窗口的功能:

library(mapboxer)
library(htmlwidgets)
library(mapboxapi)
library(htmltools)

# 1. 准备示例数据:低缩放用聚合点,高缩放用详细点
# 可替换为你自己的数据集
low_zoom_data <- mb_get_tiles(
  tileset_id = "mapbox.mapbox-streets-v8",
  x = 0, y = 0, z = 5,
  access_token = Sys.getenv("MAPBOX_PUBLIC_TOKEN")
) %>% sf::st_as_sf()

high_zoom_data <- mb_get_tiles(
  tileset_id = "mapbox.mapbox-streets-v8",
  x = 0, y = 0, z = 10,
  access_token = Sys.getenv("MAPBOX_PUBLIC_TOKEN")
) %>% sf::st_as_sf()

# 2. 构建基础Mapbox地图
map <- mapboxer(
  style = "mapbox://styles/mapbox/light-v11",
  center = c(-95.7129, 37.0902),
  zoom = 5,
  access_token = Sys.getenv("MAPBOX_PUBLIC_TOKEN")
) %>%
  # 添加低缩放图层(默认显示)
  add_circle_layer(
    id = "low-zoom-layer",
    source = low_zoom_data,
    circle_radius = 8,
    circle_color = "#2196F3"
  ) %>%
  # 添加高缩放图层(默认隐藏)
  add_circle_layer(
    id = "high-zoom-layer",
    source = high_zoom_data,
    circle_radius = 5,
    circle_color = "#F44336",
    visibility = "none"
  ) %>%
  # 添加hover信息窗口的样式
  prependContent(tags$style(HTML("
    #hover-info {
      position: absolute;
      background: white;
      padding: 8px 12px;
      border-radius: 4px;
      box-shadow: 0 2px 4px rgba(0,0,0,0.2);
      pointer-events: none;
      display: none;
      z-index: 1000;
      font-size: 14px;
    }
  "))) %>%
  # 添加hover信息窗口的DOM容器
  prependContent(tags$div(id = "hover-info")) %>%
  # 注入自定义JS实现交互逻辑
  onRender("
    function(el, x) {
      var map = this;
      var hoverInfo = document.getElementById('hover-info');

      // 缩放级别切换图层
      map.on('zoomend', function() {
        var zoom = map.getZoom();
        if (zoom >= 8) {
          map.setLayoutProperty('low-zoom-layer', 'visibility', 'none');
          map.setLayoutProperty('high-zoom-layer', 'visibility', 'visible');
        } else {
          map.setLayoutProperty('low-zoom-layer', 'visibility', 'visible');
          map.setLayoutProperty('high-zoom-layer', 'visibility', 'none');
        }
      });

      // Hover信息窗口逻辑
      ['low-zoom-layer', 'high-zoom-layer'].forEach(function(layerId) {
        // 鼠标移动到图层要素上时更新信息
        map.on('mousemove', layerId, function(e) {
          var feature = e.features[0];
          // 自定义信息内容,根据你的数据字段调整
          var infoContent = '<strong>要素ID:</strong> ' + feature.id + '<br>' +
                            '<strong>类型:</strong> ' + feature.properties.type;
          
          hoverInfo.innerHTML = infoContent;
          hoverInfo.style.display = 'block';
          // 跟随鼠标位置
          hoverInfo.style.left = e.originalEvent.clientX + 10 + 'px';
          hoverInfo.style.top = e.originalEvent.clientY + 10 + 'px';
        });

        // 鼠标离开图层时隐藏信息窗口
        map.on('mouseleave', layerId, function() {
          hoverInfo.style.display = 'none';
        });
      });
    }
  ")
)

# 输出地图
map

关键部分说明:

  1. 图层切换:

    • 通过监听zoomend事件,根据当前缩放级别调用setLayoutProperty切换图层的可见性,比直接设置minzoom/maxzoom更灵活,适合复杂切换规则。
  2. Hover信息窗口:

    • 自定义HTML容器+CSS样式实现悬浮信息框,避免依赖Mapbox默认的点击触发popup。
    • 对每个图层分别监听mousemove和mouseleave事件,动态更新信息框内容和显示状态,鼠标位置实时跟随。
  3. 纯HTML本地运行:

    • 所有数据、图层配置和交互逻辑都嵌入在生成的HTML文件中,无需上传自定义样式到Mapbox平台,直接打开HTML即可运行。

调整提示:

  • 替换示例数据为你的业务数据集,修改infoContent中的字段(feature.properties.xxx)匹配你的数据结构。
  • 通过Sys.setenv(MAPBOX_PUBLIC_TOKEN = "你的公钥")设置Mapbox访问令牌。
  • 如需修改信息窗口样式,直接调整tags$style中的CSS代码即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 08:28:41