矢量地图切片技术分析

1. 什么是矢量切片

传统的栅格地图切片,是预先在Server端绘制好固定的PNG和JPG切片集合。而矢量切片是很早就已经出现,并已通过各种不同的技术手段在应用中表现出来,大多以json或二进制文件将矢量地图数据传输至前端进行绘制。例如百度地图、Google地图等都较早实现了栅格和矢量两种模式。

矢量地图切片将矢量数据通过不同的描述文件来组织和定义,通常通过自定义文件或json文件进行传输,在前端按需请求不同的矢量瓦片数据文件,并利用类似canvas等技术进行绘制。使用这种技术有不少好处,例如不再需要为不同的样式而反复进行制图、渲染、切片、更新service等过程,并且在当前各种高分屏、视网膜屏大肆发展的阶段,避开按照特定DPI和分辨率渲染的栅格图片在不同的显示设备上无法以统一清晰的效果呈现,等等。

当前,矢量切片已经广泛应用开了,现在的在OSM数据中得到了广泛的使用,例如这个站点提供了OSM Planet和分国家区域的daily下载包,并且以MBTiles文件的形式提供。

 

1.1 矢量切片规范

Mapbox提出了Vector Tile的开放规范,并遵守Creative Commons Attribution 3.0 United States License:Mapbox Vector Tile Specification,该规范用到了Google的Protocol Buffers作为数据编码规范。同样被Mapbox列入规范的还有MBTiles is a specification,作为在SQLite中存储切片数据的规范。在两者的github页面上,都可以找到对应规范的实现清单,这些实现大多是开源工具,也包含一些闭源软件,而这些所有,足以支撑起矢量切片的数据转换、数据存储、数据服务的全技术架构的基本骨架。

1.2 数据存储

在Mapbox所用的实现中,Google Protocol Buffers是很重要的一环,Vector tiles被编码为.mvt为后缀的文件。其中,最核心的数据结构定义可参看:Vector Tile protobuf schema document

值得一提的是,OpenStreetMap的数据包也叫PBF,也同样用到了该数据互交换格式,但正如对XML的不同应用一样,两者并不相同。

MBTiles是另一种存储技术,号称能够高效地在单个SQLite数据文件中存储百万级的切片。这实质上是利用了SQLite本身较好地跨平台特性,所以Mapbox iOS toolkits等也能够直接利用MBTiles来存储数据。另一个比较显著的特点是方便图像的复用,例如大比例尺下,大量单色区域(绿地、海洋等)的切片文件可以重用。例如TileMill(现在已演化为Mapbox Studio)使用MBTiles来存储数据,并用于导出切片文件。MBTiles作为关系数据库,自然也可以用于存储矢量切片。目前来看,MBTiles最常用的使用场景是切片数据的导入导出和移动端离线使用。

例如一个典型的MBTiles库的切片表的字段如下:

2. 矢量切片的地图投影

目前为止,大多数的VT技术都没有在地图投影上做太多扩展,例如Mapbox就只支持Web Mercator投影。其实纵观Web Map的发展,这似乎一直都是不成文的行业规范了。2005年,Google Map的异军突起让Web Mercator得以众所周知,作为墨卡托投影的一个变种,这种投影(通常,指的是ESPG:3857,历史上变迁过多次,更多可看看这篇文章)被越来越广泛地使用,OpenStreetMap、Mapbox、BingMaps、Mapquest等等。此外,ESRI等商业GIS平台也都有较好的支持。开源的地图前端框架,例如OpenLayers、Leaflet等,也极其推崇这个投影。这是典型的工程领域推动的产物,而非科学界到工程界的应用,而过程也比较漫长,下面概要地整理了下Web Mercator投影的发展过程。

2.1 Mercator投影

Web Mercator其实是墨卡托投影的一个变种,所以不得不提到传统意义上的Mercator投影。这种投影得名于Gerardus Mercator(1512-1594),一个荷兰的地图学家,并由其于1569年提出。按照这种投影法,可以将世界地图绘制在一整个长方形画布上,而经纬线在任何地方都能垂直相交。这种地图在编制航海图中应用很广泛。

墨卡托投影通常叫做“正轴等角圆柱投影”,或“等角正切圆柱投影”,即以与地轴方向一致的圆柱切割地球,按照等角条件,将经纬网投影到圆柱面上,最后讲圆柱面展开成平面后形成。这样的展开,经纬线相交成直角,经线间隔相等,而纬线间隔从基准纬线处相两极逐渐增大。因此,墨卡托投影的地图上长度和面积变形明显:基准纬线处无变形,变形程度向两极逐渐增大,但是因为它在各个方向均等扩大的特性,保持了方向和相互位置关系的正确。这也是为什么在地图上,方向和角度依然是保持正确的,因此地图上两点的航线,方向是正确的,所以在海上能够准确指向目的地。

QQ20161210-0
上图来自维基百科

2.2 Web Mercator的变化

Web Mercator的公式与标准的球面墨卡托投影一样,实质上是将球面墨卡托投影公式运用于椭球面坐标的投影计算方法。该投影坐标的大地基准面(Datum)是WGS84椭球体,球面墨卡托投影公式选用WGS84椭球体的长半轴半径,即6378137米。相比于墨卡托投影(球面或椭球面)在任意点各向长度比相等,沿直线方位不变的特性,只相当于近似的椭球面墨卡托。

从数学公式来看,墨卡托投影的地图坐标计算公式如下:

\[
x=R(\lambda-\lambda_0) \\
y=R ln tan({\pi \over 4}+{\phi \over 2})
\]

其中\(R\)是球体的半径,\(\lambda\)是经度(弧度),\(\phi\)是纬度(弧度)。

类球体(spheroid,也有时候叫做ellipsoid of revolution)的地图坐标如下:
\[
x=a(\lambda-\lambda_0) \\
y={a\over2}ln [
tan({\pi \over 4}+{\phi \over 2})
{({{1-e\sin\phi} \over {1+e\sin\phi}})}^{e\over2}
]
\]

其中\(a\)是椭球体的长半轴,\(e\)是椭球体的第一偏心率,\(e={\epsilon \over a}\),\(\epsilon=\sqrt{a^2-b^2}\),\(b\)是椭球体的短半径。

某种程度上讲,Web Mercator的坐标计算与Mercator相比,主要在于纬度的计算,而这种计算差异,却是工程领域逐步传承下来的做法。普遍认为,当年谷歌工程师为了简便计算(抑或压根是搞错了?),直接使用了WGS84椭球体的长半轴作为半径的正球体(没有使用椭球体和第一偏心率),公式中的经纬度坐标使用的是WGS84坐标。这显然不符合地图学和GIS学界的科学理论,甚至有人认为搞乱了空间参考的标准体系。我猜测也是长久以来这种投影没有被学界广泛宣传的原因之一。

因此,考虑这种球体和椭球体之间的混搭,Web Mercator并非是等角投影了,只能说是近似。有人做了如下的实验,对比了两种投影在纬线上的差异。


上图借用自这篇博文

在ArcGIS的投影中,Web Mercator被称作Auxiliary Sphere。而在投影参数设置上,3785使用的是正球体参数,3857使用的是椭球体参数。

3. 应用技术架构

矢量切片只是GIS或地图可视化服务的其中一个实现环节,所以首先要构建完整的地图服务架构,在这点上,商业平台如ESRI,可以基于各自的实现技术来满足用户需求。然而熟悉开源技术栈的架构,有利于灵活配置和构建满足特定使用场景的平台、工具链或搭建个性化的数据生产流程。

首先值得借鉴的,是OpenStreetMap,OSM创立了开源地图和协同服务的完整案例,在其wiki上可以看到OSM Components的发展历程,当前的架构如下图:

该架构图从数据库、API、前端、后端Tile层、编辑器等角度,提供了尽可能全地工具框架,取其所需者,应可获益良多。

工具的使用可以让架构大相近庭,然而也有一些基本实现的文章值得一读,例如Graham Dunlop的这篇博文:Vector tiles remixed,介绍了如何脱离Mapbox技术栈,来实现基于开放地图数据的MVT的创建。下图是他的工作流,看的出来tilemaker是他使用的核心组件,更多内容可以直接去阅读那篇文章,不多赘述,但这中技术流程理论上可以移植到任何基础数据,而非仅仅是OSM planet data。

4. 总结

通过已有开源框架的大致情况分析,矢量切片相关的数据读取和解析、前端可视化技术,相对较为丰富,而私有化的样式和制图工具、切片维护和服务工具都还比较短缺或者说并不是很完善。因此,要自行完整搭建一套基于私有数据的矢量切片数据处理与服务平台,技术上仍然有很多路要走,不仅说是要跨坑,而且有不少桥梁要搭建,又不少针对现有组建的改动需要完成。任重而道远,但依旧是可以去做的事情。

更多参考:
  1. Implications of Web Mercator and Its Use in Online Mapping
  2. http://gdunlop.github.io/Vector-tiles-remixed/
  3. https://www.mapbox.com/about/open/
  4. https://github.com/mapbox/awesome-vector-tiles
  5. http://wiki.openstreetmap.org/wiki/Main_Page