Leaflet

一个开源的 JavaScript 库
用于移动友好的交互式地图

← 教程


WMS,代表 网络地图服务,是专业 GIS 软件发布地图的一种流行方式(非 GIS 用户很少使用)。这种格式类似于地图切片,但更通用,并且没有针对网络地图进行很好的优化。WMS 图像由其角的坐标定义 - Leaflet 在后台进行的计算。

TMS 代表 切片地图服务,是一种地图切片标准,更侧重于网络地图,非常类似于 Leaflet 在 L.TileLayer 中期望的地图切片。

WMTS,代表 网络地图切片服务,是地图切片的标准协议,直接提供可在 L.TileLayer 中使用的地图切片。

Leaflet 中的 WMS

当有人发布 WMS 服务时,他们很可能链接到一个名为 GetCapabilities 的文档。在本教程中,我们将使用 Mundialis 在 http://ows.mundialis.de/services/service? 提供的 WMS。服务功能在以下 URL 中描述

http://ows.mundialis.de/services/service?request=GetCapabilities

Leaflet 不理解 WMS GetCapabilities 文档。相反,您必须创建一个 L.TileLayer.WMS 图层,提供基础 WMS URL,并指定您需要的任何 WMS 选项。

基础 WMS URL 只是 GetCapabilities URL,没有任何参数,如下所示

http://ows.mundialis.de/services/service?

在 Leaflet 地图中使用它的方法很简单

var map = L.map(mapDiv, mapOptions);

var wmsLayer = L.tileLayer.wms('http://ows.mundialis.de/services/service?', wmsOptions).addTo(map);

L.TileLayer.WMS 的实例至少需要一个选项:layers。请注意,Leaflet 中的“图层”概念与 WMS 中的“图层”概念不同!

WMS 服务器在服务中定义了一组图层。这些在 GetCapabilities XML 文档中定义,大多数情况下很繁琐且难以理解。通常使用 QGIS 等软件查看 WMS 服务器中有哪些可用图层 来查看可用的图层名称

Discovering WMS layers with QGIS

我们可以看到Mundialis WMS 有一个名为 TOPO-OSM-WMS 的 WMS 图层,其中包含底图。让我们看看它是什么样子的

var wmsLayer = L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
	layers: 'TOPO-OSM-WMS'
}).addTo(map);
请查看此独立示例。

或者我们可以尝试 SRTM30-Colored-Hillshade WMS 图层

var wmsLayer = L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
	layers: 'SRTM30-Colored-Hillshade'
}).addTo(map);
请查看此独立示例。

layers 选项是图层名称的逗号分隔列表。如果 WMS 服务定义了多个图层,则地图图像请求可以引用多个图层。

对于我们正在使用的示例 WMS 服务器,有一个 TOPO-WMS WMS 图层显示世界地形,还有一个 OSM-Overlay-WMS WMS 图层显示地名。如果我们请求这两个图层(用逗号隔开),WMS 服务器将在一个图像中组合这两个图层。

var topographyAndPlaces = L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
	layers: 'TOPO-WMS,OSM-Overlay-WMS'
}).addTo(map);

请注意,这将向 WMS 服务器发出一个图像请求。这与为地形创建 L.TileLayer.WMS,为地名创建另一个,并将它们都添加到地图中不同。在第一种情况下,只有一个图像请求,并且由 WMS 服务器决定如何组合(相互叠加)图像。在第二种情况下,将会有两个图像请求,并且由在 Web 浏览器中运行的 Leaflet 代码决定如何组合它们。

如果将此与 图层控件 相结合,那么我们可以构建一个简单的地图来查看差异

var basemaps = {
	Topography: L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
		layers: 'TOPO-WMS'
	}),

	Places: L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
		layers: 'OSM-Overlay-WMS'
	}),

	'Topography, then places': L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
		layers: 'TOPO-WMS,OSM-Overlay-WMS'
	}),

	'Places, then topography': L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
		layers: 'OSM-Overlay-WMS,TOPO-WMS'
	})
};

L.control.layers(basemaps).addTo(map);

basemaps.Topography.addTo(map);

切换到“地形,然后是地名”选项,这样您就可以看到地名“叠加”在地形之上,但 WMS 服务器足够智能,可以将建筑物标签显示在上面。WMS 服务器会根据请求的多个图层来决定如何组合它们。

请查看此独立示例。

面向 WMS 服务的 GIS 用户的说明

从 GIS 的角度来看,Leaflet 中的 WMS 处理非常基础。没有 GetCapabilities 支持、没有图例支持,也没有 GetFeatureInfo 支持。

L.TileLayer.WMS 具有额外的选项,可以在 Leaflet 的 API 文档 中找到。那里没有描述的任何选项都将传递给 getImage URL 中的 WMS 服务器。

另外请注意,Leaflet 支持很少的 坐标系CRS:3857CRS:3395CRS:4326(请参阅 L.CRS 的文档)。如果您的 WMS 服务没有在这些坐标系中提供图像,您可能需要使用 Proj4Leaflet 来在 Leaflet 中使用其他坐标系。除此之外,只需在初始化地图时使用正确的 CRS,添加的任何 WMS 图层都将使用它。

var map = L.map('map', {
	crs: L.CRS.EPSG4326
});

var wmsLayer = L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
	layers: 'TOPO-OSM-WMS'
}).addTo(map);
请查看此独立示例。

Leaflet 中的 TMS

Leaflet 没有对 TMS 服务的显式支持,但切片命名结构与常见的 L.TileLayer 命名方案非常相似,因此显示 TMS 服务几乎是微不足道的。

让我们考虑一个具有以下端点的 TMS 服务器

http://base_url/tms/1.0.0

检查 MapCache 有关 TMS 的帮助TMS 规范,您可以看到 TMS 中地图切片的 URL 看起来像这样

http://base_url/tms/1.0.0/ {tileset} / {z} / {x} / {y} .png

为了将 TMS 服务用作 L.TileLayer,我们可以检查功能文档(与基础端点相同,在本例中为 http://base_url/tms/1.0.0)以查看有哪些 tileset 可用,并构建我们的基础 URL

http://base_url/tms/1.0.0/{example_layer}@png/{z}/{x}/{y}.png

并在实例化图层时使用 tms:true 选项,如下所示

var tms_example = L.tileLayer('http://base_url/tms/1.0.0/example_layer@png/{z}/{x}/{y}.png', {
	tms: true
}).addTo(map);

Leaflet 1.0 中的一项新功能是能够在 URL 中使用 {-y} 而不是 tms: true 选项,例如

var layer = L.tileLayer('http://base_url/tms/1.0.0/tileset/{z}/{x}/{-y}.png');

tms: true 选项(在 Leaflet 0.7 中)或 {-y}(在 Leaflet 1.0 中)是必需的,因为普通 L.TileLayer 的坐标原点是左上角,因此 Y 坐标向下。在 TMS 中,坐标原点是底部左上角,因此 Y 坐标向上。

除了 y 坐标的差异和切片集的发现之外,TMS 服务以 L.TileLayer 期望的方式提供切片。