CartoCSS指南

4.5 理解元瓦片

在现代Web制图应用中,一幅地图通常是由一系列具有相同尺寸的小块无缝拼合而成的。在专业术语中,这些小块被称为瓦片(tile)。尽管瓦片最终是以独立图片的形式出现,但支持CartoCSS的Web制图软件及其底层的渲染引擎会先以组的方式批量渲染瓦片,然后再对其切分得到最终的瓦片。这种处理方式能够从多个方面改善制图效率。

在使用支持CartoCSS的工具进行制图时,为了能够更高效的配置地图样式,并且合理规避一些制图渲染中的特殊问题,了解元瓦片(metatiles)的工作机理是很有必要的。元瓦片的配置在绘制地图样式中的标注、注记和图案等方面扮演着重要的角色。

元瓦片的结构

There are two main parts to a metatile: the tiles and the buffer. By default a metatile in TileMill consists of 4 tiles (arranged 2 wide and 2 high) and a buffer of 256 pixels around the tiles.

元瓦片主要包括两个组成部分:瓦片和缓冲区。一个元瓦片在默认情况下由4个(2行2列)个瓦片和一个环绕在这4个瓦片周围,256像素宽(译注:图中缓冲区条带的宽度不是128么?)的缓冲区组成。

元瓦片的缓冲区部分也会被制图渲染引擎(译注:也就是Mapnik)绘制,但这部分在最终的地图上不会被显示出来。在瓦片周围多渲染一个缓冲区的目的是为了保证标注、注记等地图要素在跨越元瓦片边界的时候仍然能够被正确绘制。如果没有这个缓冲区,那么就会在每个瓦片的边缘处出现大量被切割的标注、图标等。

调整元瓦片配置

元瓦片中包含的瓦片数量和缓冲区大小都是可以配置的。以TileMill为例,调整元瓦片中瓦片数量的方法是打开项目设置,然后拖动元瓦片大小滑块到合适的位置。滑块数值的平方代表了元瓦片中包含瓦片的个数。而缓冲区大小的调整则需要在CartoCSS中完成。在Map对象中增加一个buffer-size属性,它的值(必须是整数)就是缓冲区的像素宽度:

Map {
  background-color: white;
  buffer-size: 256;
}

合理设置缓冲区大小

如果你发现在地图上出现了标注和图标被切割的情况,那么就应该考虑调整增大缓冲区了。但是应该把缓冲区宽度设成多少呢?建议找到地图上最宽的标注,然后就先从它的宽度开始尝试。

合理设置元瓦片尺寸

对于大多数情况,使用默认的元瓦片尺寸(也就是2)就可以了。这意味着渲染引擎会将地图内容先渲染到长宽均为512像素的“大”瓦片上,然后再将其切分成4个长宽为256像素的正常瓦片并返回给地图显示前端。当一个或者更多的相邻瓦片请求正好命中同一个元瓦片时,渲染引擎会在切片之前暂停很短的时间以处理元瓦片,然后再将每个独立的256像素瓦片返回给地图显示前端。

但在一些特殊的情况下需要调整元瓦片的尺寸:有一种可能的原因让你想要将元瓦片的尺寸减小到1;而有两种可能的原因让你想把这个值增大到8或16。下面分别介绍这两种情况。

减小元瓦片尺寸

要把元瓦片尺寸从默认值2调小,那么只可能是调成1,也就是关闭元瓦片功能。这样做可以让地图在编辑制图样式过程中的响应轻微加快,因为这时每个瓦片都是独立渲染的了。如果当前地图视图范围内的某些瓦片包含的数据较多,而另一些瓦片包含的数据较少,那么关闭元瓦片功能之后会使包含数据较少的瓦片比相邻的包含数据较多的瓦片更快绘制出来。

增大元瓦片尺寸
原因1:减少导出时间

While disabling metatiling can give a more responsive feel to the map UI, the opposite is true when exporting to MBTiles. Increasing the metatile size can significantly increase overall performance and decrease the overall time it takes to render an entire export job. This is because rendering many tiles in sequence using larger metatiles means doing less overall work.

如果说关闭元瓦片功能可以让制图过程感觉响应速度更快,那么反过来(增大元瓦片尺寸)则可以让导出地图到MBTiles的过程变得更快。增大元瓦片的尺寸可以显著提高地图整体的渲染效率,缩短在执行导出任务时的渲染时间。其原因是在串行渲染大量瓦片时,如果使用尺寸更大的元瓦片,那么就意味着需要更少的整体工作量。(译注:这里的潜台词是:渲染4个小瓦片的时间要大于渲染1个大瓦片的时间。但事实是这样吗?原因何在?极端情况下,把整张地图全画在一个超级大瓦片上会是最快的吗?)

然而到底使用多大的元瓦片才能获得最佳的导出性能呢?这的确是没有个硬性准则的。这和地图中包含多少数据量、有没有建好空间索引、执行导出任务的机器内存有多大等许多因素都有关。

我们的建议是先取地图的一小部分(只选几个缩放级别,或者框一小块区域)做做测试,看看把元瓦片的尺寸分别设成4、8或16时导出性能会有什么变化。然后根据实验结果选取最佳的元瓦片大小。

原因2:减少瓦片边缘的切割问题

更大的元瓦片意味着标注、注记等要素被绘制在瓦片边缘的概率会降低。另外,对于一些标注算法(比如通过设置text-min-distance属性控制重复绘制标注的间距),更大的元瓦片可以让它有更大的工作空间,从而得到更好的标注绘制效果。

参考文献

  1. Mapbox, Understanding Metatiles