Jinuss's blog Jinuss's blog
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript高级程序设计》
    • 《Vue》
    • 《React》
    • 《Git》
    • JS设计模式总结
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

东流

前端可视化
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript高级程序设计》
    • 《Vue》
    • 《React》
    • 《Git》
    • JS设计模式总结
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 框架

  • core模块

  • dom模块

  • control

  • geometry

  • geo

  • layer

    • marker

    • tile

      • GridLayer
      • TileLayer
      • TileLayer.WMS
        • 概述
        • 源码分析
          • 源码实现
          • 源码解析
          • 初始化与配置initialize
          • 地图添加与CRS处理onAdd
          • 瓦片URL生成getTileUrl
          • 获取瓦片URLgetTileUrl
          • 设置参数setParams(params,noRedraw)
          • 使用示例
        • 总结
    • vector

    • Layer
    • LayerGroup
    • FeatureGroup
    • DivOverlay
    • Popup
    • Tooltip
    • ImageOverlay
    • SVGOverlay
    • VideoOverlay
    • GeoJSON
  • Map

  • 《Leaflet源码》笔记
  • layer
  • tile
东流
2025-04-14
目录

TileLayer.WMS

# 概述

TileLayer.WMS是TileLayer的一个子类,用于加载WMS(Web Map Service)服务提供的地图瓦片。它允许通过指定WMS服务的URL和参数来加载地图瓦片。

# 源码分析

# 源码实现

TileLayer.WMS的源码实现如下:

export var TileLayerWMS = TileLayer.extend({
  defaultWmsParams: {
    service: "WMS",
    request: "GetMap",
    layers: "", // 必填,WMS服务的图层名称
    styles: "", // 样式
    format: "image/jpeg", // 图像格式
    transparent: false, // 是否透明
    version: "1.1.1", // WMS服务版本
  },
  options: {
    crs: null, // 指定坐标系,默认使用地图的坐标系CRS
    uppercase: false, // 是否将参数名称转换为大写
  },
  initialize: function (url, options) {
    this._url = url;
    var wmsParams = extend({}, this.defaultWmsParams);
    for (var i in options) {
      if (!(i in this.options)) {
        wmsParams[i] = options[i];
      }
    }

    options = setOptions(this, options);

    var realRetina = options.detectRetina && Browser.retina ? 2 : 1;
    var tileSize = this.getTileSize();
    wmsParams.width = tileSize.x * realRetina;
    wmsParams.height = tileSize.y * realRetina;
    this._wmsParams = wmsParams;
  },
  onAdd:function(map){
    this._crs =this.options.crs || map.options.crs;
    this._wmsVersion = parseFloat(this._wmsParams.version);
    var projectionKey = this._wmsVersion >=1.3?'crs':'src';
    this.wmsParams[projectionKey] = this._crs.code;
    TileLayer.prototype.onAdd.call(this,map);
  },
  getTileUrl: function(coords){
    var tileBounds =this._tileCoordsToNwSe(coords),
        crs = this._crs,
        bounds=toBounds(crs.project(tileBounds[0]),crs.project(tileBounds[1])),
        min=bounds.min,
        max=bounds.max,
        bbox =(this._wmsVersion >=1.3 && this._crs === EPSG4326)?[min.y,min.x,max.y,max.x]:[min.x,min.y,max.x,max.y].join(','),
        url=TileLayer.prototype.getTileUrl.call(this,coords);

    return url + getParamString(this._wmsParams,url,this.options.uppercase) + (this.options.uppercase ? '&BBOX=':'$bbox=')+bbox;
  },
  setParams:function(params,noRedraw){
     extend(this.wmsParams,params);
     if(!noRedraw){
        this.redraw()
     } 
     return this;
  }
});

export function tileLayer(url,options){
    return new TileLayerWMS(url,options)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

# 源码解析

# 初始化与配置initialize

  • 保存URL:记录WMS服务的基础URL
  • 合并参数:
    • 使用extend合并defaultWmsParams和用户提供的options,得到最终的WMS参数对象
    • 遍历options,如果参数名称不在options中,则将其添加到wmsParams中
  • 设置选项:
    • 使用setOptions设置TileLayer的选项,包括crs和uppercase
    • 检测浏览器是否支持Retina显示,并根据结果设置realRetina
    • 获取瓦片的大小,并根据realRetina调整WMS参数中的width和height

# 地图添加与CRS处理onAdd

  • 保存CRS:
    • 如果用户未指定crs,则使用地图的默认坐标系map.options.crs
    • 将crs保存到_crs属性中
  • 保存WMS版本:
    • 解析WMS服务的版本号,并保存到_wmsVersion属性中
  • 设置投影参数:
    • 根据WMS版本号和坐标系,设置wmsParams中的投影参数
  • 调用父类方法:
    • 调用父类的onAdd方法,完成地图添加的初始化工作

# 瓦片URL生成getTileUrl

# 获取瓦片URLgetTileUrl

  • 计算瓦片边界:
    • 使用_tileCoordsToNwSe方法计算当前瓦片的边界
    • 将边界转换为投影坐标系
    • 计算边界的最小和最大坐标
  • 构建BBOX参数:
    • WMS 1.3+使用参数crs,旧版本使用srs
    • 根据WMS版本号和坐标系,构建BBOX参数
    • 如果WMS版本号大于等于1.3且坐标系为EPSG4326,则按照WMS标准构建BBOX参数
    • 否则,按照旧版标准构建BBOX参数
  • 构建URL:
    • 调用父类的getTileUrl方法,获取瓦片的基本URL
    • 使用getParamString方法将WMS参数添加到URL中
    • 根据uppercase选项,添加BBOX参数
  • 返回URL:
    • 返回构建好的瓦片URL

# 设置参数setParams(params,noRedraw)

  • 合并新参数:扩展wmsParams对象,支持动态修改图层、样式等
  • 重绘地图:默认触发redraw重新加载瓦片

# 使用示例

var weatherLayer = L.tileLayer.wms("http://example.com/wms", {
  layers: 'clouds,precipitation',
  styles: 'rain_style',
  format: 'image/png',
  transparent: true,
  version: '1.3.0',
  attribution: 'Weather Data © NOAA'
});
// 动态更新图层
weatherLayer.setParams({ layers: 'temperature' });
1
2
3
4
5
6
7
8
9
10

# 总结

TileLayer.WMS通过以下机制实现WMS集成:

- ​​参数管理​​:合并默认参数与用户选项,支持动态更新。 - CRS适配​​:处理不同坐标系和WMS版本差异。 - 请求构建​​:生成符合WMS规范的URL,包含BBox、图层、样式等参数。 - 扩展性​​:透传自定义参数,兼容各类WMS服务。

该设计使得Leaflet能够灵活对接标准或定制的WMS服务,适用于气象、地质等专业领域的地图可视化

编辑 (opens new window)
上次更新: 2025/05/16, 06:30:31
TileLayer
Renderer

← TileLayer Renderer→

最近更新
01
GeoJSON
05-08
02
Circle
04-15
03
CircleMarker
04-15
更多文章>
Theme by Vdoing | Copyright © 2024-2025 东流 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式