Vector tiles with MVT
Quick answer
This tutorial loads Mapbox Vector Tiles through ol.format.MVT and ol.source.VectorTile and explains how they differ from whole-file vector layers. It restricts parsing with the layers option, styles features by resolution, splits source layers into separate layers sharing one tile URL, and builds signed URLs with tileUrlFunction while flipping the y coordinate. Readers can render million-scale datasets and avoid clipped-geometry and naming traps.
Key points
- Set layers on ol.format.MVT to the source layer name found inside the .pbf.
- Flip the internal y with -tileCoord[2] - 1 when building XYZ tile URLs.
- Use the resolution argument in the style function to keep stroke widths readable.
Example
var parcels = new ol.layer.VectorTile({
source: new ol.source.VectorTile({
format: new ol.format.MVT({
layers: ['parcels'], // 只解析 parcels 这个源图层
featureClass: ol.Feature
}),
url: 'https://tiles.example.com/parcels/{z}/{x}/{y}.pbf',
maxZoom: 16,
projection: 'EPSG:3857'
}),
declutter: false,
style: function (feature, resolution) {
var usage = feature.get('usage');
var color = usage === 'residential' ? '#1f5fd0' : '#d0453a';
return new ol.style.Style({
stroke: new ol.style.Stroke({ color: color, width: resolution < 4 ? 1.5 : 1 }),
fill: new ol.style.Fill({
color: usage === 'residential' ? 'rgba(31, 95, 208, 0.18)' : 'rgba(208, 69, 58, 0.18)'
})
});
}
});
map.addLayer(parcels);function makeTileLayer(sourceLayer, styleFn, zIndex) {
return new ol.layer.VectorTile({
source: new ol.source.VectorTile({
format: new ol.format.MVT({ layers: [sourceLayer] }),
url: 'https://tiles.example.com/base/{z}/{x}/{y}.pbf',
maxZoom: 16
}),
style: styleFn,
zIndex: zIndex
});
}
var roads = makeTileLayer('roads', function (feature) {
return new ol.style.Style({
stroke: new ol.style.Stroke({ color: '#f5f7fa', width: 3 })
});
}, 10);
var labels = makeTileLayer('labels', function (feature) {
return new ol.style.Style({
text: new ol.style.Text({
text: feature.get('name'),
font: '500 12px sans-serif',
fill: new ol.style.Fill({ color: '#16181d' }),
stroke: new ol.style.Stroke({ color: '#fff', width: 3 })
})
});
}, 20);
map.addLayer(roads);
map.addLayer(labels);
Notes
- Features crossing tile boundaries are clipped, so area and adjacency stats are unreliable.
- An empty or misspelled layers name renders nothing and logs no error.
English edition written for Atlaslog. Code is taken from the original Chinese page and runs unchanged.
Atlaslog (2026). Vector tiles with MVT. https://www.jingweizhi.com/en/openlayers/tutorials/vector-tiles.html (accessed 2026-11-03).