使用 WMS 与 TMS 服务

WMS是web map service的缩写,是专业的GIS软件发布地图的一种流行方式(非GIS人员很少使用)。

TMS代表tiled map service瓦片地图服务)。

Leaflet的WMS

当有人发布WMS服务时,最有可能的就是链接到GetCapabilities文档。 在本教程中,我们将使用来自GeoServer的演示地图服务,网址是https://demo.boundlessgeo.com/geoserver/web/。 我们将使用GeoServer的演示地图服务,在https://demo.boundlessgeo.com/geoserver/web/。 正如您在该页面中看到的,“WMS”链接到以下URL:

https://demo.boundlessgeo.com/geoserver/ows?service=wms&version=1.3.0&request=GetCapabilities

Leaflet不能解析WMS的GetCapabilities文档。所以,您必须创建一个 L.TileLayer.WMS图层,该图层用来提供基本的WMS链接,并指定所需的任何WMS选项。

基本的WMS链接仅仅是没有任何参数的GetCapabilities链接,例如:

https://demo.boundlessgeo.com/geoserver/ows?

在Leaflet的地图中使用这个的方法很简单:

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

var wmsLayer = L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', wmsOptions).addTo(map);

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

WMS服务器会在GetCapabilities的XML文档中定义一组层,但是该文档大多冗长难懂,所以通常使用诸如QGIS之类的软件来查看WMS服务器中的可用图层的信息:

Discovering WMS layers with QGIS

我们可以看到,OpenGeo用一个带有基础地图的名为ne:ne的WMS图层来演示WMS。让我们看看它的样子:


var wmsLayer = L.tileLayer.wms('http://webgis.osgeo.cn/cgi-bin/mapserv?map=/oswebgis/xmfb3.map&', {
        layers: 'states',
        format: 'image/png',
        transparent: true,
    }).addTo(map);
注意上面使用的 Mapfile , 需要定义输出投影为 EPSG:3857
还有一点要注意,如果没有正确配置好 Mapfile,有可能会出现 MapServer 地图(缺省情况下的完整地图)作为切片形成覆盖的情况。
查看本实例

或者我们可以试试nasa:bluemarble的WMS图层:

var wmsLayer = L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', {
    layers: 'nasa:bluemarble'
}).addTo(map);
查看本实例

layers选项是用用逗号分隔的层列表。如果WMS服务定义了多个层,那么地图就可以同时引入多个层创建图像。

比如在我们正使用的这个WMS服务器上,有一个 ne:ne_10m_admin_0_countries图层显示国家陆地和国家名称, 还有一个ne:ne_10m_admin_0_boundary_lines_land层显示国家边界。 如果我们同时请求两个图层,WMS服务器将把这两个图层合成一个图像,并且用逗号将它们隔开:

var countriesAndBoundaries = L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', {
    layers: 'ne:ne_10m_admin_0_countries,ne:ne_10m_admin_0_boundary_lines_land'
}).addTo(map);

注意,这将向WMS服务器请求一个图像,它不同于为国家和国家边界创建的L.TileLayer.WMS,它会把这两个图层都添加到地图中。在第一种情况下,会发出一个图像请求,然后由WMS服务器决定如何组合图像。在第二种情况下,会发出两个图像请求,然后由网页浏览器中运行的Leaflet代码决定如何组合图像。

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

var basemaps = {
    Countries: L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', {
        layers: 'ne:ne_10m_admin_0_countries'
    }),

    Boundaries: L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', {
        layers: 'ne:ne_10m_admin_0_boundary_lines_land'
    }),

    'Countries, then boundaries': L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', {
        layers: 'ne:ne_10m_admin_0_countries,ne:ne_10m_admin_0_boundary_lines_land'
    }),

    'Boundaries, then countries': L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', {
        layers: 'ne:ne_10m_admin_0_boundary_lines_land,ne:ne_10m_admin_0_countries'
    })
};

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

basemaps.Countries.addTo(map);

更改为“Countries, then boundaries”选项,这样您就可以看到陆地的边界线,而且WMS服务器足够聪明,可以在地图上显示建筑标签。当请求多个图层时,如何组合图层取决于WMS服务器。

查看本实例

WMS服务的GIS用户须知

从GIS的角度来看,Leaflet的WMS处理是非常基本的。它不支持GetCapabilities,不支持legend,也不支持GetFeatureInfo

我们可以在Leaflet’s API documentation文档中找到L.TileLayer.WMS的额外选项。任何选项都可以通过getImage的链接传递给WMS服务器。

还要注意,Leaflet支持的坐标系非常少:CRS:3857, CRS:3395 以及CRS:4326 (请参阅L.CRS文档)。 如果您的WMS服务无法在这些坐标系中提供图像,那么您可能需要在Leaflet中使用Proj4Leaflet创建其它的坐标系。 除此之外,在初始化你的地图时要使用正确的CRS,添加任何WMS层都要调用它:

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

var wmsLayer = L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', {
    layers: 'nasa:bluemarble'
}).addTo(map);
查看本实例

Leaflet的TMS

虽然Leaflet没有明确支持TMS服务,但是tile的命名规则与L.TileLayer的命名规则非常相似,所以TMS服务在此不作赘述。

使用相同的OpenGeo WMS/TMS服务器演示,我们可以看到一个TMS端点:

https://demo.boundlessgeo.com/geoserver/gwc/service/tms/1.0.0

检查MapCache help about TMSTMS specification ,您可以看到TMS中的地图瓦片的链接如下:

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

将OpenGeo的TMS服务当作L.TileLayer使用,我们可以检查功能文档,查看有哪些tileset可用,并且构建我们的基本链接:

https://demo.boundlessgeo.com/geoserver/gwc/service/tms/1.0.0/ne:ne@EPSG:900913@png/{z}/{x}/{y}.png

https://demo.boundlessgeo.com/geoserver/gwc/service/tms/1.0.0/nasa:bluemarble@EPSG:900913@jpg/{z}/{x}/{y}.jpg

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

var tms_ne = L.tileLayer('https://demo.boundlessgeo.com/geoserver/gwc/service/tms/1.0.0/ne:ne@EPSG:900913@png/{z}/{x}/{y}.png', {
    tms: true
}).addTo(map);

var tms_bluemarble = L.tileLayer('https://demo.boundlessgeo.com/geoserver/gwc/service/tms/1.0.0/nasa:bluemarble@EPSG:900913@jpg/{z}/{x}/{y}.jpg', {
    tms: true
});
查看本实例

Leaflet 1.0的一个新特性是能够在链接中使用{-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的方式提供精准的服务。