之前有文章讲述了wmts服务的优点和好处,以及一些基本的原理,这篇文章我们从实际操作中来体验一下OGC定义的wmts的标准。
首先wmts服务是由服务端和客户端两部分组成,我们绝大多数人不必关心服务端,因为有服务端地图切片能力的公司和机构毕竟是少数。
我们重点在客户端加载,但是我们必须大致了解切片的原理和过程
按照OGC 的标准,服务端首先将一张地图切割成若干副地图,注意这种切割是按照不同比例层级(分辨率)来切割的,比如1:1切成了16张,1:500切成了128张等等,当然官方标准不是按照比例尺,而是按照分辨率来切的,因为比例尺是相对的,而分辨率对于计算机来讲是绝对的。
那为什么要清楚服务端是怎么切片的呢?因为了解清楚切片原理之后我们才能明白如何去获取切片。按照上面的切片规则,我们只需要知道两个关键条件就可以把图片请求回来
1.加载切片此时地图所处的分辨率
2.切片的位置,也就是我们得知道应该请求第几副图
第一个条件此时所处的分辨率,一般是地图框架本身提供的,或者说框架本身已经帮我们计算好了,不用关心,第二个条件是需要我们告诉地图框架一些信息然后框架帮我们计算好。像一般的gis类的框架leaflet ,openlayes,cesium等都有这个能力
那么我们到底需要告诉框架什么呢?
1.基础信息
包括(1)请求图片的地址(url)总得告诉我图片去哪里请求
(2)图层名称(layer)服务端可能对多个图层都进行了切片,因此得告诉服务器是哪个图层
(3)切片图层的样式(style) 这个可以没有,可以写style=default
(4)地图切片的格式(format) 一般是img/ipeg或者img/png
(5)服务信息 ,包括 request=getTile ,version=1.1.0 service=WMTS等等基本的描述信息
2.需要计算的关键信息
(1)切片矩阵
上面讲到我们必须知道地图切片的位置,比如一幅图被切成了16张小图片,我们如何快速的找到其中某一副图?最快的办法就是给这些图片编号,像我们上学的时候一样,第几排第几列立刻就知道了是哪个学生,图片也是一样,必须给图片一个行号和列号,那给图片编号有什么规则呢?
首先第一点我们必须清楚切片起点这一概念,就是一整幅地图从那个位置开始切割呢?理论上讲你可以任意选择一个位置开始切,但是为了前后端请求图片变得规范和容易,通常有这么两个标准,第一是从地图的左上角开始且,符合逻辑和人的习惯,第二种是从地图的右下角开始切(不用管这种),那么不同的切片起点就决定了图片行号和列号的不同编排。
比如你从左上角开始切片,那么图片的行列号就是这样编排的:
好,清楚了图片的行列号和地图当时的分辨率是不是就可以请求一张图片回来了,是的,理论上是的,那实际种要怎么操作呢?
目前来讲对于前端,无论你是什么地图框架,在进行wmts服务请求的时候都会经历这么几个步骤:
1.获取wmts服务的元数据地址,(元数据就是用来描述wmts切片信息的数据,从中可以知道服务地址以及服务端的图片是怎么切的),利用getCapabilities方法获取元数据。
例:https://basemap.nationalmap.gov/arcgis/rest/services/USGSHydroCached/MapServer/WMTS/1.0.0/WMTSCapabilities.xml
2.通过元数据当中的某些信息或者参数来告诉地图框架进行图片的请求
3.框架请求图片至浏览器并通过自身解析添加在地图上
我们一步一步来带大家操作一遍,体会一下实际的wmts请求。
首先你通过第一种方式请求到了一个能够描述wmts服务端切片信息的xml文档,他可能是像下面这个样子的:
这里面写了很多东西,其中有我们上文中提到过的一些基础信息,如下:
1.请求图片的地址(url)
这个两个url都是图片请求地址,一种是传统的restful url,另一种是kvp url (Key-value-pair 键值对形式的url) ,本文以kvp为例
2.图层名称
3.样式以及格式
至于服务信息都是固定的,就不再赘述里
除了这些基本信息外,这个xml文档也描述了切片矩阵的信息,让我们一起来看下:
首先第一个要说的是TileMatrixSet,意思是切片矩阵集合,它是一个集合,里面装着很多个切片矩阵,一般来讲,服务端可以选择在任意分辨率下进行切片,TileMatrixSet就是用来记录在每个分辨率下地图的切片信息,正如文中之前讲过的,随着地图的不断放大,肯定切片数量和大小都会随之发生变化。
其中,
这个信息很重要,他描述的是这个切片矩阵集合是基于何种分辨率计算尺度下的,一般来讲我们无法得知客户端实际加载图片时地图一个像素代表的宽和高,于是就用0.28mmx0.28mm来代表一个像素的宽高,一张切片通常的宽和高是256像素x256像素,那么一张切图实际的宽高就是256x0.28mm,不过这只是一个标准,不理解也没关系,如果某些地图框架需要这个信息就可以直接把xml文档中这个信息照搬过去就行
接下来我们来看每个具体的矩阵,
我来一一说这些参数都是什么意思,第一个参数ows:Identifier是这个矩阵的id,服务端就是通过这个参数找到具体的矩阵,要注意想加载哪一级别的切片是由客户端决定的,服务端切好图片以后图片就只是在服务器上的文件夹里,前端发送请求时携带参数可以控制服务端返回哪一级图片。另外需要注意的是,同一个图层可能有多个矩阵,因此每个矩阵(TileMatrix)的id在有些框架中也是必要的,例如在cesium中:
还有一种情况就是像geoserver发布的wmts服务一个xml会含有多个图层,因此矩阵id也是必须的。
第二个参数ScaleDenominator代表的是达到该切片请求的分辨率,达到这个分辨率的时候就能够请求这个矩阵所定义的切片,TopLeftCorner代表的是本级别切片起始点,也就是从地图的-180°,90°的位置开始切图,TileWidth和TileHeight刚才说过了代表的是这个级别下切片的高和宽是256像素。MatrixWidth和MatrixHeight分别代表矩阵的高和宽,就是矩阵的行号最大值和列号最大值,也就意味着规定了这一级别的切片有多少行和多少列,从而也能算出来该矩阵包含的图片个数。
给大家看一个明显的:
这就代表着在第13级切片矩阵时,当分辨率达到了68170.94725....时,服务端将地图切成了6848行和1416列,共6848x1416=9696768张图片,不过不用惊讶,很多图片实际上是没有被切成功的,因此请求某些图片时服务端可能会报错。
最后呢我们做一下总结,请求wmts服务的时候有两种方式,无论是restful还是kvp的请求,都需要一下几个必要的参数:
请求地址url,服务参数,格式,样式,当前切片矩阵ID,切片行号,列号
一个标准的kvp请求地址应当是:
http://61.175.211.102/arcgis/rest/services/wzmap/map/MapServer/WMTS?request=WMTS&version=1.1.0&style=default&format=img/png&tilematrix=13&tileRow=2&tileCol=5
要注意有的时候这个tilematrix不一定是纯数字,比如可能会有这样的:['EPSG:900913:1','EPSG:900913:2','EPSG:900913:3','EPSG:900913:4','EPSG:900913:5'....]



