The VectorTile layer

We now know how to load tiled images, and we have seen different ways to load and render vector data. But what if we could have tiles that are fast to transfer to the browser, and can be styled on the fly? Well, this is what vector tiles were made for. OpenLayers supports vector tiles through the VectorTile layer.

A world map rendered from vector data

We'll start with the same markup in index.html as in the Basics exercise.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>OpenLayers</title>
    <style>
      html, body, #map-container {
        margin: 0;
        height: 100%;
        width: 100%;
        font-family: sans-serif;
      }
    </style>
  </head>
  <body>
    <div id="map-container"></div>
  </body>
</html>

As usual, we save index.html in the root of our workshop folder.

For the application, we'll start with a fresh main.js in the root of the workshop folder, and add the required imports:

import 'ol/ol.css';
import {Map, View} from 'ol';
import MVT from 'ol/format/MVT';
import VectorTileLayer from 'ol/layer/VectorTile';
import VectorTileSource from 'ol/source/VectorTile';
import {fromLonLat} from 'ol/proj';

The data source we are going to use is street map data from OpenStreetMap. The provider of the tiles grants free access for demonstration purposes, but requires an access key. Please read the terms at https://openmaptiles.com/hosting/, where you can also get your own key. The code below assigns the key to a constant we're going to use later:

// See https://openmaptiles.com/hosting/ for terms and API key
const key = 'lirfd6Fegsjkvs0lshxe'; // use your own instead

The map we're going to create here is the same that we have used in previous exercises, but we'll center it on San Diego and zoom in a bit more:

const map = new Map({
  target: 'map-container',
  view: new View({
    center: fromLonLat([-117.1625, 32.715]),
    zoom: 6
  })
});

The layer type we are going to use now is VectorTileLayer, with a VectorTileSource:

const layer = new VectorTileLayer({
  source: new VectorTileSource({
    attributions: [
      '<a href="http://www.openmaptiles.org/" target="_blank">&copy; OpenMapTiles</a>',
      '<a href="http://www.openstreetmap.org/about/" target="_blank">&copy; OpenStreetMap contributors</a>'
    ],
    format: new MVT(),
    url: `https://free-{1-3}.tilehosting.com/data/v3/{z}/{x}/{y}.pbf.pict?key=${key}`,
    maxZoom: 14
  })
});
map.addLayer(layer);

Our data source provides only zoom levels 0 to 14, so we need to pass this information to the source. Vector tile layers are usually optimized for a tile size of 512 pixels, which is also the default for the VectorTile source's tile grid. The data provider requires us to display some attributions, which we are adding to the source configuration as well.

As you can see, a VectorTileSource is configured with a format and a url, just like a VectorSource. The MVT format parses Mapbox Vector Tiles. Like with raster tiles, the tile data is accessed by zoom level and x and y coordinates of the tile. Therefore, the URL includes a {z} placeholder for the zoom level, and {x} and {y} placeholders for the tile coordinates.

The working example at http://localhost:3000/ shows an unstyled vector tile map like this:

A world map without style, centered on San Diego
A world map without style, centered on San Diego

results matching ""

    No results matching ""