leaflet-vector-tile-layer

Leaflet layer for vector tiles

Downloads in past

Stats

StarsIssuesVersionUpdatedCreatedSize
leaflet-vector-tile-layer
0.16.06 months ago7 years agoMinified + gzip package size for leaflet-vector-tile-layer in KB

Readme

Leaflet.VectorTileLayer
This module provides a LeafletL layer that displays vector tilesVT. It is very similar to Leaflet.VectorGridLVG.
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 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 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.LayerLYR 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 GridLayerGL. 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.CircleMarkerCM, L.PolylinePL or L.PolygonPG, 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`][ICO] 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`][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.PathPT 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 protobufPBF format are supported, but support for other renderers or formats may be added through options in the future.