GIS

Vector Tile是什么

了解GIS中Vector Tile(矢量瓦片)的基本概念、数据结构、切片方式、缩放级别、MVT格式以及Vector Tile与GeoJSON、Raster Tile和地图渲染之间的关系。

阅读约 117 分钟

Vector Tile是什么

Vector Tile(矢量瓦片)是一种将大量矢量地理数据按照地图瓦片方式进行切分和传输的技术。

简单来说:

Vector Tile就是把大量GIS矢量数据切成一个个小的数据块,地图需要哪个区域,就加载哪个区域的数据。

传统的矢量数据可能包含:

道路
建筑物
河流
行政区
POI
土地

如果一次性把整个城市甚至整个国家的数据发送给浏览器:

大量GIS数据
    ↓
全部下载
    ↓
浏览器解析
    ↓
地图渲染

数据量可能非常大。

Vector Tile则采用:

整个地图
    ↓
切成很多瓦片
    ↓
按需加载
    ↓
只获取当前地图需要的数据

因此Vector Tile非常适合:

  • WebGIS
  • 在线地图
  • 大规模矢量数据
  • 地图缩放
  • 地图平移
  • 动态地图渲染
  • 地图样式控制

什么是Tile

Tile就是:

瓦片

可以把一张很大的地图想象成一张巨大的图片。

如果一次性加载:

┌──────────────────────────────┐
│                              │
│          整个地图             │
│                              │
└──────────────────────────────┘

数据量可能很大。

因此可以切成很多小块:

┌──────┬──────┬──────┬──────┐
│  1   │  2   │  3   │  4   │
├──────┼──────┼──────┼──────┤
│  5   │  6   │  7   │  8   │
├──────┼──────┼──────┼──────┤
│  9   │  10  │  11  │  12  │
└──────┴──────┴──────┴──────┘

每个小块就是一个Tile。

地图只需要加载当前视口附近的Tile。

Raster Tile与Vector Tile

地图瓦片主要可以分为两类:

Tile
├── Raster Tile
└── Vector Tile

Raster Tile:

瓦片
 ↓
图片

Vector Tile:

瓦片
 ↓
矢量数据

例如Raster Tile:

PNG
JPG
WebP

Vector Tile:

MVT

两者最大的区别是:

Raster Tile保存的是像素,而Vector Tile保存的是矢量几何和属性数据。

Raster Tile

Raster Tile本质上是一张图片。

例如:

tile.png

地图服务器返回:

┌──────────────────┐
│                  │
│     地图图片      │
│                  │
└──────────────────┘

浏览器直接显示图片。

优点:

  • 简单
  • 兼容性好
  • 渲染成熟

缺点:

  • 放大容易失真
  • 样式通常由服务器决定
  • 无法方便地修改单个矢量对象样式
  • 图片数据无法直接作为Geometry进行空间分析

Vector Tile

Vector Tile保存的是矢量数据。

例如:

道路
    ↓
LineString

建筑
    ↓
Polygon

POI
    ↓
Point

因此浏览器拿到Vector Tile以后,可以自己进行渲染。

例如:

Vector Tile
    ↓
解析Geometry
    ↓
地图渲染引擎
    ↓
显示道路、建筑、POI

Vector Tile的基本结构

Vector Tile通常可以理解为:

Vector Tile
├── Layer
│   ├── Feature
│   │   ├── Geometry
│   │   └── Properties
│   │
│   └── Feature
│
└── Layer

例如一个瓦片:

Tile
├── roads
│   ├── Road 1
│   ├── Road 2
│   └── Road 3
│
├── buildings
│   ├── Building 1
│   └── Building 2
│
└── poi
    ├── POI 1
    └── POI 2

因此一个Vector Tile可以同时包含多个图层。

Vector Tile中的Layer

Vector Tile通常按照Layer组织数据。

例如:

Tile
├── roads
├── buildings
├── water
└── poi

其中:

roads

负责道路。

buildings

负责建筑物。

water

负责水系。

poi

负责兴趣点。

这种组织方式非常适合地图渲染。

Vector Tile中的Feature

每个Layer中包含多个Feature。

例如:

roads
├── Feature 1
├── Feature 2
├── Feature 3
└── Feature 4

一个Feature通常包含:

Geometry
+
Properties

例如:

Feature
├── Geometry
│   └── LineString
│
└── Properties
    ├── name
    ├── type
    └── level

因此Vector Tile仍然延续了GIS中:

Feature
    ↓
Geometry + Attributes

的基本思想。

Vector Tile中的Geometry

Vector Tile可以保存不同类型的矢量Geometry。

例如:

Point
LineString
Polygon

对应:

POI
道路
建筑物

例如:

roads
    ↓
LineString
buildings
    ↓
Polygon
poi
    ↓
Point

因此:

Vector Tile
    ↓
Feature
    ↓
Geometry

与普通GIS矢量数据的概念是一致的。

Vector Tile为什么需要切片

假设一个城市拥有:

100万条道路和建筑数据

如果一次加载:

100万Feature
    ↓
浏览器

会带来:

  • 网络传输压力
  • 数据解析压力
  • 内存压力
  • GPU压力
  • 渲染压力

Vector Tile可以:

100万Feature
    ↓
空间切片
    ↓
大量Tile

例如:

Tile 1
Tile 2
Tile 3
...
Tile N

用户只查看某个区域:

Viewport
    ↓
需要Tile 100
Tile 101
Tile 102
Tile 103

只请求这些数据。

Vector Tile的XYZ结构

Web地图中最常见的瓦片索引方式是:

z
x
y

通常称为:

XYZ Tile

例如:

z = 10
x = 843
y = 386

可以表示:

z/x/y

即:

10/843/386

一个典型Vector Tile URL可以类似:

/tiles/10/843/386.pbf

其中:

10
 ↓
Zoom

843
 ↓
X

386
 ↓
Y

Zoom

Zoom表示地图缩放级别。

例如:

Zoom 0

通常表示整个世界由非常少的瓦片表示。

随着Zoom增加:

Zoom 0
    ↓
Zoom 1
    ↓
Zoom 2
    ↓
Zoom 3
    ↓
...

地图越来越详细。

可以简单理解为:

Zoom小
    ↓
看整个世界

Zoom大
    ↓
看街道和建筑

Zoom与瓦片数量

如果使用标准XYZ瓦片体系:

Zoom 0
    ↓
1 × 1

Zoom 1
    ↓
2 × 2

Zoom 2
    ↓
4 × 4

Zoom 3
    ↓
8 × 8

因此Zoom为 z 时,理论上每个方向有:

2^z

个瓦片。

整个世界最多有:

2^z × 2^z

即:

4^z

个瓦片。

Vector Tile的加载过程

用户打开地图:

用户打开地图
      ↓
确定Viewport
      ↓
确定Zoom
      ↓
计算需要的Tile
      ↓
请求Vector Tile
      ↓
解析数据
      ↓
地图渲染

例如:

Viewport
    ↓
z = 12
    ↓
计算x/y
    ↓
请求
12/3432/1684.pbf
    ↓
解析
    ↓
渲染道路和建筑

Vector Tile的格式:MVT

最常见的Vector Tile标准格式是:

MVT

全称:

Mapbox Vector Tile

MVT是一种用于编码Vector Tile的标准格式。

它通常使用:

Protocol Buffers

进行编码。

因此实际文件通常是:

.pbf

例如:

12/3432/1684.pbf

可以理解为:

MVT
 ↓
Protocol Buffers
 ↓
.pbf

PBF是什么

PBF是:

Protocol Buffer

相关的二进制数据格式。

与JSON相比:

JSON:

{
  "type": "Feature",
  "properties": {
    "name": "道路"
  }
}

文本结构比较直观。

PBF:

二进制数据

体积通常更小,解析效率也更适合网络传输和地图瓦片场景。

因此Vector Tile通常不会直接使用JSON作为最终传输格式,而是使用二进制编码。

Vector Tile与GeoJSON

GeoJSON:

GeoJSON
    ↓
FeatureCollection
    ↓
Feature
    ↓
Geometry

Vector Tile:

Vector Tile
    ↓
Tile
    ↓
Layer
    ↓
Feature
    ↓
Geometry

两者都可以表达:

Point
LineString
Polygon
Properties

但使用方式不同。

特性GeoJSONVector Tile
数据组织FeatureCollectionTile + Layer + Feature
空间范围可以很大单个Tile
格式JSON通常PBF
可读性
网络传输数据较大通常更紧凑
大规模地图一般非常适合
按区域加载不天然支持核心能力
地图渲染支持非常适合

GeoJSON适合什么

GeoJSON非常适合:

数据交换
API接口
小型空间数据
开发调试
数据分析

例如:

一个行政区
    ↓
GeoJSON

或者:

100个POI
    ↓
GeoJSON

都比较方便。

Vector Tile适合什么

Vector Tile更适合:

大规模地图
道路网络
建筑物
POI
在线地图
高并发地图服务
动态地图样式

例如:

整个城市
    ↓
数百万Feature
    ↓
Vector Tile
    ↓
按Tile加载

Vector Tile与坐标

Vector Tile中的Geometry并不一定直接使用:

经度
纬度

而通常使用瓦片内部坐标系表达Geometry。

例如一个Tile可以定义:

extent = 4096

那么Tile内部空间可以理解为:

(0, 0)
   ┌─────────────────┐
   │                 │
   │                 │
   │                 │
   │                 │
   └─────────────────┘
             (4096,4096)

Geometry会被转换到这个Tile内部坐标空间。

因此:

真实世界坐标
    ↓
投影
    ↓
Tile坐标
    ↓
编码
    ↓
Vector Tile

Vector Tile中的Extent

Extent表示Tile内部坐标范围。

例如:

extent = 4096

可以理解为:

X: 0 ~ 4096
Y: 0 ~ 4096

一个道路可能变成:

LINESTRING
(
  100 500,
  300 800,
  700 1000
)

这些数字不是直接的:

经度
纬度

而是Tile内部坐标。

为什么使用Tile坐标

使用Tile内部坐标有利于:

数据压缩
网络传输
快速解析
GPU渲染
统一Tile空间

例如:

Tile A
    ↓
0 ~ 4096

Tile B
    ↓
0 ~ 4096

每个Tile都可以使用统一的局部坐标空间。

Vector Tile与坐标投影

Web地图Vector Tile通常与:

Web Mercator

密切相关。

常见坐标系:

EPSG:3857

而常见经纬度坐标:

EPSG:4326

通常需要经过投影转换:

EPSG:4326
    ↓
Web Mercator
    ↓
EPSG:3857
    ↓
Tile

因此:

Vector Tile的数据处理与地图投影、瓦片编号密切相关。

Vector Tile与EPSG:4326

EPSG:4326通常使用:

经度
纬度

例如:

116.397
39.908

这种坐标适合表示地理位置。

但Web地图瓦片通常不是直接按照经纬度瓦片进行渲染。

因此常见流程是:

EPSG:4326
    ↓
投影转换
    ↓
EPSG:3857
    ↓
Tile坐标

Vector Tile与EPSG:3857

EPSG:3857是Web地图中非常常见的投影坐标系。

它可以将:

经纬度

转换为:

平面X/Y

然后进行:

Tile切分

因此WebGIS中经常可以看到:

EPSG:4326
    ↓
EPSG:3857
    ↓
XYZ Tile
    ↓
Vector Tile

Vector Tile与Feature裁剪

一个Feature可能跨越多个Tile。

例如一条很长的道路:

───────────────

可能穿过:

┌──────┬──────┬──────┐
│ Tile │ Tile │ Tile │
│  A   │  B   │  C   │
└──────┴──────┴──────┘

因此服务器需要对Geometry进行:

Clip

即:

根据Tile边界裁剪Geometry。

例如:

完整道路
────────────────────

Tile A
────────

Tile B
        ────────

Tile C
                ───────

每个Tile只保存自己范围内需要的部分。

Vector Tile的裁剪

典型流程:

原始Geometry
      ↓
计算Tile范围
      ↓
Geometry Clip
      ↓
Tile内部坐标转换
      ↓
编码
      ↓
MVT

因此Vector Tile不仅仅是:

把GeoJSON切成很多文件

实际上还包含:

空间裁剪
坐标转换
简化
编码
属性处理

Vector Tile与Geometry简化

如果地图处于较小Zoom:

Zoom 5

用户看到的是大范围地图。

这时候没有必要保留道路的每一个顶点。

例如原始道路:

●─●─●─●─●─●─●─●─●─●

可以简化为:

●──────●──────●

这就是:

Geometry Simplification

即Geometry简化。

因此Vector Tile通常可以根据Zoom生成不同精度的数据。

Vector Tile与LOD

这与LOD思想非常接近:

Zoom小
    ↓
低精度Geometry

Zoom大
    ↓
高精度Geometry

例如:

Zoom 5
    ↓
道路简化

Zoom 10
    ↓
道路较详细

Zoom 15
    ↓
道路非常详细

因此:

Vector Tile
+
Geometry Simplification
+
LOD

可以显著提高地图性能。

Vector Tile与样式

Vector Tile最大的优势之一是:

数据和地图样式可以分离。

例如同一个道路Feature:

name = 北京路
type = primary

可以根据样式显示成:

白天地图
    ↓
黄色道路

也可以显示成:

夜间地图
    ↓
蓝色道路

数据本身没有改变。

改变的是:

Style

因此:

Vector Data
    +
Style
    ↓
Map

Vector Tile与Raster Tile的样式区别

Raster Tile:

数据
 +
样式
 ↓
图片

服务器已经把:

道路颜色
字体
线宽
建筑颜色

绘制进图片。

Vector Tile:

数据
 ↓
客户端
 ↓
Style
 ↓
渲染

因此客户端可以动态改变:

颜色
线宽
透明度
字体
图标
显示级别

Vector Tile与交互

由于Vector Tile保存的是矢量数据,因此地图可以对Feature进行交互。

例如用户点击道路:

用户点击
    ↓
Vector Tile Feature
    ↓
获取Properties
    ↓
显示信息

例如:

name = 北京路
type = primary
length = 1250

可以显示:

道路名称:北京路
道路类型:主干道

这比单纯点击Raster图片更加灵活。

Vector Tile与空间查询

Vector Tile中的数据可以作为:

地图显示数据

但需要注意:

Vector Tile主要用于地图数据的分块传输和渲染,并不等于完整的空间数据库。

如果需要复杂空间分析:

Intersection
Buffer
Distance
Spatial Join

通常应该在:

GIS数据库
空间服务
后端

进行处理。

Vector Tile主要负责:

数据分发
 ↓
客户端地图渲染

Vector Tile服务器

一个典型的Vector Tile系统可以表示为:

GIS Database
      ↓
Tile Server
      ↓
Vector Tile
      ↓
HTTP
      ↓
Web Browser
      ↓
Map Renderer

例如:

PostGIS
   ↓
Tile Generation
   ↓
MVT
   ↓
.pbf
   ↓
WebGIS

Vector Tile生成流程

从原始GIS数据生成Vector Tile:

Shapefile
GeoPackage
PostGIS
GeoJSON
    ↓
数据处理
    ↓
坐标转换
    ↓
Geometry简化
    ↓
Tile裁剪
    ↓
Tile坐标转换
    ↓
编码
    ↓
MVT

最终得到:

z/x/y.pbf

Vector Tile客户端流程

浏览器端:

地图初始化
    ↓
获取Viewport
    ↓
确定Zoom
    ↓
计算Tile
    ↓
请求.pbf
    ↓
解码MVT
    ↓
读取Layer
    ↓
读取Feature
    ↓
读取Geometry
    ↓
应用Style
    ↓
GPU渲染

这就是现代WebGIS矢量地图的基本流程。

Vector Tile的优点

1. 数据量小

二进制编码和Geometry简化可以减少:

网络传输

2. 按需加载

只加载:

当前Viewport

附近的Tile。

3. 样式灵活

数据和样式分离:

Data
+
Style

4. 交互能力强

可以直接针对:

Feature

进行交互。

5. 适合大规模地图

非常适合:

道路
建筑
行政区
POI
土地利用

等大量数据。

6. 支持动态样式

同一份Vector Tile可以实现:

白天地图
夜间地图
卫星风格
灰色地图
高对比度地图

而无需重新生成底图数据。

Vector Tile的缺点

1. 实现复杂

相比Raster Tile:

Raster
    ↓
图片
    ↓
直接显示

Vector Tile需要:

解码
 ↓
Geometry解析
 ↓
样式计算
 ↓
渲染

2. 客户端计算压力

大量Vector Tile会增加:

CPU
GPU
内存

压力。

3. 不适合所有数据

例如:

卫星影像
航空影像
连续栅格数据

更适合使用Raster Tile。

4. 数据不是原始Geometry

Vector Tile中的Geometry通常经过:

裁剪
简化
编码

因此不能简单认为:

Vector Tile = 原始GIS数据

Vector Tile与GeoPackage

GeoPackage:

.gpkg

通常用于:

GIS数据存储
数据交换
离线数据

Vector Tile:

.pbf

更偏向:

网络传输
地图瓦片
按需加载

可以理解为:

GeoPackage
    ↓
存储GIS数据

Vector Tile
    ↓
分发GIS地图数据

Vector Tile与Shapefile

Shapefile:

.shp
.shx
.dbf
.prj

通常用于:

传统GIS数据交换

Vector Tile:

.pbf

通常用于:

Web地图

一个常见的数据流程:

Shapefile
    ↓
GIS数据处理
    ↓
Tile生成
    ↓
Vector Tile
    ↓
WebGIS

Vector Tile与GeoJSON的典型关系

可以这样理解:

GeoJSON
    ↓
完整矢量数据

而:

Vector Tile
    ↓
切片后的矢量数据

例如:

城市道路GeoJSON
        ↓
     Tile切分
        ↓
┌──────┬──────┬──────┐
│Tile A│Tile B│Tile C│
└──────┴──────┴──────┘

每个Tile保存自己空间范围内的道路数据。

Vector Tile知识结构

可以将Vector Tile理解为:

Vector Tile
├── Tile
│   ├── z
│   ├── x
│   └── y
│
├── Layer
│
├── Feature
│
├── Geometry
│
├── Properties
│
├── Extent
│
├── Tile Coordinate
│
└── MVT / PBF

核心流程:

GIS Data
    ↓
Tile
    ↓
Layer
    ↓
Feature
    ↓
Geometry
    ↓
MVT
    ↓
PBF
    ↓
WebGIS

一个完整的Vector Tile地图架构

可以用下面的结构理解:

                 GIS Database
                       ↓
                Spatial Query
                       ↓
              Geometry Processing
                       ↓
          ┌────────────┼────────────┐
          ↓            ↓            ↓
       Clip         Simplify     Transform
          └────────────┼────────────┘
                       ↓
                    MVT
                       ↓
                    PBF
                       ↓
                 Tile Server
                       ↓
                    HTTP
                       ↓
                  Browser
                       ↓
                Vector Tile Parser
                       ↓
                    Layer
                       ↓
                   Feature
                       ↓
                  Geometry
                       ↓
                    Style
                       ↓
                 GPU Rendering

Vector Tile与空间索引

Vector Tile本身就是一种空间分块思想。

可以理解为:

整个世界
    ↓
Zoom
    ↓
Tile Grid
    ↓
Tile
    ↓
Feature

因此它和空间索引有天然联系。

例如:

QuadTree
    ↓
空间递归划分

而:

Vector Tile
    ↓
地图规则网格划分

两者都可以减少:

一次需要处理的数据量

Vector Tile与QuadTree

两者都具有层级空间结构:

QuadTree
    ↓
递归四分

Vector Tile:

Zoom
    ↓
Tile Grid
    ↓
2^z × 2^z

可以简单理解为:

QuadTree
    ↓
空间索引思想

Vector Tile
    ↓
空间分块和数据分发

现代地图瓦片体系与四叉树空间层级在思想上存在密切关系。

Vector Tile与地图性能

如果没有Vector Tile:

整个城市
    ↓
全部数据
    ↓
浏览器

使用Vector Tile:

整个城市
    ↓
Tile
Tile
Tile
Tile
...
    ↓
Viewport
    ↓
只加载需要Tile

因此可以减少:

网络数据
解析数据
内存占用
渲染对象

从而提升地图交互体验。

Vector Tile与缓存

Tile天然适合缓存。

例如:

z/x/y.pbf

同一个Tile可能被大量用户请求。

可以使用:

Browser Cache
CDN
Reverse Proxy
Server Cache

缓存Vector Tile。

流程:

用户请求
    ↓
CDN
    ↓
命中缓存?
  ↙      ↘
是        否
↓          ↓
返回      Tile Server
             ↓
           MVT
             ↓
           缓存

因此Vector Tile非常适合CDN分发。

Vector Tile与动态数据

对于实时车辆:

车辆A
车辆B
车辆C

也可以使用Vector Tile思想进行空间分块。

例如:

车辆数据
    ↓
按空间区域分组
    ↓
Tile
    ↓
只更新变化区域

但对于高频实时数据,也可能采用:

WebSocket
WebRTC
实时API

等其他方式。

因此Vector Tile更适合:

大规模空间数据
相对稳定的数据
地图底图

而不是所有实时数据。

Vector Tile的典型应用

Vector Tile非常适合:

道路地图
建筑地图
行政区地图
土地利用
POI
城市地图
全国地图
全球地图

例如:

全国道路
    ↓
Vector Tile
    ↓
Web地图

或者:

城市建筑
    ↓
Vector Tile
    ↓
3D / 2D地图

总结

Vector Tile(矢量瓦片)是一种将大量矢量GIS数据按照地图瓦片进行空间切分、编码和按需传输的技术。

它的核心结构是:

Map
 ↓
Zoom
 ↓
Tile
 ↓
Layer
 ↓
Feature
 ↓
Geometry

常见格式:

MVT
 ↓
Protocol Buffers
 ↓
.pbf

典型的数据流程:

GIS数据
    ↓
坐标转换
    ↓
Geometry简化
    ↓
Tile裁剪
    ↓
Tile坐标转换
    ↓
MVT编码
    ↓
PBF
    ↓
WebGIS
    ↓
地图渲染

Vector Tile与GeoJSON的核心区别可以记住:

GeoJSON更适合表达和交换完整矢量数据,Vector Tile更适合将大规模矢量数据切成地图瓦片后进行网络传输和高性能地图渲染。

Vector Tile与Raster Tile的区别可以记住:

Raster Tile保存像素图片,Vector Tile保存矢量Geometry和属性数据。

Vector Tile与QuadTree的关系可以记住:

QuadTree主要解决空间层级索引问题,而Vector Tile主要解决大规模矢量地图的空间分块、按需加载和网络分发问题。

最终可以把现代WebGIS地图理解为:

GIS Database
      ↓
Spatial Processing
      ↓
Vector Tile
      ↓
MVT / PBF
      ↓
Tile Server / CDN
      ↓
WebGIS
      ↓
Layer
      ↓
Feature
      ↓
Geometry
      ↓
Style
      ↓
GPU
      ↓
地图
🧰

相关工具

使用 IYATools 在线工具快速处理 GIS 数据