王文杰,申传庆,张 哲,王丽惠
(1.自然资源部陕西基础地理信息中心,陕西 西安 710054;2.自然资源部第一地形测量队,陕西 西安 710054)
目前,地图服务的种类一般包括瓦片地图服务WMTS(web map tile service),动态地图服务WMS(web map service),要素地图服务WFS(web feature service)等几种类型,不同服务在前端显示的技术有所不同。其中瓦片地图服务又称缓存地图服务,地图缓存是通过预先制作完成的不同比例尺级别的地图分块图像(瓦片)进行分发,是实现地图使用的一种非常有效的方法。但其在地图显示时,按空间范围进行显示控制比较困难;动态地图服务与瓦片地图服务使用方式类似,二者的主要区别是动态地图的图层内容可以指定,但该方法是在服务端渲染,因性能原因应用较少[1-3]。要素地图服务则可以通过属性、空间范围等参数筛选需要显示的数据,数据过滤效率较低,且需要前端自定义渲染,主要用于数据检索方面。文献[4]针对ArcGIS 的动态服务提出了一种图像处理的方式实现范围控制,显示效果较好,但对瓦片服务的控制无法实现。文献[5]对瓦片服务请求返回的图片进行相交判断,实时裁切达到范围显示控制,但是由于计算量较大,影响了地图显示的效率。文献[6]尝试了基于Html5 页面CSS不规则遮罩的控制方法,该方法性能因遮罩范围的坐标复杂度而受到限制。文献[7]利用ArcGIS Server SOE 和种子填充算法,实现了对ArcGIS 地图服务的定制范围和图层类别的显示控制,但只能服务于Arc-GIS 动态图层服务,操作复杂且容易导致地图服务异常。从前面列举的文献可以看出,对电子地图显示范围控制多是基于传统栅格地图,随着矢量瓦片地图逐步成为地图服务应用的热点,本文主要研究基于矢量瓦片的电子地图显示范围控制方法。
矢量瓦片地图是一种基于四叉树金字塔模型,将矢量数据按地理格网进行分割形成瓦片数据,客户端根据地图显示范围从服务器获取相应的瓦片,通过指定样式在客户端实现地图的实时绘制[1]。针对矢量瓦片技术,Mapbox 公司制定的矢量瓦片规范(Mapbox Vector Tile Specification)已经被众多公司和组织所采用,它是一种节省存储空间的数据编码方式,能够在客户端高效渲染或查询要素信息。
Mapbox地图渲染样式规范定义了一套地图所呈现的视觉外观配置方法,内容包括绘制数据源、过滤器、图层样式、字体等内容。其中对矢量图层的渲染,首先定义ID,引用一个瓦片数据源(source),指定的要素内容(source-layer),并可对source-layer 内容进行过滤(filter),然后定义要素渲染的具体参数(paint)。
基于矢量瓦片技术,研究一种只发布一套地图,可实现对该地图内任意区域单独显示的技术方法,尤其适用于按多级行政区划显示地图的应用中。在发布完一幅全域地图后,当需要单独显示其中某一子域范围内地图时,只需要从全域地图中选取子域地图进行展示,而无需再对子域单独发布一个的地图。
矢量瓦片是一种在客户端进行渲染的新型矢量地图服务,支持地图样式的灵活配置,基于此特性,对需要按范围控制显示的矢量数据,可通过前端数据过滤的方式对实现数据显示范围的控制。首先按最小空间单元分割并赋予范围属性值,然后进行矢量数据瓦片,在发布为矢量瓦片服务后,客户端进行地图渲染时可对矢量瓦片按空间范围属性标识进行过滤,从而实现地图显示范围的控制。
矢量瓦片地图显示范围控制的实现流程总体分为两步,一是在矢量数据预处理与瓦片时,在矢量数据属性中增加区域标识码;二是对地图服务调用时,在服务访问参数中设置区域标识码参数,在返回的矢量瓦片样式文件中自动添加区域标识码过滤配置,从而在地图展示时可实现按区域进行地图展示。
在数据预处理阶段,首先将矢量数据按最小区域单元(如行政区划中的村界)进行分割,然后根据数据所在的空间区域对数据添加区域代码属性(如赋予数据所属行政区划中村的代码值),如果需要按多级空间范围展示,可对矢量数据添加多个级别的空间区域代码属性(如行政区划中村所在的乡镇代码、区县代码等)。由于矢量瓦片本身会对矢量数据进行分割,因此按区域对矢量数据进行分割,不影响数据内容的准确性。
全域范围P包含子域P1、P2、P3,矢量线要素A包含在全域P中,同时分布在子域P1、P2、P3中,P为一级区域,P1、P2、P3为二级区域。在数据预处理阶段,在P1、P2、P3的边界处对A进行断开处理,得到A的子集a1、a2、a3。对a1、a2、a3添加1级区域属性L1,并赋值为P;对a1、a2、a3添加2 级区域属性L2,根据其所处的2 级空间区域,分别赋值为P1、P2、P3,属性设置结果如表1所示。
表1 矢量数据属性赋值
图1 与表1 表示了空间区域划分为两级的情况,如果P1、P2、P3继续分割为更小的子域,则需要对a1、a2、a3按更小子域的边界进行分割,同时增加新的子域属性Ln,属性赋值以此类推。
图1 矢量数据预处理
对完成预处理的矢量数据,进行矢量数据切片,并将区域属性(如1.2 属性L1、L2)输出到矢量瓦片中,然后发布为矢量瓦片服务。目前常用的矢量数据瓦片的商业工具有ESRI公司的ArcGIS Pro和北京超图地理信息技术有限公司的SuperMap iDesktop等,开源工 具 有Geoserver、Mapbox、TileStache、Mapnik 等,各种软件对矢量数据瓦片的包装格式各不相同,但底层实现都是PBF(google protocol buffers)格式。对矢量瓦片地图服务发布支持的软件有ArcGIS Portal、SuperMap IServer、GeoServer、Mapbox等。
发布完成的矢量瓦片地图,先配置地图样式,然后通过Web API进行调用。基于矢量瓦片的电子地图显示范围控制是渲染时通过设置数据过滤条件实现的,数据过滤条件在地图渲染时的样式文件中进行配置,由客户端指定。
如表2 所示,过滤条件以键值对应的方式进行表示。filter为过滤标识,其值为一个数组对象。
表2 显示范围过滤条件配置
在实际应用中,按行政区划对地图进行显示,是电子地图显示范围过滤最常见的一种应用场景。按本文所述技术原理,以安康市综合电子地图为实验数据,采用GeoServer制作并发布矢量瓦片地图服务,对安康市综合电子地图进行控制显示范围实验。
在发布完成矢量瓦片地图服务之后,默认展示地图为安康市全域地图,如图1 所示。样式中数据过滤配置为filter:["all",["in","CITYCODE","610900"]],其中CITYCODE为市级区划代码的属性名,610900为安康市区划代码值。
当只显示安康市一个子域旬阳市(县级市)的地图时,数据过滤配置为filter: ["all", ["in", "COUNTYCODE", "610928"]],其中COUNTYCODE 为县级区划代码的属性名,610928 为旬阳市(县级市)的区划代码值。
当同时显示安康市内2 个子域宁陕县与旬阳市的地图时, 数据过滤配置为filter: ["all", ["in", "COUNTYCODE","610928","610922"],其中,610928为旬阳市(县级市)的区划代码值,610922为宁陕县的区划代码值。如需显示2个以上子域,配置与此类似。
当不显示安康市内子域旬阳市的地图时,数据过滤配置为filter: ["none", ["in", "COUNTYCODE", "610928"]],其中,610928 为旬阳市(县级市)的区划代码值。如需不显示2个以上子域,配置与此类似。
传统的地图服务应用中,如果需要按范围显示地图,则是将数据预先按范围进行裁切,然后发布为多个地图服务,这显然是一种数据体不同,其他操作与配置基本相同的服务提供方式,这种方式对服务发布与管理的压力较大。如上述实验中的4 种地图范围场景,传统地图服务需要发布4 个单独的服务,而通过设置过滤条件的矢量瓦片地图只需发布一个服务即可实现。
本文方法是在客户端通过数据过滤方式实现电子地图按范围显示,发布一套地图可支持多种显示范围。经过实践验证,在地理信息服务应用领域内能够满足地图按范围显示的需求,但这种机制并没有从数据源头对数据内容进行控制,如果涉及按空间范围进行数据安全控制时,该方法有不足之处。由于矢量瓦片数据是一种可编辑的数据,讨论在服务端直接对数据内容按空间范围进行过滤时,可以进一步拓展矢量瓦片服务按范围展示的应用场景。