16 |
17 |
Leaflet.VectorGrid API reference
18 |
35 |
36 |
VectorGrid.Slicer
A VectorGrid
for slicing up big GeoJSON or TopoJSON documents in vector
37 | tiles, leveraging geojson-vt
.
38 |
39 |
40 | Usage example
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | var geoJsonDocument = {
49 | type: 'FeatureCollection',
50 | features: [ ... ]
51 | };
52 | L.vectorGrid.slicer(geoJsonDocument, {
53 | vectorTileLayerStyles: {
54 | sliced: { ... }
55 | }
56 | }).addTo(map);
57 |
VectorGrid.Slicer
can also handle TopoJSON transparently:
58 | var layer = L.vectorGrid.slicer(topojson, options);
59 |
60 | The TopoJSON format implicitly groups features into "objects".
61 | These will be transformed into vector tile layer names when styling (the
62 | vectorTileLayerName
option is ignored when using TopoJSON).
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | Options
71 |
72 |
73 |
74 |
75 |
76 |
78 |
79 |
80 |
81 | Option |
82 | Type |
83 | Default |
84 | Description |
85 |
86 |
87 |
88 | vectorTileLayerName |
89 | String
90 | | 'sliced' |
91 | Vector tiles contain a set of data layers, and those data layers
92 | contain features. Thus, the slicer creates one data layer, with
93 | the name given in this option. This is important for symbolizing the data. |
94 |
95 |
96 |
97 |
98 |
99 |
100 | VectorGrid
A VectorGrid
is a generic, abstract class for displaying tiled vector data.
101 | it provides facilities for symbolizing and rendering the data in the vector
102 | tiles, but lacks the functionality to fetch the vector tiles from wherever
103 | they are.
104 | Extends Leaflet's L.GridLayer
.
105 |
106 |
107 | Options
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 | Option |
117 | Type |
118 | Default |
119 | Description |
120 |
121 |
122 |
123 | rendererFactory |
124 |
125 | | L.svg.tile |
126 | A factory method which will be used to instantiate the per-tile renderers. |
127 |
128 |
129 | vectorTileLayerStyles |
130 | Object
131 | | {} |
132 | A data structure holding initial symbolizer definitions for the vector features. |
133 |
134 |
135 | interactive |
136 | Boolean
137 | | false |
138 | Whether this VectorGrid fires Interactive Layer events. |
139 |
140 |
141 | getFeatureId |
142 | Function
143 | | undefined |
144 | A function that, given a vector feature, returns an unique identifier for it, e.g.
145 | function(feat) { return feat.properties.uniqueIdField; } .
146 | Must be defined for setFeatureStyle to work. |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 | Methods
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 | Method |
164 | Returns |
165 | Description |
166 |
167 |
168 |
169 | setFeatureStyle(<Number> id, <L.Path Options> layerStyle) |
170 | this |
171 | Given the unique ID for a vector features (as per the getFeatureId option),
172 | re-symbolizes that feature across all tiles it appears in.
173 | Reverts the effects of a previous setFeatureStyle call.
174 | |
175 |
176 |
177 | getDataLayerNames() |
178 | Array |
179 | Returns an array of strings, with all the known names of data layers in
180 | the vector tiles displayed. Useful for introspection.
181 | |
182 |
183 |
184 |
185 |
186 |
187 | Extension methods
188 |
189 |
190 |
191 |
192 |
193 | Method |
194 | Returns |
195 | Description |
196 |
197 |
198 |
199 | getVectorTilePromise(<Object> coords) |
200 | Promise |
201 | Given a coords object in the form of {x: Number, y: Number, z: Number} ,
202 | this function must return a Promise for a vector tile.
203 | |
204 |
205 |
206 |
207 |
208 |
209 |
210 | FillSymbolizer
A symbolizer for filled areas. Applies only to polygon features.
211 |
212 |
VectorGrid.Protobuf
A VectorGrid
for vector tiles fetched from the internet.
213 | Tiles are supposed to be protobufs (AKA "protobuffer" or "Protocol Buffers"),
214 | containing data which complies with the
215 | MapBox Vector Tile Specification.
216 | This is the format used by:
217 |
223 |
224 |
225 | Usage example
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 | You must initialize a VectorGrid.Protobuf
with a URL template, just like in
234 | L.TileLayer
s. The difference is that the template must point to vector tiles
235 | (usually .pbf
or .mvt
) instead of raster (.png
or .jpg
) tiles, and that
236 | you should define the styling for all the features.
237 |
238 | For OpenMapTiles, with a key from https://openmaptiles.org/docs/host/use-cdn/,
239 | initialization looks like this:
240 | L.vectorGrid.protobuf("https://free-{s}.tilehosting.com/data/v3/{z}/{x}/{y}.pbf.pict?key={key}", {
241 | vectorTileLayerStyles: { ... },
242 | subdomains: "0123",
243 | key: 'abcdefghi01234567890',
244 | maxNativeZoom: 14
245 | }).addTo(map);
246 |
And for Mapbox vector tiles, it looks like this:
247 | L.vectorGrid.protobuf("https://{s}.tiles.mapbox.com/v4/mapbox.mapbox-streets-v6/{z}/{x}/{y}.vector.pbf?access_token={token}", {
248 | vectorTileLayerStyles: { ... },
249 | subdomains: "abcd",
250 | token: "pk.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRTS.TUVWXTZ0123456789abcde"
251 | }).addTo(map);
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 | Creation
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 | Factory |
269 | Description |
270 |
271 |
272 |
273 | L.vectorGrid.protobuf(<String> url, options) |
274 | Instantiates a new protobuf VectorGrid with the given URL template and options |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 | Options
283 |
284 |
285 |
286 |
287 |
288 |
291 |
292 |
293 |
294 | Option |
295 | Type |
296 | Default |
297 | Description |
298 |
299 |
300 |
301 | subdomains |
302 | String
303 | | 'abc' |
304 | Akin to the subdomains option for L.TileLayer . |
305 |
306 |
307 |
308 |
309 |
310 |
311 | LineSymbolizer
A symbolizer for lines. Can be applied to line and polygon features.
312 |
313 |
PointSymbolizer
A symbolizer for points.
314 |
315 |
Symbolizer
The abstract Symbolizer class is mostly equivalent in concept to a L.Path
- it's an interface for
316 | polylines, polygons and circles. But instead of representing leaflet Layers,
317 | it represents things that have to be drawn inside a vector tile.
318 |
319 |
320 | Methods
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 | Method |
330 | Returns |
331 | Description |
332 |
333 |
334 |
335 | initialize(<GeoJSON> feature, <Number> pxPerExtent) |
336 |
|
337 | Initializes a new Line Symbolizer given a GeoJSON feature and the
338 | pixel-to-coordinate-units ratio. Internal use only.
339 | |
340 |
341 |
342 | render(renderer, style) |
343 |
|
344 | Renders this symbolizer in the given tiled renderer, with the given
345 | L.Path options. Internal use only.
346 | Updates the L.Path options used to style this symbolizer, and re-renders it.
347 | Internal use only.
348 | |
349 |
350 |
351 |
352 |
353 |
354 |
355 | Styling VectorGrids
Vector tiles have a concept of "layer" different from the Leaflet concept of "layer".
356 |
357 | In Leaflet, a "layer" is something that can be atomically added or removed from the map. In vector tiles, a "layer" is a named set of features (points, lines or polygons) which share a common theme.
358 |
359 | A vector tile layer¹ can have several layers². In the mapbox-streets-v6
vector tiles layer¹ above, there are named layers² like admin
, water
or roads
.
360 |
361 | (¹ In Leaflet)
362 |
363 | (² Groups of themed features)
364 |
365 | Styling is done via per-layer² sets of L.Path
options in the vectorTileLayerStyles
layer¹ option:
366 |
var vectorTileOptions = {
367 | vectorTileLayerStyles: {
368 | // A plain set of L.Path options.
369 | landuse: {
370 | weight: 0,
371 | fillColor: '#9bc2c4',
372 | fillOpacity: 1,
373 | fill: true
374 | },
375 | // A function for styling features dynamically, depending on their
376 | // properties and the map's zoom level
377 | admin: function(properties, zoom) {
378 | var level = properties.admin_level;
379 | var weight = 1;
380 | if (level == 2) {weight = 4;}
381 | return {
382 | weight: weight,
383 | color: '#cf52d3',
384 | dashArray: '2, 6',
385 | fillOpacity: 0
386 | }
387 | },
388 | // A function for styling features dynamically, depending on their
389 | // properties, the map's zoom level, and the layer's geometry
390 | // dimension (point, line, polygon)
391 | water: function(properties, zoom, geometryDimension) {
392 | if (geometryDimension === 1) { // point
393 | return ({
394 | radius: 5,
395 | color: '#cf52d3',
396 | });
397 | }
398 |
399 | if (geometryDimension === 2) { // line
400 | return ({
401 | weight: 1,
402 | color: '#cf52d3',
403 | dashArray: '2, 6',
404 | fillOpacity: 0
405 | });
406 | }
407 |
408 | if (geometryDimension === 3) { // polygon
409 | return ({
410 | weight: 1,
411 | fillColor: '#9bc2c4',
412 | fillOpacity: 1,
413 | fill: true
414 | });
415 | }
416 | },
417 | // An 'icon' option means that a L.Icon will be used
418 | place: {
419 | icon: new L.Icon.Default()
420 | },
421 | road: []
422 | }
423 | };
424 | var pbfLayer = L.vectorGrid.protobuf(url, vectorTileOptions).addTo(map);
425 |
426 |
A layer² style can be either:
427 |
428 | - A set of
L.Path
options
429 | - An array of sets of
L.Path
options
430 | - A function that returns a set of
L.Path
options
431 | - A function that returns an array of sets of
L.Path
options for point, line, and polygon styles respectively
432 |
433 | Layers² with no style specified will use the default L.Path
options.
434 |
435 | Polylines and polygons can be styled exactly like normal Leaflet L.Path
s, points can be styled like polygons using L.CircleMarker
s or L.Icon
s.
436 |
437 |
438 |
Updating Styles
In some cases it can be desirable to change the style of a feature on screen, for example for highlighting when a feature is clicked.
439 |
440 | To do this, VectorGrid needs to know how to identify a feature. This is done through the getFeatureId
option, which should be set to a function
441 | that returns an id given a feature as argument. For example:
442 |
var vectorGrid = L.vectorGrid.slicer(url, {
443 | ...
444 | getFeatureId: function(f) {
445 | return f.properties.osm_id;
446 | }
447 | }
448 |
449 |
Note that features with the same id will be treated as one when changing style, this happens normally when for example a polygon spans more than one tile.
450 |
451 | To update the style of a feature, use setFeatureStyle
:
452 |
vectorGrid.setFeatureStyle(id, style);
453 |
454 |
The styling follows the same rules as described above, it accepts a single style, an array, or a function that returns styling.
455 |
456 | To revert the style to the layer's default, use the resetFeatureStyle
method:
457 |
vectorGrid.resetFeatureStyle(id);
458 |
459 |
460 |
Interactivity
You can enable interacting (click, mouseover, etc.) with layer features if you pass the option interactive: true
; you can then add listeners to the VectorGrid layer. When
461 | an event fires, it will include the layer
property, containing information about the feature.
462 |
463 |
SVG vs canvas
Leaflet.VectorGrid is able to render vector tiles with both SVG and <canvas>
, in the same way that vanilla Leaflet can use SVG and <canvas>
to draw lines and polygons.
464 |
465 | To switch between the two, use the rendererFactory
option for any L.VectorGrid
layer, e.g.:
466 |
var sliced = L.vectorGrid.slicer(geojson, {
467 | rendererFactory: L.svg.tile,
468 | attribution: 'Something',
469 | vectorTileLayerStyles: { ... }
470 | });
471 | var pbf = L.vectorGrid.protobuf(url, {
472 | rendererFactory: L.canvas.tile,
473 | attribution: 'Something',
474 | vectorTileLayerStyles: { ... }
475 | });
476 |
477 |
Internally, Leaflet.VectorGrid uses two classes named L.SVG.Tile
and L.Canvas.Tile
, with factory methods L.svg.tile
and L.canvas.tile
- a L.VectorGrid
needs to be passed one of those factory methods.
478 |
479 |
480 |
481 |
484 |
485 |
486 |
487 |
488 |
539 |
656 |
657 |
--------------------------------------------------------------------------------
/gobblefile.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | var gobble = require('gobble');
4 | var src = gobble('src');
5 |
6 |
7 | // Run rollup on the web worker code, in order to include GeoJSON-vt and TopoJSON into it.
8 | var concatenatedWebWorker = src.transform('rollup', {
9 | entry: 'slicerWebWorker.js',
10 | dest: 'slicerWebWorker.js.worker',
11 | format: 'cjs',
12 | sourceMap: true,
13 | plugins: [
14 | require('rollup-plugin-buble')({
15 | include: '**/**.js'
16 | }),
17 | require('rollup-plugin-node-resolve')({
18 | jsnext: false,
19 | main: true
20 | }),
21 | require('rollup-plugin-commonjs')(),
22 | // require('rollup-plugin-file-as-blob')({
23 | // include: '**/**.png'
24 | // }),
25 | ]
26 | });
27 |
28 | var uglifiedWebWorker = src.transform('rollup', {
29 | entry: 'slicerWebWorker.js',
30 | dest: 'slicerWebWorker.js.worker',
31 | format: 'cjs',
32 | sourceMap: false,
33 | plugins: [
34 | require('rollup-plugin-buble')({
35 | include: '**/**.js'
36 | }),
37 | require('rollup-plugin-node-resolve')({
38 | jsnext: false,
39 | main: true
40 | }),
41 | require('rollup-plugin-commonjs')(),
42 | require('rollup-plugin-uglify')()
43 | ]
44 | });
45 |
46 | // Get the rolled-up worker code back next to the same directory as the main code
47 | var src2 = gobble([src, concatenatedWebWorker]);
48 | var src2uglified = gobble([src, uglifiedWebWorker]);
49 |
50 |
51 | // We'll run rollup four times, with slightly different options and using different
52 | // source files (uglified worker or not). But the plugins stay the same.
53 | var rollupPluginOptions = [
54 | require('rollup-plugin-file-as-blob')({
55 | // Note the '.*' at the beginning of the minimatch, because
56 | // https://github.com/rollup/rollup-pluginutils/issues/9
57 | include: '.*/**/**.worker'
58 | }),
59 | require('rollup-plugin-buble')({
60 | include: '**/**.js'
61 | }),
62 | require('rollup-plugin-node-resolve')({
63 | jsnext: false,
64 | main: true
65 | }),
66 | require('rollup-plugin-commonjs')(),
67 | ];
68 |
69 | var rollupUglyPluginOptions = rollupPluginOptions.concat([require('rollup-plugin-uglify')()]);
70 |
71 | // Roll up the main code, merging the web worker code as a blob URL.
72 | var builtCode = src2.transform('rollup', {
73 | entry: 'bundle.js',
74 | dest: 'Leaflet.VectorGrid.js',
75 | format: 'cjs',
76 | sourceMap: true,
77 | plugins: rollupPluginOptions
78 | });
79 |
80 |
81 | // Roll up the main code plus the optional bundled deps, merging the web worker code as a blob URL.
82 | var bundledCode = src2.transform('rollup', {
83 | entry: 'bundle-extra.js',
84 | dest: 'Leaflet.VectorGrid.bundled.js',
85 | format: 'iife',
86 | sourceMap: true,
87 | plugins: rollupPluginOptions,
88 | globals: {
89 | Pbf: 'Pbf',
90 | VectorTile: 'vector-tile',
91 | }
92 | });
93 |
94 |
95 | var uglifiedCode = src2uglified.transform('rollup', {
96 | entry: 'bundle.js',
97 | dest: 'Leaflet.VectorGrid.min.js',
98 | format: 'cjs',
99 | sourceMap: false,
100 | plugins: rollupUglyPluginOptions
101 | });
102 |
103 |
104 | var uglifiedBundledCode = src2uglified.transform('rollup', {
105 | entry: 'bundle-extra.js',
106 | dest: 'Leaflet.VectorGrid.bundled.min.js',
107 | format: 'cjs',
108 | sourceMap: false,
109 | plugins: rollupUglyPluginOptions
110 | });
111 |
112 |
113 | var leafdoc = src.transform('leafdoc', {
114 | templateDir: 'leafdoc-templates',
115 | output: 'vectorgrid-api-docs.html',
116 | showInheritancesWhenEmpty: true,
117 |
118 | });
119 |
120 | // var leaflet = vendor.include([
121 | // 'leaflet-src.js',
122 | // 'leaflet-src.map',
123 | // 'leaflet.css'
124 | // ]).moveTo('demo');
125 |
126 |
127 | module.exports = gobble([
128 | builtCode, // No extra deps, no minified
129 | bundledCode, // Extra deps, no minified
130 | uglifiedCode, // No extra deps, minified
131 | uglifiedBundledCode, // Extra deps, minified
132 |
133 | // leaflet
134 | leafdoc
135 | ]);
136 |
--------------------------------------------------------------------------------
/leafdoc-templates/comments.hbs:
--------------------------------------------------------------------------------
1 | {{{rawmarkdown comments}}}
--------------------------------------------------------------------------------
/leafdoc-templates/constructor.hbs:
--------------------------------------------------------------------------------
1 |