OpenLayers教程:多源数据加载之WMTS

目录

一、WMTS简介

二、WMTS的接口

2.1、GetCapabilities

2.2、GetTile

2.3、GetFeatureInfo

三、加载ArcGIS产品发布的WMTS服务数据

3.1、加载ArcGIS Online发布的WMTS服务数据 

3.2、加载ArcGIS Server发布的WMTS服务数据

四、加载GeoServer发布的WMTS服务数据

五、加载天地图的WMTS服务数据

六、总结


一、WMTS简介

    WMTS,即Web地图瓦片服务(Web Map Tile Service),由OGC(开放地理信息联盟)制定。根据WMTS标准,可以使我们轻松的访问瓦片数据。

    WMTS提供了一种采用预定义图块方法发布数字地图服务的标准化解决方案,它最重要的特征是采用瓦片缓存技术缓解WebGIS服务器端数据处理的压力,提高前后端交互响应速度。

    WMS(Web地图服务)提供可定制地图的服务,是一个动态数据或用户定制地图(需结合SLD-Style Layer Descriptor)的理想解决方法。例如,可以在GeoServer中通过修改SLD样式文件来随时自定义地图样式:

    随时都可以修改,而且一修改在客户端就能实时渲染出变化。根本原因是WMS的地图数据并没有通过切片放置到硬盘中,它的地图数据是实时处理并传输到客户端的。

    而WMTS标准需要地图数据切片后放置在硬盘中,然后再调用数据传输到客户端。

    WMTS牺牲了提供定制地图的灵活性,代之以通过提供静态数据(瓦片地图)来增强伸缩性,这些静态数据的范围框和比例尺被限定在瓦片坐标系中。这些固定的瓦片地图数据集使得对WMTS服务的实现可以使用一个仅简单返回已有文件的Web服务器即可,同时使得可以利用一些标准诸如分布式缓存的网络机制实现伸缩性。

二、WMTS的接口

    WMTS服务支持RESTful访问,其接口包括:

  • GetCapabilities    ——    获取服务元数据,元数据描述该服务的功能和包含的信息
  • GetTile    ——    获取地图瓦片
  • GetFeatureInfo    ——    通过在WMTS图层上指定一定的条件,返回指定的地图瓦片内容对应的要素信息

2.1、GetCapabilities

    GetCapabilities操作的参数:

    

    示例:

        ArcGIS Online发布的美国地图WMTS服务的基地址是:

             http://services.arcgisonline.com/arcgis/rest/services/Demographics/USA_Population_Density/MapServer/WMTS/

        那么要查询它的元数据,就可以使用以下URL:

             http://services.arcgisonline.com/arcgis/rest/services/Demographics/USA_Population_Density/MapServer/WMTS/?Service=GetCapabilities

       查询结果如下所示(节选):

2.2、GetTile

    GetTile的参数:

    示例:

        要查询以上ArcGIS Online发布的美国地图WMTS服务的层级为4,列号为3,行号为5的一块瓦片,可以这样请求:

        http://services.arcgisonline.com/arcgis/rest/services/Demographics/USA_Population_Density/MapServer/WMTS/?tilematrixset=EPSG%3A3857&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image%2Fpng&TileMatrix=4&TileCol=3&TileRow=5

        请求结果:

            

2.3、GetFeatureInfo

    GetFeatureInfo的参数:

    查询要素信息一般使用OGC的WFS(Web Feature Service),所以就不详细介绍WMTS的GetFeatureInfo这个接口了

三、加载ArcGIS产品发布的WMTS服务数据

3.1、加载ArcGIS Online发布的WMTS服务数据 

    ArcGIS Online中的美国地图的WMTS服务基地址为:

    http://services.arcgisonline.com/arcgis/rest/services/Demographics/USA_Population_Density/MapServer/WMTS/

    可以使用OpenLayers中的ol.layer.Tile类 + ol.source.WMTS类来加载WMTS服务数据。

    效果:

    代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>加载ArcGIS Online发布的WMTS服务数据</title>
    <link rel="stylesheet" href="../../v5.3.0/css/ol.css" />
    <script src="../../v5.3.0/build/ol.js"></script>
</head>
<body>
    <div id="map"></div>

    <script>
        // 首先设置好WMTS瓦片地图的投影坐标系
        let projection = ol.proj.get('EPSG:3857');          // 获取web墨卡托投影坐标系
        let projectionExtent = projection.getExtent();      // web墨卡托投影坐标系的四至
        let width = ol.extent.getWidth(projectionExtent);   // web墨卡托投影坐标系的水平宽度,单位米
        let resolutions = [];                               // 瓦片分辨率
        let matrixIds = [];
        for(let z = 0; z < 14; z++){
            resolutions[z] = width / (256 * Math.pow(2, z)); 
            matrixIds[z] = z;
        }
        let wmtsTileGrid = new ol.tilegrid.WMTS({
            origin: ol.extent.getTopLeft(projectionExtent), // 原点(左上角)
            resolutions: resolutions,                       // 分辨率数组
            matrixIds: matrixIds                            // 矩阵ID,就是瓦片坐标系z维度各个层级的标识
        }); 
        
        // WMTS数据源与地图
        let wmtsSource = new ol.source.WMTS({
            url: "http://services.arcgisonline.com/arcgis/rest/services/" +
                        "Demographics/USA_Population_Density/MapServer/WMTS/",
            matrixSet: 'EPSG:3857',             // 投影坐标系参数矩阵集
            format: 'image/png',                // 图片格式
            projection: projection,             // 投影坐标系
            // 投影坐标系
            tileGrid: wmtsTileGrid
        });
        let wmtsLayer = new ol.layer.Tile({
            source: wmtsSource
        });

        let map = new ol.Map({
            target: 'map',
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.Stamen({
                        layer: 'terrain'
                    })
                }),
                wmtsLayer
            ],
            view: new ol.View({
                center: [0, 0],
                zoom: 3
            })
        });
    </script>
</body>
</html>

    可以发现并不是那么容易,需要我们自己定义瓦片坐标系,也就是自定义初始化ol.tilegrid.WMTS类。

    关键的地方就是生成分辨率resolutions,即首先得到Web墨卡托投影坐标系的宽度值(单位米),然后除以瓦片坐标系对应层级的瓦片总宽度就得到对应层级的分辨率了。前面的文章也都讲过相关的原理。

3.2、加载ArcGIS Server发布的WMTS服务数据

    我这里使用ArcGIS Server发布了广东省路网shp数据,其WMTS基地址为:

        https://localhost:6443/arcgis/rest/services/gd_roads/MapServer/WMTS

    效果:

    代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>加载ArcGIS Server发布的WMTS服务数据</title>
    <link rel="stylesheet" href="../../v5.3.0/css/ol.css" />
    <script src="../../v5.3.0/build/ol.js"></script>
</head>
<body>
    <div id="map"></div>

    <script>
        // 首先设置好WMTS瓦片地图的投影坐标系
        let projection = ol.proj.get('EPSG:3857');          // 获取web墨卡托投影坐标系
        let projectionExtent = projection.getExtent();      // web墨卡托投影坐标系的四至
        let width = ol.extent.getWidth(projectionExtent);   // web墨卡托投影坐标系的水平宽度,单位米
        let resolutions = [];                               // 瓦片分辨率
        let matrixIds = [];
        for(let z = 0; z < 14; z++){
            resolutions[z] = width / (256 * Math.pow(2, z)); 
            matrixIds[z] = z;
        }
        let wmtsTileGrid = new ol.tilegrid.WMTS({
            origin: ol.extent.getTopLeft(projectionExtent), // 原点(左上角)
            resolutions: resolutions,                       // 分辨率数组
            matrixIds: matrixIds                            // 矩阵ID,就是瓦片坐标系z维度各个层级的标识
        }); 
        
        // WMTS数据源与地图
        let wmtsSource = new ol.source.WMTS({
            url: "https://localhost:6443/arcgis/rest/services/gd_roads/MapServer/WMTS",
            layer: 'gd_roads',                  // 图层名
            version: '1.0.0',                   // WMTS版本
            // 投影坐标系矩阵集,一定要和WMTS capabilities文档中一致,否则会加载失败
            matrixSet: 'default028mm',          
            format: 'image/png',                // 图片格式
            projection: projection,             // 投影坐标系
            requestEncoding: 'KVP',             // 请求的编码方式,默认就是'KVP'   
            // 在WMTS capabilities文档中对应的样式名,一定要写,否则会加载失败  
            style: 'default',                   
            tileGrid: wmtsTileGrid              // 投影坐标系
        });
        let wmtsLayer = new ol.layer.Tile({
            source: wmtsSource
        });

        let map = new ol.Map({
            target: 'map',
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.Stamen({
                        layer: 'terrain'
                    })
                }),
                wmtsLayer
            ],
            view: new ol.View({
                center: [0, 0],
                zoom: 3
            })
        });
    </script>
</body>
</html>

    一个经验之谈就是:如果加载失败,请先检查参数是否与WMTS GetCapabilities文档里的参数一致,一定要严格一致!

四、加载GeoServer发布的WMTS服务数据

    GeoServer同样也支持WMTS标准,使用OpenLayers同样也能加载GeoServer发布的WMTS服务数据。

    我这里使用GeoServer发布了广东省路网shp数据,其WMTS基地址为:

        http://localhost:8080/geoserver/gwc/service/wmts

    效果:

    代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>加载GeoServer发布的WMTS服务数据</title>
    <link rel="stylesheet" href="../../v5.3.0/css/ol.css" />
    <script src="../../v5.3.0/build/ol.js"></script>
</head>
<body>
    <div id="map"></div>

    <script>
        // 首先设置好WMTS瓦片地图的投影坐标系
        let projection = ol.proj.get('EPSG:900913');          // 获取web墨卡托投影坐标系
        let projectionExtent = projection.getExtent();      // web墨卡托投影坐标系的四至
        let width = ol.extent.getWidth(projectionExtent);   // web墨卡托投影坐标系的水平宽度,单位米
        let resolutions = [];                               // 瓦片分辨率
        let matrixIds = [];
        for(let z = 0; z < 10; z++){
            resolutions[z] = width / (256 * Math.pow(2, z)); 
            matrixIds[z] = "EPSG:900913:" + z;              // 注意这里的matrixId的格式为EPSG:900913:z
        }
        let wmtsTileGrid = new ol.tilegrid.WMTS({
            origin: ol.extent.getTopLeft(projectionExtent), // 原点(左上角)
            resolutions: resolutions,                       // 分辨率数组
            matrixIds: matrixIds                            // 矩阵ID,就是瓦片坐标系z维度各个层级的标识
        }); 
        
        // WMTS数据源与地图
        let wmtsSource = new ol.source.WMTS({
            url: "http://localhost:8080/geoserver/gwc/service/wmts",
            layer: "guangdong:gd_roads",        // 对应的图层
            matrixSet: 'EPSG:900913',           // 投影坐标系参数矩阵集
            format: 'image/png',                // 图片格式
            projection: projection,             // 投影坐标系
            // 投影坐标系
            tileGrid: wmtsTileGrid
        });
        let wmtsLayer = new ol.layer.Tile({
            source: wmtsSource
        });

        let map = new ol.Map({
            target: 'map',
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.Stamen({
                        layer: 'terrain'
                    })
                }),
                wmtsLayer
            ],
            view: new ol.View({
                center: [0, 0],
                zoom: 3
            })
        });
    </script>
</body>
</html>

    这里需要注意的是matrixId的格式为EPSG:900913:z,而不再是和上面一样单纯的数字了。

五、加载天地图的WMTS服务数据

    天地图的大部分地理数据都是依据WMTS规范发布:

    

    现在来加载天地图发布的影像底图:

    效果:

    源代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>加载天地图发布的WMTS影像服务数据</title>
    <link rel="stylesheet" href="../../v5.3.0/css/ol.css" />
    <script src="../../v5.3.0/build/ol.js"></script>
</head>
<body>
    <div id="map"></div>

    <script>
        // 首先设置好WMTS瓦片地图的投影坐标系
        let projection = ol.proj.get('EPSG:900913');          // 获取web墨卡托投影坐标系
        let projectionExtent = projection.getExtent();      // web墨卡托投影坐标系的四至
        let width = ol.extent.getWidth(projectionExtent);   // web墨卡托投影坐标系的水平宽度,单位米
        let resolutions = [];                               // 瓦片分辨率
        let matrixIds = [];
        for(let z = 1; z < 18; z++){
            resolutions[z] = width / (256 * Math.pow(2, z)); 
            matrixIds[z] = z;
        }
        let wmtsTileGrid = new ol.tilegrid.WMTS({
            origin: ol.extent.getTopLeft(projectionExtent), // 原点(左上角)
            resolutions: resolutions,                       // 分辨率数组
            matrixIds: matrixIds                            // 矩阵ID,就是瓦片坐标系z维度各个层级的标识
        }); 
        
        // WMTS数据源与地图
        let wmtsSource = new ol.source.WMTS({
            url: "http://t0.tianditu.gov.cn/img_w/wmts?tk=你的天地图key",  // 天地图key去官网很容易申请
            layer: 'img',                  // 图层名
            version: '1.0.0',                   // WMTS版本
            // 投影坐标系矩阵集,一定要和WMTS capabilities文档中一致,否则会加载失败
            matrixSet: 'w',          
            format: 'tiles',                // 图片格式
            projection: projection,             // 投影坐标系
            requestEncoding: 'KVP',             // 请求的编码方式,默认就是'KVP'   
            // 在WMTS capabilities文档中对应的样式名,一定要写,否则会加载失败  
            style: 'default',                   
            tileGrid: wmtsTileGrid              // 投影坐标系
        });
        let wmtsLayer = new ol.layer.Tile({
            source: wmtsSource
        });

        let map = new ol.Map({
            target: 'map',
            layers: [
                wmtsLayer
            ],
            view: new ol.View({
                center: [0, 0],
                zoom: 1
            })
        });
    </script>
</body>
</html>

    以后开发就可以基于WMTS规范来加载天地图的各种底图了,非常方便!

六、总结

    其实掌握加载WMTS服务数据非常简单,就是首先要基于WMTS服务的基地址查询对应的元数据,然后根据元数据文档里写的参数去请求瓦片数据就好了。

    关键就是参数要正确!

  • 9
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenLayers是一种用于在网页上展示地理空间数据的开源JavaScript库。当使用OpenLayers加载WMTS(Web Map Tile Service)元数据时,可能会遇到加载速度慢且出现空白的情况。 这种现象可能是由于几个原因导致的。首先,WMTS服务本身可能存在响应速度较慢的问题。这可能是由于服务端处理请求需要时间,或者服务器的带宽限制导致数据传输速度变慢。 其次,网络连接问题也可能影响加载速度。如果网络连接较差或不稳定,数据传输过程中可能会出现延迟和错误,导致加载速度变慢甚至加载失败。 另外,加载大量地图数据也可能导致加载速度变慢。如果WMTS服务返回的元数据包含大量图块数据,而浏览器或设备的处理能力有限,就可能导致加载速度下降并出现空白。 针对这些问题,我们可以采取一些解决方法来提高加载速度和避免空白出现。首先,我们可以尝试优化WMTS服务端的响应速度。这可以包括调整服务器配置、增加带宽、优化服务端代码等。 其次,我们可以通过改善网络连接来提高加载速度。这包括连接到更稳定的网络、使用更快的网络连接等。 另外,我们还可以通过优化OpenLayers的配置来提高加载速度。例如,可以调整地图缩放级别、裁剪地图视图范围以减少加载数据量。还可以使用OpenLayers提供的异步加载机制,在加载数据时显示加载动画或进度条,以提高用户体验。 总之,通过综合考虑WMTS服务端、网络连接和OpenLayers配置等因素,我们可以尝试解决由于加载数据速度慢和空白问题所带来的困扰。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值