矢量地图技术

栅格地图与矢量地图

早期使用的是栅格地图,即地图是由一张张图片按照一定数学规则拼接而成,每张图片大小一般为256*256像素。若要显示全国(或全球)地图范围,需要用到金字塔模式进行数据组织,第0级是一张256*256像素大小的全国范围缩略图,第1级则在第0级基础上进行2行2列等分出4张图片,依此类推,直到20级(或更多)。这种数据组织方式有效平衡了数据量与显示效率的矛盾。

矢量地图技术

矢量地图技术

实际应用中会先把所有栅格瓦片生成好,并存放到地图服务器上。用户浏览地图时,执行的主要动作是根据浏览器显示范围调取相应瓦片,再拼接、显示,然后用户就看到地图了。栅格地图的优势是显示速度快,对浏览器端要求较低。缺点也很明显,首先就是数据量巨大,全国范围20级地图数据量数以TB记,然后是显示特性不丰富,栅格瓦片只读,不能改变显示样式,更不能显示3D效果,再有就是栅格图增量更新不方便,只能通过重新切割相关瓦片再替换实现,这些缺点制约了栅格图的进一步应用。于是,矢量地图呼应而出。

矢量地图也是按照金字塔结构进行数据组织和读取,相应的矢量瓦片不再是图片,而是包含点、线、面等数据和指令的集合。相比而言,矢量地图的数据量更小,通常为几个到几十GB;地图表现力很强,可以灵活配置显示样式,可以进行3D渲染,可以不依赖显示器分辨率,可以快速实现增量更新;另外,矢量地图能更好地进行数据加密等等。

矢量地图对显示端要求更高,其渲染效果是基于WebGL实现的。WebGL是一个融合JavaScript语言和OpenGL库的绘图协议,以此可实现丰富的要素显示效果,尤其是3D绘制能力,典型代表如三维场景渲染库three.js等。主流浏览器内核均已支持该技术,而无需安装额外插件,如 Chrome 9+、Firefox 4+、IE 11+、Opera 12+、Safari 5.1+。简言之,若要显示3D地图,必须要使用支持WebGL的浏览器。目前,矢量地图已经广泛应用起来,像百度地图、高德地图、谷歌地图、MapBox、OSM等。

矢量瓦片

矢量地图是通过矢量瓦片实现的,矢量瓦片是一个数据包单元,其中包含了点、线、面数据及其操作指令。其结构如图:

矢量地图技术

每个矢量瓦片可以包含多个图层,图层又包含多个特征,特征由几何图形组成。图层对象存放所有的绘制指令和坐标数据(偏移数),特征对象存放了自己相关的指令和数据索引,真正的指令和数据要在图层对象中获取。常用的绘制指令有moveTo、lineTo、close等,坐标数据因为存放的是偏移量,所以给4个字节长度足够用了。为了减少数据量,数据都是按位存放的,比如,无符号整型变量在内存中占32bit(4个byte),可以用低3位存放指令,剩下的29位存放指令执行的数量。对于坐标数据,通常会处理成整数,这样比小数方便存储,读取效率也更高。所以指令和数据的内存结构就变成了:

矢量地图技术

 客户端则需要按结构解析,并执行绘制命令。通过上述介绍可以看出,可以通过灵活的命令和参数操作矢量瓦片数据,使其显示效果极其丰富,这是栅格瓦片不具有的特性。

常用的矢量瓦片格式有pbf、mvt、 geojson等,由于protobuf具有跨平台、数据量小的特点(可参考往期博客:protobuf协议原理与应用),工程中用pbf的更多,geojson则可读性更佳。

地图访问

服务器端搭建好地图访问服务后,客户端可通过浏览器访问地图。地图访问接口通常遵循OGC标准,除此以外,应用广泛的还有ZXY取图接口,Z表示地图等级(或比例尺),X、Y表示所在级别的瓦片行列号。前端地图框架在调取瓦片数据时,首先根据当前显示级别计算出屏幕覆盖范围,然后将屏幕坐标转经纬度再转瓦片坐标,将视域内瓦片块分别调取,最后由渲染接口将地图显示出来。

浏览地图时看到的是平面图,将球面坐标到平面坐标需要进行投影转换。投影变换的种类很多,有平面投影、圆锥投影、圆柱投影等等,按投影轴与地轴的方向分为正轴投影、斜轴投影、横轴投影,按照投影面与地球表面位置又分为切投影、割投影,按照投影效果又分为等积、等角、等距之分。我们接触最多的是墨卡托投影,即正轴等角圆柱投影,我国大于1:100万比例尺地图采用的是横轴墨卡托(TM)投影。需要注意的是,互联网地图采用的是Web Mercator投影,相比标准Merctor投影,Web Mercator投影是选用WGS84椭球的长半轴为半径构成的球体投用,可能是考虑这种方式更容易计算,实际上两者主要在纬度上计算有差异。这种投影有谷歌提出应用,已基本成为业界规范。