指南:无底图、图片瓦片与本地图案底图)
数据可视化数据分析GIS【免费下载链接】foliumPython Data. Leaflet.js Maps.项目地址https://gitcode.com/gh_mirrors/fo/folium点击查看免费下载本文围绕 docs/advanced_guide/custom_tiles.md 展开讲解 Folium 中Map的tiles参数在自定义场景下的三种典型用法完全不加载底图tilesNone、把本地数组生成的图片当作瓦片源、以及构造大尺寸棋盘格图案作为底图。读完本文你将掌握branca.utilities.image_to_url/folium.utilities.image_to_url的 data URL 生成原理、自定义瓦片必须携带attr归属信息的约束并能用任意本地图片或图案为自己的地图搭建可运行的底图层。tiles 参数Folium 底图层的唯一注入入口Folium 的地图对象folium.Map通过tiles关键字统一管理底图层。根据 folium/folium.py 的 docstringtiles的取值可以是内置瓦片名OpenStreetMap、CartoDB Positron、CartoDB Voyager等Folium 内置了xyzservices包中的全部瓦片源一个xyzservices.TileProvider对象用于精确指定某个瓦片供应商一个 Leaflet 风格的瓦片 URL 模板例如https://{s}.yourtiles.com/{z}/{x}/{y}.png一个现成的folium.raster_layers.TileLayer对象None创建一个没有任何底图的地图。从源码看Map.__init__对tiles的处理非常简洁folium/map.pyif isinstance(tiles, TileLayer): self.add_child(tiles) elif tiles: tile_layer TileLayer( tilestiles, attrattr, min_zoommin_zoom, max_zoommax_zoom ) self.add_child(tile_layer, nametile_layer.tile_name)也就是说传入TileLayer实例时直接挂载传入字符串或TileProvider时由TileLayer二次解析并构造传入None或空值时什么都不创建——这正是无底图地图的实现基础。最终TileLayer的 Jinja 模板会把它渲染为 Leaflet 的L.tileLayer(url, options)调用folium/raster_layers.py。无底图地图tilesNone当只需要突出显示数据本身例如行政区边界、轨迹、点标记而不需要任何地理底图时可以传入tilesNone。官方指南中的做法如下import folium states ... # GeoJSON FeatureCollection例如美国各州边界 kw {location: [48, -102], zoom_start: 3} m folium.Map(tilesNone, **kw) folium.GeoJson(states).add_to(m) m代码先定义了一个公共参数kw中心点[48, -102]、初始缩放级别 3随后创建不带底图的地图并把 GeoJSON 边界图层叠加其上。这里的states数据在官方示例中取自 folium-example-data 仓库的us_states.json如果你在本地跑同样的效果可以直接使用本仓库已有的 examples/data/us-states.json读取方式如下import json with open(examples/data/us-states.json) as f: states json.load(f)tilesNone也是 Folium 测试代码中非常常见的写法例如 tests/test_map.py 中Map(tilesNone)与TileLayer、Marker、GeoJson、LayerControl的组合验证以及tests/snapshots/modules/issue_1885.py等快照模块中大量folium.Map(tilesNone, ...)的用法。这说明无底图 自定义图层是社区验证过的稳定组合特别适合做纯数据可视化或后续叠加高透明度瓦片层。用图片作为瓦片image_to_url 与 data URL 机制最小示例一张 4 像素的白色瓦片指南展示了如何把一张 4 像素2×2的白色图片直接作为整个地图的瓦片源import branca # 创建一个 4 像素的白色图片并嵌入到一个 url 中。 white_tile branca.utilities.image_to_url([[1, 1], [1, 1]]) # 使用这个 url 作为每个瓦片的来源。 m folium.Map(tileswhite_tile, attrwhite tile, **kw) folium.GeoJson(states).add_to(m) m[[1, 1], [1, 1]]是一个 2×2 的二维数组image_to_url会把它编码为一张 PNG 图片再以 base64 字符串的形式拼装成一个 data URL。把这个 data URL 传给tiles后Leaflet 在加载每个瓦片时都会请求这同一个 URL——由于 data URL 的内容已完整嵌入 HTML 中整个过程不需要任何瓦片服务器浏览器直接解码显示。源码解析image_to_url 究竟做了什么branca.utilities.image_to_url是 branca 库Folium 的核心依赖提供的工具Folium 自身也在 folium/utilities.py 提供了行为一致的同名实现其 docstring 和代码逻辑与 branca 完全对应。它的处理分支如下字符串且不是 URL按文件路径打开图片读取二进制内容base64 编码后生成data:image/{扩展名};base64,...形式的 URL字符串是 URL_is_url通过urlparse校验协议folium/utilities.py合法则直接作为链接使用字符串是 JSON其余字符串会被当作 JSONround-trip 格式化后嵌入数组含 numpy 数组调用write_png将其编码为 PNG 字节流再 base64 编码为data:image/png;base64,...folium/utilities.py。此外该函数还支持两个可选参数参数默认值作用originupper决定数组的[0, 0]索引位于图片的左上角还是左下角取值upper/lowercolormapNone仅用于单通道mono灰度图接受形如x - (r, g, b)或x - (r, g, b, a)的函数把灰度值映射为 0~1 之间的 RGB(A) 元组可直接使用matplotlib.cm中的色带这也意味着image_to_url的输入非常灵活除了示例中的二维数组你还可以传一张本地图片文件路径甚至一个由matplotlib生成的numpy.ndarray。自定义瓦片必须声明归属attr注意上面示例中给Map额外传入了attrwhite tile。这不是可选项TileLayer.__init__在构造自定义瓦片时会强制检查folium/raster_layers.pyif not attr: raise ValueError(Custom tiles must have an attribution.)即自定义瓦片必须提供归属信息attribution。这与内置瓦片不同——使用xyzservices.TileProvider时attr会自动从tiles.html_attribution填充folium/raster_layers.py而自定义 URL 或 data URL 无法自动推断归属因此必须显式指定否则直接抛出ValueError。生成更大的图案作为瓦片棋盘格底图第一种模式对角斜向条纹指南接着用 300×300 的数组生成棋盘格图案images [[(-1) ** ((i j) // 30) for i in range(300)] for j in range(300)] tiles branca.utilities.image_to_url(images) m folium.Map(tilestiles, attrJust because we can, **kw) folium.GeoJson(states).add_to(m) m这里的表达式(-1) ** ((i j) // 30)i是列索引横向j是行索引纵向。由于i j恒定意味着同一条对角线(i j) // 30每跨过 30 个单位变化一次于是图案由宽度为 30 像素的斜向条纹交替组成——整张图在放大后会呈现清晰的 45° 斜纹效果。第二种模式水平与垂直网格images [[(-1) ** ((i // 30 j // 30)) for i in range(300)] for j in range(300)] tiles branca.utilities.image_to_url(images) m folium.Map(tilestiles, attrJust because we can, **kw) folium.GeoJson(states).add_to(m) m与第一种模式的区别在于把i j换成了i // 30 j // 30i // 30每 30 列变化一次形成竖直条带j // 30每 30 行变化一次形成水平条带二者之和的奇偶性把画面切分成 2×2 的网格单元——即标准的 30px×30px 棋盘格。两种模式放在一起对比正好演示了如何用极少的数学表达式控制瓦片图案的形态。无论哪种模式最终每个瓦片都是同一张图案data URL 中不含{z}/{x}/{y}占位符因此画面实际上是把这幅 300×300 图案无限平铺在地图上。attr在这里同样不可或缺示例中的Just because we can展示了它可以是任意描述性字符串。进阶实战把自定义瓦片用到真实项目中1. 指向真实瓦片服务器的 URLtiles更常见的用法是传入一个标准的 Leaflet 瓦片 URL 模板此时{z}缩放级别、{x}、{y}瓦片行列号以及可选的{s}子域占位符会被 Leaflet 逐瓦片替换。例如 folium/folium.py docstring 中的 Mapbox 示例m folium.Map( location[45.523, -122.675], zoom_start2, tileshttps://api.mapbox.com/v4/mapbox.streets/{z}/{x}/{y}.png?access_tokenmytoken, attrMapbox attribution, )自定义 URL 在TileLayer中的解析流程是先尝试用xyzservices.providers.query_name(tiles)按名称匹配内置供应商匹配失败则当作自定义 URL 直接使用folium/raster_layers.py。这类 URL 的瓦片请求会真正打到远程服务器因此归属信息attr是服务条款层面的硬要求。2. 使用 TileLayer 精细控制瓦片行为TileLayer暴露的参数比Map的tiles简写更全面folium/raster_layers.py关键参数如下参数默认值说明min_zoom/max_zoom0/18瓦片层允许的最小/最大缩放级别使用TileProvider时由供应商自动填充max_native_zoomNone瓦片服务器能提供瓦片的最高原生缩放级别把max_zoom设得更高时超出部分会由 Leaflet 自动放大attrNone归属信息自定义瓦片必填detect_retinaFalse为 True 时视网膜屏幕会用2x的高清瓦片替换普通瓦片subdomainsabc瓦片服务的子域列表用于分散请求tmsFalse为 True 时反转 Y 轴编号用于 TMS 协议服务opacity1图层不透明度no_wrapFalse禁止地图在水平方向无限循环平铺overlay/control/showFalse/True/True决定该层作为覆盖层还是底图层、是否出现在 LayerControl、打开地图时是否显示例如把一张半透明的自定义图片瓦片作为覆盖层叠加在标准底图上import folium from folium.raster_layers import TileLayer tiles folium.utilities.image_to_url([[1, 1], [1, 1]]) TileLayer(tilestiles, attrwhite tile, opacity0.4, overlayTrue).add_to(m)3. 与 GeoJson、LayerControl 组合本指南的三个示例都演示了自定义底图 GeoJson 边界的组合GeoJson 图层绘制在各州边界而底图则由自制的白色或棋盘格图案承担。如果同时引入folium.LayerControl()注意它应最后添加见 folium/map.py 的注释说明自定义瓦片层会自动进入图层面板允许用户在不同底图之间切换。4. 性能与使用注意图片瓦片的锯齿用单张数组图片如 2×2 白色图做瓦片时Leaflet 会把它拉伸铺满每个瓦片网格缩放级别越高图片被放大得越厉害画面会越来越模糊300×300 的棋盘格图案相对细腻但同样无法随缩放级别提供更高分辨率的内容。data URL 的体积大数组经write_png编码后体积可观base64 编码又会使其再膨胀约 33%整个 HTML 文件会随之变大。小图案或纯色底图如 2×2几乎不占空间复杂图案则要权衡。GeoJson 数据加载GeoJson的边界数据加载不依赖底图无论tilesNone还是自定义图片瓦片边界渲染都不受影响。常见问题排查Qfolium.Map(tileswhite_tile)报错Custom tiles must have an attribution.怎么办A自定义瓦片自定义 URL 或 data URL必须显式传入attr参数例如attrwhite tile这是 folium/raster_layers.py 的强制校验内置瓦片源不受影响。Q为什么整张地图显示的都是同一幅图案A因为image_to_url生成的 data URL 不包含{z}/{x}/{y}占位符Leaflet 对每个瓦片位置请求的都是同一个 URL所以图案被无限平铺。若想让瓦片随位置变化应改为传真实瓦片服务器的 URL 模板。Qbranca.utilities.image_to_url和folium.utilities.image_to_url有什么区别A两者逻辑一致branca 是 Folium 的底层依赖folium.utilities提供了同名的等价实现folium/utilities.py在任何安装了 Folium 的环境中folium.utilities.image_to_url都可以直接使用。Q除了数组还能给image_to_url传什么A本地图片文件路径、合法 URL、JSON 字符串均可folium/utilities.py灰度数组还可搭配colormap与origin参数控制配色与坐标原点方向。总结从tilesNone的纯数据地图到branca.utilities.image_to_url/folium.utilities.image_to_url生成的 data URL 图片瓦片再到 300×300 棋盘格图案底图本文完整覆盖了 docs/advanced_guide/custom_tiles.md 的三种自定义瓦片方案。其底层链路始终是Map.tiles→TileLayer解析强制attr校验→L.tileLayer(url, options)渲染。掌握了这条链路与image_to_url的数据编码规则你就能自由地为 Folium 地图配置任意本地生成的底图、叠加半透明瓦片层或将任何符合 Leaflet 规范的瓦片服务器接入自己的地图项目中。赞分享数据可视化数据分析GIS【免费下载链接】foliumPython Data. Leaflet.js Maps.项目地址https://gitcode.com/gh_mirrors/fo/folium点击查看免费下载相关推荐Metabase 自定义地图完全指南瓦片服务器替换与自定义区域地图Custom Maps实战Metabase 自定义地图完全指南瓦片服务器替换与自定义区域地图Custom Maps实战 Metabase 的地图可视化默认依赖 OpenStreet数据分析数据可视化后端数据库客户端企业应用Tiled瓦片集切片工具从 sprite sheet 到地图瓦片Tiled瓦片集切片工具从 sprite sheet 到地图瓦片 在游戏开发中你是否曾为如何将一张包含多个角色或场景元素的精灵图Sprite Sheet游戏开发桌面应用开发工具上一篇探索智能家居新维度Matt8707的HASS配置仓库打造终极可视化控制中心下一篇前端开发资源宝库一站式学习与提升创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考