如何让Quarto生成的Leaflet地图从JSON加载数据以缩减HTML体积
Leaflet地图从JSON加载数据的实现方法
第一步:在R里导出地图数据为JSON
不要直接在Quarto里渲染Leaflet地图,而是先把地图的核心数据提取出来存成JSON文件:
library(leaflet) library(jsonlite) # 生成你的Leaflet地图对象 my_map <- leaflet() %>% addTiles() %>% addMarkers(data = your_large_dataset) # 提取widget的核心配置数据(剔除依赖库相关内容) map_core_data <- my_map$x # 保存到项目的data目录下,确保路径正确 write_json(map_core_data, "data/leaflet_map_1.json", auto_unbox = TRUE)
第二步:在Quarto里写空容器和自定义加载脚本
在Quarto文档里,替换原来的leaflet()调用,改成空div容器,再写脚本从JSON拉数据并触发渲染:
--- title: "带外部数据的Leaflet地图" embed-resources: false --- ## 我的地图 <!-- 给地图准备空容器,设置好宽高 --> <div id="map-container-1" class="html-widget html-widget-static-bound" style="width:100%; height:500px;"></div> <script> // 等DOM和所有依赖脚本加载完再执行 document.addEventListener("DOMContentLoaded", () => { // 监听htmlwidgets的ready事件,确保Leaflet渲染器已经注册 htmlwidgets.addPostRenderHook(() => { // 拉取外部JSON数据 fetch("data/leaflet_map_1.json") .then(res => res.json()) .then(mapData => { // 手动调用htmlwidgets的初始化方法,指定容器ID和数据 htmlwidgets.widget({ name: "leaflet", type: "output", id: "map-container-1", x: mapData, options: {} }); }); }); }); </script>
多地图场景的处理
如果有多个地图,给每个容器分配唯一ID,对应不同的JSON文件:
- 每个地图的JSON命名为
map_1_data.json、map_2_data.json - 空div的ID设为
map-container-1、map-container-2 - 脚本里分别fetch对应JSON,调用
htmlwidgets.widget时指定对应的ID即可
关键注意事项
- 确保JSON文件路径正确:Quarto生成静态页后,
data目录会被复制到_site目录下,所以路径要基于生成后的静态页位置来写 - 不要手动删除Quarto自动引入的
leaflet.js和htmlwidgets.js,embed-resources: false已经帮你分离成外部脚本,会自动加载 - 必须等
htmlwidgets的渲染器注册完成再加载数据,不然会报“找不到leaflet渲染器”的错误,用addPostRenderHook就是为了等这个时机
内容的提问来源于stack exchange,提问作者SamR
相关产品推荐
相关产品推荐

