瓦片计算

不同环境条件下,加载具有不同细节的图片资源,可以提高效率,但这并不是终点。 瓦片技术可以更进一步提高效率。 其原理是将一张大图片切割成很多张小图片,按照呈现需要,加载其中的几张小图片即可。 为什么这样就能提高效率?因为屏幕显示窗口的大小是固定,比如屏幕分辨率是800*600,或者1024*768,又或者是1920*800等等。如果屏幕分辨率是800*600,一张大图是9000*9000,那么同一时间,你只能看到这张图片的十分之一。 但是在不切片的情况下,你却必须要加载整个地图。 如果是在本地浏览还好,假如是发布在网络上,则网络传输和渲染,都将耗时。如果我们按照500*500大小进行切片,我们则只需要加载4张500*500的小图片就可以了。 对于WebGIS而言,需要在网络上发布,同时需要显示整个地球,自然需要使用瓦片技术。

切片方式

如果对整个地球图片进行切片,需要考虑的是整个地球图片大小,以及切片规则,切片大小。 对于WebGIS而言,在线地图几乎都采用墨卡托投影坐标系(Mercator),对应的地图投影到平面上就是一个正方形。 为了方便使用,切片时大多按照正方形的方式来进行切片,比如切片大小为256*256。一个1024*1024的地图,就可以切成4张小的瓦片。 同时,瓦片大小几乎都是256*256,有一些则会增加到512*512。

LOD会使得不同层级下的全球地图大小不一致,结合瓦片技术一起,就出现了金字塔瓦片。 参见万能瓦片地图加载秘籍里面的图。 在WebGIS中,上一层级的一张瓦片,在更大一层级中,会用4张瓦片来表示,依次类推,比如上一节中看到的Google在线瓦片地图的第0级和第1级的瓦片地图。 这样做可以维持正方形的投影方式不变,同时按照2的幂次方放大,计算效率非常高。

计算

通过上面切片的介绍,我们可以对每一层级瓦片的数量进行简单的计算。 层级0的瓦片数是1=20201=2^0*2^0, 层级1的瓦片数是4=21214=2^1*2^1,层级n的瓦片数是2n2n2^n*2^n。 这个地方计算的是所有瓦片数,因为是一个正方形,所以是边长的平方,如只计算x轴或者y轴一边的瓦片数,就是2n2^n个。

瓦片坐标

任意一个层级的地图,切成多个瓦片后,我们需要给瓦片编号,才能通过编号找到瓦片。这个问题在这就涉及到坐标系,在万能瓦片地图加载秘籍里我们提到过,不同的在线地图服务商,可能定义不一样的瓦片坐标系,坐标系不一样,那么对应的同一个位置的瓦片的坐标也会不一样。 需要引起重视。

在OpenLayers 3提供了一个用于调试瓦片的source: ol.source.TileDebug。可以清晰的看到每一个瓦片的坐标:

代码如下:

<div id="map" style="width: 100%"></div>
<script type="text/javascript">
    var osmSource = new ol.source.OSM();
    var map = new ol.Map({
    layers: [
        // 加载Open Street Map地图
      new ol.layer.Tile({
        source: osmSource
      }),
      // 添加一个显示Open Street Map地图瓦片网格的图层
      new ol.layer.Tile({
        source: new ol.source.TileDebug({
          projection: 'EPSG:3857',
          tileGrid: osmSource.getTileGrid()
        })
      })
    ],
    target: 'map',
    view: new ol.View({
      center: ol.proj.transform(
          [104, 30], 'EPSG:4326', 'EPSG:3857'),
      zoom: 10
    })
});
</script>

首先从上图可以看到地图上多了网格,每一个网格对应的就是一个瓦片。 其次网格中有三个数字,这些数字就表示当前瓦片的坐标,第一个数字是层级z,第二个数字是表示经度方向上的x,第三个数字是表示维度方向上的y。 同样的,可以采用上面的方式来看看在万能瓦片地图加载秘籍中提到的各种瓦片地图的瓦片坐标。