Leaflet.VectorTileLayer
This module provides a LeafletL layer that displays vector tilesVT.
It is very similar to Leaflet.VectorGrid
LVG.The biggest difference to
VectorGrid
is the styling.
VectorTileLayer
also supports two options min/maxDetailZoom
which are
subtly different from VectorGrid
's min/maxNativeZoom
. Both provide the
possibility to specify a range of zoom levels that offer an optimal
trade-off between detail and size. When using the native
variants, tiles
above or below the zoom range are scaled, changing the stroke weight. The
detail
settings offer the same trade-off while still rendering the tiles
at the correct zoom levels, meaning stroke weight is visually consistent
across all zoom levels.Furthermore,
VectorTileLayer
gives clients full control over the SVG DOM
created for vector tile features. The layer option featureToLayer
accepts
a function that can return any graphics for visualising a given feature
while making it easy to fall back to the default implementation.In contrast to
VectorGrid
, this class has been designed as much as
possible in terms of Leaflet's public API. This makes it more likely to
continue working with future versions of Leaflet.Use
Loads vector tiles from a URL template likehttps://{s}.example.com/tiles/{z}/{x}/{y}.pbf
The URL template also supports the undocumented {-y}
option for
»inverted YY« if the map's coordinate reference systemCRS is finite
(the default).This pacakge can be used as an ES6 module.
import vectorTileLayer from 'leaflet-vector-tile-layer';
const tileLayer = vectorTileLayer(url, options);
The AMD build comes with all dependencies included. If imported as an ES6 module, the dependencies need to be made available to the build system, for example:
$ npm install @mapbox/vector-tile pbf
See this package's development dependencies for version information.
Layer options
The main difference toVectorGrid
is that VectorTileLayer
takes a
different approach to styling. Whereas VectorGrid
only supports styling a
previously known set of vector-tile layer names, this class allows
specifying a single style for all layers irrespective of their names. When
specifying a function, it is called with the vector-tile feature, the layer
name and the current zoom level, enabling clients can handle layer names
dynamically or ignore them altogether.Another feature not supported by
VectorGrid
is a setStyle()
call which
allows changing the style of the entire layer.For compatibility, support for the
vectorTileLayerStyles
option and
set/resetFeatureStyle()
method is also provided.VectorTileLayer
also supports ordering the layers based on their names
using an option like layers: ["a", "b", "c"]
.Another added feature of
VectorTileLayer
is a getBounds()
function.
After the load
event, it returns the bounds occupied by the features on
all currently loaded tiles.VectorTileLayer
allows clients to create their own DOM representation for
any given layer. A function provided to the featureToLayer
option takes a
vector-tile feature, the layer name, the number of SVG coordinate units per
vector-tile unit and the feature's style object. It should return an object
that eventually delegates to Leaflet.Layer
LYR and provides the
following:
- a bbox()
function that returns the feature's bounding box in SVGcoordinate units.
- a graphics
property that holds the top-level SVG DOM element.
- a setStyle(style)
function that takes a style object and applies itto the generated SVG elements.
VectorTileLayer
supports all options provided by GridLayer
GL.
Additionally, the following options are provided:const url = 'https://{s}.example.com/tiles/{z}/{x}/{y}.pbf';
const options = {
// A function that will be passed a vector-tile feature, the layer
// name, the number of SVG coordinate units per vector-tile unit
// and the feature's style object to create each feature layer.
featureToLayer, // default undefined
// Options passed to the `fetch` function when fetching a tile.
fetchOptions, // default undefined
// A function that will be used to decide whether to include a
// feature or not. If specified, it will be passed the vector-tile
// feature, the layer name and the zoom level. The default is to
// include all features.
filter, // default undefined
// A function that receives a list of vector-tile layer names and
// the zoom level and returns the names in the order in which they
// should be rendered, from bottom to top. The default is to render
// all layers as they appear in the tile.
layerOrder, // default undefined
// An array of vector-tile layer names from bottom to top. Layers
// that are missing from this list will not be rendered. The
// default is to render all layers as they appear in the tile.
layers, // default undefined
// Specify zoom range in which tiles are loaded. Tiles will be
// rendered from the same data for Zoom levels outside the range.
minDetailZoom, // default undefined
maxDetailZoom, // default undefined
// Either a single style object for all features on all layers or a
// function that receives the vector-tile feature, the layer name
// and the zoom level and returns the appropriate style options.
style, // default undefined
// This works like the same option for `Leaflet.VectorGrid`.
// Ignored if style is specified.
vectorTileLayerStyles, // default undefined
};
const layer = vectorTileLayer(url, options);
The style can be updated at any time using the
setStyle()
method.layer.setStyle({ weight: 3 });
All omitted options will be substituted by the default options for
L.CircleMarker
CM, L.Polyline
PL or L.Polygon
PG, as
appropriate.Style options
Style options are interpreted by the individual feature layers. For points, these areL.CircleMarker
options, or the icon
property supplies an
L.Icon
to determine the appearance. For polylines or polygons, these are
L.Path
options. If the options.style
property is a function, it will be
passed the vector-tile feature, the layer name and the zoom level as
parameters.If the style option
interactive
is true
, the created SVG elements will
listen to mouse events.The style option
hidden
permits any feature to be hidden. It operates by
setting the SVG attribute visibility
to hidden
.Feature layer helpers
A few functions are made available to simplify creating custom layers for individual features:-
defaultFeatureLayer(feature, layerName, pxPerExtent, options)
. Thisfunction is used if the `featureToLayer` option is unset. It takes the
vector-tile feature, the layer name, the number of SVG coordinate units
per vector-tile unit and a style object and returns an appropriate layer
object to visualise it.
- featureCircleLayer(feature, layerName, pxPerExtent, options)
returns alayer object that visualises a vector-tile point feature.
- featureIconLayer(feature, layerName, pxPerExtent, options)
returns alayer object that visualises a vector-tile point feature using the
[`Leaflet.Icon`][ICO] specified by `options.icon`.
- featurePathLayer(feature, layerName, pxPerExtent, options)
returns alayer object to visualise a vector-tile line or polygon feature.
- featureLayerBase(feature, layerName, pxPerExtent, options)
can be usedto create a layer object for a vector-tile feature. It returns an object
that eventually delegates to a [`Leaflet.Layer`][LYR] instantiated with
the given options. The delegating object must provide:
- a `graphics` property that holds the top-level SVG DOM element.
- a `setStyle(style)` method that applies the given style to the
layer's DOM after enhancing it with the feature layer's default
options.
Objects created by this function provide the following:
- An `applyOptions(style)` function that should be called by a
delegating object once the `graphics` property is initialised. It
applies the `style.className` option to it and then invokes
`setStyle({})` to allow the delegating object to apply its default
style.
- A `bbox()` function that returns the feature's bounding box in SVG
coordinate units and is used by `VectorTileLayer.getBounds()`.
- A `scalePoint(point)` function converts from vector-tile coordinates
to SVG coordinates.
A few functions are provided to simplify the implementation of
setStyle(style)
functions:-
applyBasicStyle(element, style)
applies the style.interactive
and`style.hidden` options to the given SVG DOM element.
- applyImageStyle(element, style)
applies the height
, width
and`href` proprties from the [`Leaflet.Icon`][ICO] object in `style.icon`
to the SVG `<image>` element.
- applyPathStyle(element, style)
applies Leaflet.Path
PT styleproperties to the SVG `<path>` element.
Feature layer example
ThefeatureToLayer
option on VectorTileLayer
accepts a function that
can render custom SVG elements depending on feature properties, options,
layer names and zoom level.Example drawing a thickened transparent overlay for polyline interaction:
import {SVG} from "leaflet";
import {defaultFeatureLayer, featureLayerBase} from "leaflet-vector-tile-layer";
function interactiveLinesLayer(feature, layerName, pxPerExtent, options) {
// Construct a base feature layer.
const self = featureLayerBase(feature, layerName, pxPerExtent, options);
// Compose this feature layer of two sub-layers, one for the visible
// line controlled by `options` and a second controlled by the path
// options contained in `options.interaction`. Both will share the same
// path geometry.
self.visibleLine = defaultFeatureLayer(
feature,
layerName,
pxPerExtent,
options
);
self.interactionLine = defaultFeatureLayer(
feature,
layerName,
pxPerExtent,
options.interaction
);
// Place the two layers in an SVG group.
const group = SVG.create("g");
group.appendChild(self.visibleLine.graphics);
group.appendChild(self.interactionLine.graphics);
self.graphics = group;
// Setting of style is delegated to the sub layers.
self.setStyle = function setStyle(style) {
self.visibleLine.setStyle(style);
self.interactionLine.setStyle(style.interaction);
};
// Initial setup of this feature layer.
self.applyOptions(options);
return self;
}
// Example options for the above custom renderer:
const interactiveLineOptions = {
color: "red",
weight: 2,
interaction: {
opacity: 0.0,
weight: 10
}
};
Events
Events attached to this layer provide access to the vector-tilefeature
and the layerName
through their layer
attribute. For compatibility with
VectorGrid
, the feature's properties
are also made directly available.Installing and building
You can install this package using$ npm install leaflet-vector-tile-layer
It can be built by
$ npm run build
Limitations
At this time, only SVG rendering and vector tiles inprotobuf
PBF
format are supported, but support for other renderers or formats may be
added through options in the future.