- 数据可视化
- 数据分析
- GIS
【免费下载链接】folium
Python Data. Leaflet.js Maps.
导读:WMS(Web Map Service,Web 地图服务)是地理信息系统领域广泛采用的 OGC 标准接口,通过 HTTP 请求动态返回地图图像。本文将围绕 folium 的
WmsTileLayer类,讲解如何把 WMS 服务无缝叠加到 Leaflet 地图上:包括类的完整参数体系、真实的气象雷达 WMS 接入示例、透明叠加与图层控制器的配合方式,以及从源码层面剖析其底层实现机制(URL 拼接、参数驼峰化、cql_filter特例处理等)。读完本文,你将能在 folium 中熟练接入任意符合 WMS 规范的服务器,并完成多图层叠加与交互控制。
什么是 WmsTileLayer
folium.WmsTileLayer是 folium 栅格图层家族(folium/raster_layers.py)中的一员,与TileLayer(普通瓦片层)、ImageOverlay(图片叠加层)、VideoOverlay(视频叠加层)并列。它的定位是:
Creates a Web Map Service (WMS) layer.
WMS 服务与普通的 XYZ 瓦片服务不同:瓦片服务按固定的{z}/{x}/{y}网格提供静态切片;而 WMS 服务则由客户端发送GetMap请求,携带图层名、样式、坐标范围、输出格式等参数,服务端实时渲染并返回地图图像。folium 通过WmsTileLayer把这类服务包装为 Leaflet 的L.tileLayer.wms图层,可以直接叠加在任意地图之上。
快速上手:接入气象雷达 WMS 数据
docs/user_guide/raster_layers/wms_tile_layer.md中给出了一个可直接运行的完整示例:接入美国爱荷华州立大学(IEM)提供的 Nexrad 气象雷达 WMS 服务,并叠加到 CartoDB Positron 底图上:
import folium m = folium.Map(location=[41, -70], zoom_start=5, tiles="cartodb positron") folium.WmsTileLayer( url="https://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi", name="test", fmt="image/png", layers="nexrad-n0r-900913", attr=u"Weather data © 2012 IEM Nexrad", transparent=True, overlay=True, control=True, ).add_to(m) folium.LayerControl().add_to(m) m这段代码做了四件事,代表了 WMS 接入的核心套路:
- 创建底图:
folium.Map(location=[41, -70], zoom_start=5, tiles="cartodb positron")指定了初始中心(美国东海岸附近)与缩放级别,底图使用 CartoDB Positron 浅色瓦片,便于凸显半透明的雷达图层。 - 配置 WMS 图层:
WmsTileLayer指向 IEM 的 Nexrad 雷达服务,输出image/png格式并开启透明通道,图层名为nexrad-n0r-900913。 - 注册到地图:
.add_to(m)将图层挂载到地图对象上。 - 添加图层控制器:
folium.LayerControl().add_to(m)让用户在网页上自由开关该 WMS 图层。
在 Notebook 环境中,最后一行m会直接渲染出交互式地图。该示例同样可以在 examples/WMS_and_WMTS.ipynb 中找到对应版本。
WmsTileLayer 参数体系详解
WmsTileLayer的完整签名定义在 folium/raster_layers.py 中,与docs/user_guide/raster_layers/wms_tile_layer.md示例中出现的参数一一对应。下面逐个说明其含义、默认值与典型用法:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
url | str | 必填 | WMS 服务器的GetMap服务端点地址。 |
layers | str | 必填 | 要显示的 WMS 图层名,多个图层用逗号分隔(Comma-separated list of WMS layers to show)。 |
styles | str | "" | 逗号分隔的 WMS 样式列表;留空则使用服务端默认样式。 |
fmt | str | "image/jpeg" | 服务输出图片格式,例如image/png。该参数会被映射为 WMS 请求中的format参数。 |
transparent | bool | False | 图层是否允许透明。叠加在底图上显示时通常设为True。 |
version | str | "1.1.1" | 使用的 WMS 服务版本号。 |
attr | str | "" | 图层归属说明(attribution),显示在地图右下角。 |
name | str | None | 图层名称,显示在LayerControl中。 |
overlay | bool | True | True表示作为覆盖层(overlay)叠加在底图之上;False则作为底图(base layer)。 |
control | bool | True | 是否把该图层纳入LayerControl,便于用户勾选开关。 |
show | bool | True | 地图打开时该图层是否默认显示。 |
**kwargs | — | — | 额外关键字参数,会透传给 Leaflet 的tileLayer.wms对象,既可作为瓦片层选项,也可作为 WMS 请求中的附加参数(例如时间维度参数)。 |
关于attr参数的一个实现细节
与TileLayer不同(自定义瓦片 URL 强制要求attr,否则抛出ValueError,见 folium/raster_layers.py),WmsTileLayer的attr默认值为空字符串"",即 WMS 图层不强制要求归属说明。不过从规范性与版权角度,建议仍传入明确的归属信息。
源码级原理:WmsTileLayer 是如何工作的
继承与图层语义
WmsTileLayer直接继承自folium.map.Layer(folium/map.py),Layer是 folium 中一切可被LayerControl管理的图层的抽象基类,其构造函数接收并存储四个核心字段:
name:图层在控件中显示的名称;overlay:是否为覆盖层(默认False,但WmsTileLayer显式改为True);control:是否纳入图层控件;show:是否默认显示。
此外Layer.render()会依据show的值决定是否生成addTo调用,从而实现"默认显示/默认隐藏"的语义(folium/map.py)。
模板与 JS 渲染
WmsTileLayer定义了一个 Jinja 模板作为其渲染蓝图(folium/raster_layers.py):
{% macro script(this, kwargs) %} var {{ this.get_name() }} = L.tileLayer.wms( {{ this.url|tojson }}, {{ this.options|tojson }} ); {% endmacro %}当图层被添加到地图并渲染时,folium 会把url与序列化后的options字典填入模板,生成 Leaflet 的L.tileLayer.wms(url, options)调用。也就是说,folium 的WmsTileLayer本质上是 Python 侧的声明式封装,真正的渲染与请求逻辑由 Leaflet 的tileLayer.wms完成。
参数处理流程
构造函数中的核心逻辑(folium/raster_layers.py)如下:
super().__init__(name=name, overlay=overlay, control=control, show=show) self.url = url kwargs["format"] = fmt cql_filter = kwargs.pop("cql_filter", None) self.options = parse_options( layers=layers, styles=styles, transparent=transparent, version=version, attribution=attr, **kwargs, ) # special parameter that shouldn't be camelized if cql_filter: self.options["cql_filter"] = cql_filter其中有两个值得注意的机制:
fmt映射为format:fmt参数在进入 options 之前被改写为kwargs["format"],因此最终传给 Leaflet 的是标准的format键(WMSGetMap请求参数)。parse_options的驼峰化:parse_options(定义于 folium/utilities.py)会把 Python 风格的下划线键名转为 lowerCamelCase,其实现为:
def parse_options(**kwargs): return {camelize(key): value for key, value in kwargs.items() if value is not None}其中camelize(folium/utilities.py)将variable_name转换为variableName,同时会过滤掉值为None的键,保证传给 Leaflet 的 options 干净紧凑。
cql_filter特例:如果用户传入cql_filter(ECQL 过滤表达式,常见于 GeoServer 等 WMS 服务用于做要素级过滤),它会先被从 kwargs 中弹出,再原样放回 options——故意不做驼峰化。因为cqlFilter(驼峰化后的形式)不是 WMS 标准参数,Leaflet/GeoServer 需要的是保留下划线形式的cql_filter。
测试用例的印证
test_raster_layers.py 中的test_wms用例完整复现了上述流程,并专门验证了cql_filter特例:
def test_wms(): m = folium.Map([40, -100], zoom_start=4) url = "http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi" w = folium.raster_layers.WmsTileLayer( url=url, name="test", fmt="image/png", layers="nexrad-n0r-900913", attr="Weather data © 2012 IEM Nexrad", transparent=True, cql_filter="something", ) w.add_to(m) html = m.get_root().render() # verify this special case wasn't converted to lowerCamelCase assert '"cql_filter": "something",' in html assert "cqlFilter" not in html该测试断言渲染后的 HTML 中必须包含"cql_filter": "something"且不能出现cqlFilter,从测试层面锁定了这一特例行为,避免后续重构误伤。
进阶用法:透明叠加与图层控制
回到示例本身,几个参数组合值得单独拆解:
transparent=True:雷达图像通常是"有颜色数据、无数据区域透明"的 PNG,开启透明后雷达回波才能叠加在地图上显示,而非以不透明矩形遮挡底图。overlay=True:声明该图层是覆盖层。folium 的Layer基类会据此把图层归入 LayerControl 的"Overlays"分组(folium/map.py中LayerControl类,folium/map.py),用户可以在"Overlays"分组中独立开关它,而底图分组(Base Layers)不受影响。control=True:确保该图层出现在 LayerControl 中。如果设为False,图层仍会渲染,但用户无法在界面上控制其显隐。name="test":该名称会显示在图层控件的 Overlays 列表中,实际使用时应改为可读性更强的名称,例如"NEXRAD Radar"。
这种"底图 + 多个透明 WMS 覆盖层 + LayerControl"的组合,是气象、海洋、国土等行业最常见的叠加分析范式:底图负责地理上下文,WMS 图层负责动态专题数据,用户按需开关。
与其他栅格图层的协同
WmsTileLayer与同类栅格图层共享Layer基类语义(overlay/control/show/name四个行为参数完全一致),因此可以和其他图层自由叠加:
TileLayer:普通 XYZ 瓦片底图,对应 folium/raster_layers.py;ImageOverlay:将单张图片按指定地理范围贴图(folium/raster_layers.py);VideoOverlay:在地图上播放视频(folium/raster_layers.py)。
例如可以在一张底图上同时叠加一个 WMS 遥感影像图层与一个ImageOverlay标注图层,再由LayerControl统一管理显隐——这正体现了 folium 栅格图层体系的组合能力。它们共同的**kwargs透传机制意味着你始终可以按 LeaflettileLayer.wms的文档(https://leafletjs.com/reference.html#tilelayer-wms)补充额外选项。
小结与使用建议
- 最小可用配置:
url与layers为必填,其余参数均有合理默认值,示例中额外设置的fmt、transparent、overlay、control、attr属于接入外部 WMS 时的推荐标配。 - 叠加显示三件套:叠加到已有底图上时,建议
transparent=True、overlay=True、control=True配合LayerControl使用。 - 格式选择:需要透明叠加时优先
fmt="image/png";对 JPEG 可接受的场景可使用默认的image/jpeg以减小流量。 cql_filter传参:需要 ECQL 空间/属性过滤时直接传cql_filter=...,folium 会原样透传,不会被改写成cqlFilter。- 归属说明:虽然 WMS 图层不强制
attr,但为合规与可追溯,建议填写数据来源说明。
接入 WMS 是 folium 做专业地理数据可视化的重要一环:服务端负责按需渲染,folium 负责声明式配置与 Leaflet 桥接,二者结合即可在几行代码内完成复杂专题图层的上线。
- 数据可视化
- 数据分析
- GIS
【免费下载链接】folium
Python Data. Leaflet.js Maps.
相关推荐
Leaflet 中的 WMS 图层组合实战:用 WMSTileLayer 叠加多图层并理解服务端合成
Leaflet 中的 WMS 图层组合实战:用 WMSTileLayer 叠加多图层并理解服务端合成 导读 本文基于 Leaflet 官方示例 docs/exa
前端数据可视化GISLeaflet WMS 图层接入与识别实战:从 WMSTileLayer 到增强插件 leaflet.wms
Leaflet WMS 图层接入与识别实战:从 WMSTileLayer 到增强插件 leaflet.wms Web Map Service(WMS)是 GIS
前端数据可视化GISLeaflet WMS 实战指南:使用 WMSTileLayer 加载 SRTM30-Colored-Hillshade 高程晕渲图层
Leaflet WMS 实战指南:使用 WMSTileLayer 加载 SRTM30 Colored Hillshade 高程晕渲图层 导读 :本文以仓库中 w
前端数据可视化GIS
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考