ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

folium 图像叠加实战:用 ImageOverlay 在 Leaflet 地图上绘制本地图片、URL 图片与 numpy 数组

folium 图像叠加实战:用 ImageOverlay 在 Leaflet 地图上绘制本地图片、URL 图片与 numpy 数组 数据可视化数据分析GIS【免费下载链接】foliumPython Data. Leaflet.js Maps.项目地址https://gitcode.com/gh_mirrors/fo/folium点击查看免费下载导读在基于 folium 的 Web 地图应用中经常需要把一张静态图片如扫描图、遥感影像、热力图网格精确“贴”到地图的指定经纬度范围上。本文以官方指南 docs/user_guide/raster_layers/image_overlay.md 为核心骨架结合仓库源码 folium/raster_layers.py 与测试用例完整讲解folium.raster_layers.ImageOverlay的三种图片来源本地文件、URL、numpy 数组、全部核心参数以及最容易被忽视的 Mercator 投影校正问题。读完本文你将能够把任意图像以像素级精度叠加到经纬度边界内并处理数组坐标系与投影带来的偏移陷阱。什么是 ImageOverlayImageOverlay是 folium 对 Leaflet 官方L.imageOverlay的封装类用于“加载并在地图的特定边界内显示一张图片”。它的本质是给定一张图片资源本地路径、URL 或 numpy 数组和一组经纬度边界bounds把图片拉伸铺满该矩形区域作为地图上的一个覆盖层overlay参与图层的显示、隐藏与叠加。从源码看ImageOverlay继承自Layer其核心初始化逻辑位于 folium/raster_layers.pydef __init__( self, image: Any, bounds: TypeBounds, origin: str upper, colormap: Optional[Callable] None, mercator_project: bool False, pixelated: bool True, name: Optional[str] None, overlay: bool True, control: bool True, show: bool True, **kwargs, ):在渲染时它通过模板把数据转换成 Leaflet 可执行的 JavaScript 调用var {{ this.get_name() }} L.imageOverlay( {{ this.url|tojson }}, {{ this.bounds|tojson }}, {{ this.options|tojavascript }} );其中url是由folium.utilities.image_to_url根据传入的image类型动态生成的bounds则原样传给 Leaflet。因此使用ImageOverlay前需要重点理解三件事图片如何被编码成 URL、bounds 如何指定、数组图片如何处理投影。核心参数速览以下参数来自 folium/raster_layers.py 中ImageOverlay的类文档与签名是实战中的主要可调项参数类型默认值说明imagestring 或 array-like必填图片来源本地文件路径会被 Base64 嵌入、URL外链引用、JSON 字符串按 JSON 嵌入、数组转换为 PNG Base64 嵌入bounds[[lat_min, lon_min], [lat_max, lon_max]]必填图片在地图上的经纬度边界必须是嵌套列表/元组opacityfloatLeaflet 默认 1.0图层不透明度0~1 之间altstring图片的替代文本alt 属性originupper或lowerupper数组[0,0]索引对应图像的左上角还是左下角原理同numpy.imshowcolormapcallableNone仅用于单通道mono数组图片形式x - (r,g,b)或x - (r,g,b,a)输出长度 3 或 4、取值 0~1可直接复用matplotlib.cm的 colormapmercator_projectboolFalse仅对数组图片生效把按经度,纬度坐标系计算的数组变换为 Web Mercator 投影。开启后纬度超出 ±85.0511 的部分会被裁剪pixelatedboolTrue控制缩放时像素是否锐利Truepixelated/crisp-edges渲染还是平滑抗锯齿FalsenamestringNone图层名称显示在LayerControl中overlayboolTrue作为覆盖图层True还是底图False加入controlboolTrue是否出现在LayerControl中showboolTrue地图打开时该图层是否默认可见此外**kwargs会透传给 Leaflet 的L.imageOverlay对象可参考 Leaflet 官方 ImageOverlay 文档并通过remove_empty过滤掉空值后写入self.options。例如官方指南中用到的interactive、cross_origin、zindex正是通过这一机制传入的。用法一从本地磁盘加载图片如果你有一张静态图片文件可以把它直接画到地图上。官方指南给出的完整示例路径以仓库根目录为起点换算import os import folium m folium.Map([0, 0], zoom_start2) image_filepath os.path.join(docs, _static, folium_logo.png) img folium.raster_layers.ImageOverlay( nameFolium logo, imageimage_filepath, bounds[[-50, -45], [50, 45]], opacity0.6, interactiveTrue, cross_originFalse, zindex1, ) folium.Popup(I am an image).add_to(img) img.add_to(m) folium.LayerControl().add_to(m) m这段代码演示了几个关键点本地文件会被 Base64 嵌入。从 folium/utilities.py 的image_to_url实现可以看到只要传入的是字符串且不是 URLfolium 就会读取文件内容、用base64.b64encode编码并生成data:image/{fileformat};base64,...形式的 data URL 嵌入到输出 HTML 中。这意味着地图 HTML 文件可以脱离原图片独立打开代价是 HTML 体积变大。bounds[[-50, -45], [50, 45]]表示图片将被拉伸覆盖西经 45°东经 45°、南纬 50°北纬 50° 的矩形区域。opacity0.6做半透明叠加便于同时观察底图。interactiveTrue允许该图层响应鼠标事件因此可以把folium.Popup(I am an image)挂到它上面——点击图片即可弹出提示框。官方指南特别提醒你的图片必须使用 Mercator 投影格式即图片内容本身应当符合 Web 地图的墨卡托投影坐标系详见后文第五节。pixelated参数同样在此生效当pixelatedTrue时模板会向页面注入一段 CSS让图像在缩放时使用image-rendering: pixelatedChrome、crisp-edgesSafari/Firefox等渲染模式保证放大时边缘锐利清晰见 folium/raster_layers.py。用法二从 URL 加载远程图片如果图片来源是网络 URL直接传入字符串即可m folium.Map([37, 0], zoom_start1) folium.raster_layers.ImageOverlay( imagehttps://upload.wikimedia.org/wikipedia/commons/f/f4/Mercator_projection_SW.jpg, nameI am a jpeg, bounds[[-82, -180], [82, 180]], opacity1, interactiveFalse, cross_originFalse, zindex1, altWikipedia File:Mercator projection SW.jpg, ).add_to(m) folium.LayerControl().add_to(m) m与本地文件的关键区别在于嵌入方式image_to_url通过_is_url使用urlparse检查 URL scheme 是否合法识别出这是外链后会原样保留该 URL而不是 Base64 嵌入folium/utilities.py。也就是说输出 HTML 里只保留图片 URL图片不会被嵌入浏览器渲染时需要能访问该网址nameI am a jpeg让该图层在LayerControl中以该名称显示alt参数为图片提供替代文本官方指南明确指出JPG 与 PNG 在此场景下处理方式完全相同只需更换 URL 即可。远程 URL 方式适合引用大型图片避免 HTML 体积膨胀但代价是离线或跨域受限时图片可能无法显示。用法三用 numpy 数组动态生成图像这是ImageOverlay最有价值的使用场景先用 Python 计算生成数据再把它渲染成覆盖层。前提是本机安装了 numpy。基础把数组直接画到地图上官方指南示例——在[[0, -60], [60, 60]]的边界内画一个红色矩形边框import numpy as np image np.zeros((61, 61)) image[0, :] 1.0 image[60, :] 1.0 image[:, 0] 1.0 image[:, 60] 1.0 m folium.Map([37, 0], zoom_start2) folium.raster_layers.ImageOverlay( imageimage, bounds[[0, -60], [60, 60]], colormaplambda x: (1, 0, 0, x), ).add_to(m) m这里image是一个 61×61 的单通道mono数组数值 1.0 表示不透明红色0.0 表示透明。核心规则是必须提供 colormap。对于单通道数组colormap的形式必须是lambda x: (R, G, B, A)其中R, G, B, A是 0~1 之间的浮点数。本例lambda x: (1, 0, 0, x)的含义是固定红色通道为 1、绿色蓝色为 0alpha 通道取数组值x本身——于是数组值为 1 的像素显示为不透明红色值为 0 的像素完全透明。从image_to_url的源码可知folium/utilities.py凡是类名包含ndarray的对象都会走write_png分支被编码为data:image/png;base64,...嵌入输出。colormap 同样兼容matplotlib.cm中现成的 colormap 对象如plt.cm.viridis前提是其输出满足 3 或 4 元组、取值 0~1 的约定folium/raster_layers.py。深入origin 参数与“线条错位”问题官方指南接着演示了一个容易踩坑的场景——在纬度 45° 处画一条线并用folium.PolyLine验证位置import numpy as np image np.zeros((61, 1)) image[45, :] 1.0 m folium.Map([37, 0], zoom_start3) folium.raster_layers.ImageOverlay( imageimage, bounds[[0, -60], [60, 60]], colormaplambda x: (1, 0, 0, x), originlower, ).add_to(m) folium.PolyLine([[45, -60], [45, 60]]).add_to(m) m这里需要originlower因为数组第 0 行对应数据中的最低纬度必须告诉 folium数组的第一行绘制在图像底部与numpy.imshow的origin参数同义默认upper。如果origin设错图像会上下颠倒。但即便设置了originlower红色线条仍然没有落在正确的纬度上。官方指南指出这是 Leaflet以及绝大多数地图系统采用Mercator墨卡托投影导致的必然现象在地理坐标系等经纬度网格中纬度 45° 的线是一条水平直线在 Web Mercator 投影下纬度越高同等的纬度差在屏幕上占据的像素高度越小纬度被“压缩”因此按等间距数组直接贴图时线条会偏离真实纬度位置。解决mercator_projectTrue官方给出的终极方案是让 folium 帮你处理投影m folium.Map([37, 0], zoom_start3) folium.PolyLine([[45, -60], [45, 60]]).add_to(m) folium.raster_layers.ImageOverlay( imageimage, bounds[[0, -60], [60, 60]], originlower, colormaplambda x: (1, 0, 0, x), mercator_projectTrue, ).add_to(m) m这一次线条才精确落在纬度 45°精度取决于数组分辨率。其底层原理在 folium/utilities.py 的mercator_transform中开启mercator_projectTrue后ImageOverlay.__init__会在编码前调用mercator_transform(image, (bounds[0][0], bounds[1][0]), originorigin)folium/raster_layers.py也就是取出bounds的纬度下限与上限作为投影范围投影核心公式为np.arcsinh(np.tan(x * np.pi / 180.0)) * 180.0 / np.pi即 Web Mercator 的墨卡托函数它在每个纬度行之间做插值np.interp把等间隔的纬度采样重排为等间隔的投影坐标采样从而在视觉上“拉开”高纬区域、补偿投影压缩纬度边界超出±85.051128779806589的部分会被裁剪到该值这是 Web Mercator 的有效纬度极限见源码 folium/utilities.py支持 monoN×M、RGBN×M×3、RGBAN×M×4三种数组形状height_out可指定输出高度默认取输入高度。源码实现细节url 的生成与 bounds 的传递为了准确理解行为我们把ImageOverlay内部的关键调用链梳理如下ImageOverlay.__init__接收image、bounds把bounds原样存入self.boundsfolium/raster_layers.py若mercator_projectTrue先对数组做投影变换调用image_to_url(image, originorigin, colormapcolormap)生成self.urlfolium/raster_layers.pyimage_to_url按类型分派folium/utilities.py本地路径字符串 → Base64 编码 →data:image/{ext};base64,...ndarray →write_png编码为 PNG →data:image/png;base64,...其他URL 或 JSON→ JSON round-trip 后原样使用渲染模板把url、bounds、options注入 JavaScript 生成L.imageOverlay(...)调用。此外ImageOverlay还实现了_get_self_bounds方法folium/raster_layers.py返回规范化后的自身边界。这一点与VideoOverlay相同可配合地图的 fitBounds 类功能使用。测试用例 tests/test_raster_layers.py 中test_image_overlay对上述行为做了明确验证传入一个 2×3×4 的 RGBA 数组并设置mercator_projectTrue断言io.url精确等于一段固定的data:image/png;base64,...字符串并验证了m.get_bounds()返回[[0, -180], [90, 180]]——说明 bounds 被完整传递、数组被稳定地编码成 PNG可作为自行扩展时对照的标准输出。常见问题与最佳实践数组上下颠倒检查origin是否与你的数据生成方式匹配。数据第一行是最低纬度时用originlower是第一行最高纬度时用originupper。高纬线条偏移只要数组数据是按“等经纬度间隔”计算的就必须设置mercator_projectTrue否则仅适合加载已经是墨卡托投影的成品图片如官方指南中的 Mercator projection 示例图。本地图片失效本地路径图片以 Base64 内嵌生成的 HTML 是自包含的URL 图片不内嵌离线环境会加载失败按需二选一。控制 HTML 体积数组分辨率越高、图片越大Base64 体积膨胀越明显约增 33%大型数据优先考虑 URL 或先压缩再嵌入。图层管理给每个ImageOverlay设置有意义的name并搭配folium.LayerControl()方便用户在地图上切换显示。以上用法均可在本仓库的官方指南 docs/user_guide/raster_layers/image_overlay.md 中找到原始示例并结合 folium/raster_layers.py 与 folium/utilities.py 的源码深入理解。赞分享数据可视化数据分析GIS【免费下载链接】foliumPython Data. Leaflet.js Maps.项目地址https://gitcode.com/gh_mirrors/fo/folium点击查看免费下载相关推荐Leaflet ImageOverlay 图像叠加层实战指南在指定地理边界上叠加任意图片Leaflet ImageOverlay 图像叠加层实战指南在指定地理边界上叠加任意图片 导读 本文以 Leaflet 官方教程的 ImageOverlay前端数据可视化GISfolium FloatImage 插件指南在地图 HTML 画布上叠加浮动图片folium FloatImage 插件指南在地图 HTML 画布上叠加浮动图片 导读 FloatImage 是 folium 内置插件之一用于在 Leaf数据可视化数据分析GISflet-map 地图叠加图片图层 OverlayImageLayer 完整使用指南在 Flet 地图上叠加 OverlayImage 与 RotatedOverlayImageflet map 地图叠加图片图层 OverlayImageLayer 完整使用指南在 Flet 地图上叠加 OverlayImage 与 RotatedOv前端跨平台桌面应用移动开发上一篇Chatterbox TTS重新定义开源语音合成赋能开发者与创作者的即时语音引擎下一篇自然变换与类型转换mostly-adequate-guide高级主题解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表