leaflet-vector-tile-layer

0.16.0 • Public • Published

Leaflet.VectorTileLayer

This module provides a Leaflet layer that displays vector tiles. It is very similar to Leaflet.VectorGrid.

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 like

https://{s}.example.com/tiles/{z}/{x}/{y}.pbf

The URL template also supports the undocumented {-y} option for »inverted Y« if the map's coordinate reference system 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 to VectorGrid 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 and provides the following:

  • a bbox() function that returns the feature's bounding box in SVG coordinate units.
  • a graphics property that holds the top-level SVG DOM element.
  • a setStyle(style) function that takes a style object and applies it to the generated SVG elements.

VectorTileLayer supports all options provided by GridLayer. 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, L.Polyline or L.Polygon, as appropriate.

Style options

Style options are interpreted by the individual feature layers. For points, these are L.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). This function 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 a layer object that visualises a vector-tile point feature.

  • featureIconLayer(feature, layerName, pxPerExtent, options) returns a layer object that visualises a vector-tile point feature using the Leaflet.Icon specified by options.icon.

  • featurePathLayer(feature, layerName, pxPerExtent, options) returns a layer object to visualise a vector-tile line or polygon feature.

  • featureLayerBase(feature, layerName, pxPerExtent, options) can be used to create a layer object for a vector-tile feature. It returns an object that eventually delegates to a Leaflet.Layer 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 object in style.icon to the SVG <image> element.
  • applyPathStyle(element, style) applies Leaflet.Path style properties to the SVG <path> element.

Feature layer example

The featureToLayer 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-tile feature 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 in protobuf format are supported, but support for other renderers or formats may be added through options in the future.

Readme

Keywords

Package Sidebar

Install

npm i leaflet-vector-tile-layer

Weekly Downloads

1,892

Version

0.16.0

License

BSD-3-Clause

Unpacked Size

675 kB

Total Files

12

Last publish

Collaborators

  • jkuebart