meface/docs/article/gis/openlayers/33vectortiles.md

137 lines
5.0 KiB
Markdown
Raw Normal View History

2023-11-17 10:54:23 +08:00
---
title: 矢量瓦片
date: 2020-10-20
author: ac
tags:
- Vector Tiles
- OpenLayers
categories:
- GIS
---
> Vector Tiles 是一种输出格式,而不是数据源
## 1. 矢量瓦片
### 1.1 矢量瓦片是什么?
顾名思义矢量瓦片包含的是几何信息geometry和元数据attributes**是一种轻量级的紧凑型结构化的用于存储地理空间矢量数据的【数据格式】**。
### 1.2 格式与编码规则
**格式**
矢量瓦片使用[Google Protobufs](https://github.com/google/protobuf) (PBF)数据转换格式(用于序列化结构化数据)对矢量数据进行编码,生成以`.mvt`为后缀的文件。使用`Mapnik`或`Node Mapnik`之类的工具可以将单个矢量图块快速编码为`.mvt`格式([Mapbox Vector Tile format](https://docs.mapbox.com/vector-tiles/reference/))。
**编码规则**
几何属性的编码规则:
1. 数据必须为地理坐标矢量瓦片没有地理信息的概念geographic information
2. 以自右向下顺时针的方式将点、线和多边形编码为相对于网格左上角的x/y坐标对。即将地理坐标信息转换为相对于图块的非地理矢量网格坐标non-geographic vector grid coordinates
![vectorformat1](./images/vectorformat1.png)![vectorformat2](./images/vectorformat2.png)
### 1.3 优点缺点
矢量图块Vector Tiles的优点是
- **渲染是由客户端**(例如`OpenLayers`)完成的,而不是由服务器完成的。这允许不同的地图/应用程序以不同的方式设置地图样式,而不必重新配置`GeoServer`。
- **向量图块的大小通常小于**图像图块,从而导致更快的数据传输和更低的带宽使用率。
- `GeoServer`内嵌的`GeoWebCache`有效地存储了矢量切片数据。由于样式是由客户端而不是服务器完成的,因此`GeoWebCache`**仅需要为所有不同的样式存储一个图块**。
- 由于矢量数据在客户端上可用,**因此可以绘制**非常**高分辨率的地图,而不会相应增加带宽**。
- **客户端可以本地访问实际的特征信息**(属性和几何形状),从而可以进行非常复杂的渲染。
它主要缺点是,可能需要对地理数据进行预处理,以使客户可以进行所需的绘图(类似于对图像地图进行预处理的数据)。考虑到这一点,**矢量 tiles更适用于渲染**。
## 2. GeoServer中的矢量瓦片
`GeoServer`除了支持标准的image tiles输出格式外还支持`vector tiles`的输出格式。
标准WMS将生成具有地理参考的地图图像作为输出而`vector tiles`矢量瓦片是输出包含地理参考的矢量数据,这些数据被裁剪成图块以便于检索。
> GeoServer还可以输出三种格式的矢量切片GeoJSONTopoJSON和MapBox VectorMVT
`GeoServer`默认不支持Vector Tiles输出格式需要添加[Vector Tiles](http://sourceforge.net/projects/geoserver/files/GeoServer/2.18.2/extensions/geoserver-2.18.2-vectortiles-plugin.zip)扩展。
在需要输出Vector Tiles格式的矢量图层中勾选矢量输出格式
<img src="./images/image-20210426175433007.png" alt="image-20210426175433007" style="zoom:50%;" />
加载`GeoServer`中输出的矢量瓦片,示例:
![image-20210426180051627](./images/image-20210426180051627.png)
```html
<!DOCTYPE html -->
<html>
<head>
<title>Vector tiles</title>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/build/ol.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/css/ol.css">
<style>
html, body {
font-family: sans-serif;
width: 100%;
}
.map {
height: 500px;
width: 100%;
}
</style>
</head>
<body>
<h3>Mapbox Protobuf - vector tiles</h3>
<div id="map" class="map"></div>
<script>
var style_simple = new ol.style.Style({
fill: new ol.style.Fill({
color: '#ADD8E6'
}),
stroke: new ol.style.Stroke({
color: '#880000',
width: 1
})
});
function simpleStyle(feature) {
return style_simple;
}
var layer = 'nyc:ne_110m_countries';
var projection_epsg_no = '900913';
var map = new ol.Map({
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 2
}),
layers: [
new ol.layer.VectorTile({
style:simpleStyle,
source: new ol.source.VectorTile({
tilePixelRatio: 1, // oversampling when > 1
tileGrid: ol.tilegrid.createXYZ({maxZoom: 19}),
format: new ol.format.MVT(),
url: 'http://localhost:8080/geoserver/gwc/service/tms/1.0.0/' + layer +
'@EPSG%3A'+projection_epsg_no+'@pbf/{z}/{x}/{-y}.pbf'
})
})]
});
</script>
</body>
</html>
```
> 加载矢量切片时建议使用最新的ol。较旧的ol不支持所有矢量切片功能并且可能导致渲染错误。
## 参考文章
[1] Vector tiles `https://docs.mapbox.com/vector-tiles/reference/`
[2] Specification `https://docs.mapbox.com/vector-tiles/specification/`