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

137 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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/`