2
2
< html lang ="en ">
3
3
< head >
4
4
< meta charset ='utf-8 '>
5
- < title > map-gl-utils 0.42.0 | Documentation</ title >
5
+ < title > map-gl-utils 0.42.1 | Documentation</ title >
6
6
< meta name ='description ' content ='Utility functions for Mapbox GL JS or Maplibre GL JS '>
7
7
< meta name ='viewport ' content ='width=device-width,initial-scale=1 '>
8
8
< link href ='assets/bass.css ' rel ='stylesheet '>
15
15
< div id ='split-left ' class ='overflow-auto fs0 height-viewport-100 '>
16
16
< div class ='py1 px2 '>
17
17
< h3 class ='mb0 no-anchor '> map-gl-utils</ h3 >
18
- < div class ='mb1 '> < code > 0.42.0 </ code > </ div >
18
+ < div class ='mb1 '> < code > 0.42.1 </ code > </ div >
19
19
< input
20
20
placeholder ='Filter '
21
21
id ='filter-input '
@@ -3129,13 +3129,39 @@ <h2>Major features:</h2>
3129
3129
</ ul >
3130
3130
< h2 > Usage</ h2 >
3131
3131
< p > To use without any build process:</ p >
3132
+ < pre > < code > <script src="https://unpkg.com/map-gl-utils"> </script>
3133
+ </ code > </ pre >
3132
3134
< p > then</ p >
3135
+ < pre > < code > U.init(map)
3136
+ </ code > </ pre >
3133
3137
< p > With Webpack etc:</ p >
3138
+ < pre > < code > const mapgl = require('maplibre-gl'); // or require('mapbox-gl');
3139
+ const map = new mapgl.Map({ ... });
3140
+
3141
+ // or:
3142
+ import U from 'map-gl-utils';
3143
+ U.init(map);
3144
+
3145
+ // A small number of methods (eg hoverPopup) require access to the maplibre-gl/mapbox-gl library itself, in order to instantiate other objects.
3146
+ require('map-gl-utils').init(map, mapgl);
3147
+ </ code > </ pre >
3134
3148
< p > The default distribution is an ES2015 module with no transpiling. If you experience any syntax issues (such as using older JavaScript versions), use the UMD bundle instead:</ p >
3149
+ < pre > < code > // Adds U property to map, containing these methods.
3150
+ require('map-gl-utils/umd').init(map);
3151
+ </ code > </ pre >
3135
3152
< p > If you want to use Flow types:</ p >
3153
+ < pre > < code > import type MapGlUtils from 'map-gl-utils/src/index'
3154
+ </ code > </ pre >
3136
3155
< h3 > Guide</ h3 >
3137
3156
< h2 > Working with layers</ h2 >
3138
3157
< p > The < code > props</ code > object passed when adding a layer can freely mix paint, layout and other properties. Property keys can be specified in camelCase or kebab-case:</ p >
3158
+ < pre > < code > map.U.addCircleLayer('trees-circle', 'trees', {
3159
+ circleColor: 'green', // paint property
3160
+ circleRadius: ['interpolate', ['zoom'], 12, 3, 15, 5], // paint property
3161
+ circleSortKey: ['get', 'tree-sort-key'], // layout property
3162
+ filter: ['!=', 'type', 'stump'], // other property
3163
+ });
3164
+ </ code > </ pre >
3139
3165
< p > Almost every method that works with existing layers (eg, < code > show()</ code > ) can work with multiple layers. There are four ways to specify the layer(s) you want to modify:</ p >
3140
3166
< ul >
3141
3167
< li > string: < code > map.U.show('trees-label'); map.U.show('trees-circle');</ code > </ li >
@@ -3145,12 +3171,228 @@ <h2>Working with layers</h2>
3145
3171
</ ul >
3146
3172
< h2 > Adding sources</ h2 >
3147
3173
< p > Methods that add sources return an object ("SourceBoundUtils" in this documentation) that can be chained to allow layers to be added to it:</ p >
3174
+ < pre > < code > map.U.addGeoJSONSource('properties')
3175
+ .addCircleLayer('properties-line', { lineWidth: 3 })
3176
+ .addSymbolLayer('properties-fill', { fillColor: 'hsla(30,30%,60%,0.5)' })
3177
+ </ code > </ pre >
3148
3178
< h3 > Adding and removing layers</ h3 >
3179
+ < pre > < code > // Conveniently add a line feature, mixing paint, layout and other properties.
3180
+ // Notice you can use camelCase for all property names.
3181
+ map.U.addLineLayer('mylines', 'mysource', {
3182
+ lineWidth: 3,
3183
+ lineCap: 'round',
3184
+ minzoom: 11
3185
+ });
3186
+
3187
+ // Also addFillLayer, addFillExtrusionLayer, addRasterLayer, addVideoLayer, addSymbolLayer, addHillshadeLayer, addHeatmapLayer
3188
+ map.U.addCircleLayer('mycircles', 'mysource', { circleStrokeColor: 'red' });
3189
+ // if the layer already exists, calling add*Layer simply updates any of the properties
3190
+ map.U.addCircleLayer('mycircles', 'mysource', { circleStrokeColor: 'red', circleRadius: 4, filter: ['==', 'type', 'active'});
3191
+
3192
+
3193
+ // and of course add the layer "before" another layer if needed:
3194
+ map.U.addLineLayer('mylayer', 'mysource', { lineColor: 'red' }, 'toplayer');
3195
+
3196
+ // removeLayer() doesn't throw errors if the layers don't exist
3197
+ map.U.removeLayer(['towns','town-labels']);
3198
+
3199
+ </ code > </ pre >
3149
3200
< h3 > Adding and removing sources</ h3 >
3201
+ < pre > < code > // Simpler way to create GeoJSON source:
3202
+ map.U.addGeoJSON('mysource', geojson);
3203
+
3204
+ // Or create a GeoJSON source with initially blank data. This is very convenient if you're loading
3205
+ // the data separately and will call .setData() later.
3206
+ map.U.addGeoJSON('mysource');
3207
+
3208
+ // Simpler ways to create a vector tile source:
3209
+ map.U.addVector('mysource', 'mapbox://foo.blah');
3210
+ map.U.addVector('mysource', 'https://example.com/tiles/{z}/{x}/{y}.pbf');
3211
+
3212
+ // Additional properties still work
3213
+ map.U.addVector('mysource', 'https://example.com/tiles/{z}/{x}/{y}.pbf', { maxzoom: 13 });
3214
+
3215
+ // There's also addRaster(), addRasterDem(), addImage(), addVideo()
3216
+ // Calling any of the add* functions simply updates the source definition if it exists already.
3217
+
3218
+ // Automatically removes any layers using these sources. Not an error if sources don't exist.
3219
+ map.U.removeSource(['buildings', 'roads']);
3220
+
3221
+ // You can also use the returned object to add layers conveniently:
3222
+ map.U.addGeoJSON('buildings', 'data/buildings.geojson')
3223
+ .addFillExtrusion('buildings-3d', {
3224
+ fillExtrusionHeight: 100,
3225
+ fillExtrusionColor: 'grey'
3226
+ }).addLineLayer('buildings-footprint', {
3227
+ lineColor: 'lightblue'
3228
+ });
3229
+
3230
+ // Replace the source on an existing layer. (Actually removes and re-adds it.)
3231
+ map.U.setLayerSource('buildings', 'newsource');
3232
+ map.U.setLayerSource(['buildings-3d', 'buildings-outline]', 'newsource', 'newsourcelayer');
3233
+
3234
+ // To change the source layer, pass a third argument, or null to clear it (if switching from vector tiles to geojson)
3235
+ map.U.setLayerSource('buildings', 'mylocalbuildings', null);
3236
+ </ code > </ pre >
3150
3237
< h3 > Setting properties and updating data</ h3 >
3238
+ < pre > < code > // Every property has a setXxx() form:
3239
+ map.U.setTextSize('mylayer', 12);
3240
+
3241
+ // And they all work on multiple layers at once:
3242
+ map.U.setLineWidth(['mylayer', 'mylayer-highlight'], 4);
3243
+ map.U.setLineOpacity(/^border-/, 0);
3244
+ map.U.setFillColor(layer => layer.source === 'farms', 'green');
3245
+
3246
+ // There's also a more familiar setProperty() form.
3247
+ map.U.setProperty('mylayer', 'line-width', 3);
3248
+ // Existing properties aren't touched
3249
+ map.U.setProperty('mylayer', {
3250
+ textSize: 12,
3251
+ textColor: 'red'
3252
+ });
3253
+
3254
+ // There's a `get...` version of every function, too.
3255
+ map.U.getFillColor('water')
3256
+
3257
+ // Simpler way to update source data:
3258
+ map.U.setData('mysource', data);
3259
+
3260
+ // you can leave out the data parameter to clear out a GeoJSON source:
3261
+ map.U.setData('mysource');
3262
+
3263
+ // Easier to remember way to turn layers on and off:
3264
+ map.U.show('mylayer');
3265
+ map.U.hide('mylayer');
3266
+ map.U.toggle(['mylayer', 'myotherlayer'], isVisible);
3267
+
3268
+ // To avoid name clashes such as with 'raster', you can use a longer form ending
3269
+ // with either ...Layer() or ...Source()
3270
+
3271
+ map.U.addRasterSource('myrastersource', { type: 'raster', url: 'mapbox://mapbox.satellite', tileSize: 256 });
3272
+ map.U.addRasterLayer('myrasterlayer', 'myrastersource', { rasterSaturation: 0.5 });
3273
+ </ code > </ pre >
3151
3274
< h3 > Hovering and clicking</ h3 >
3275
+ < pre > < code > // Use the mouse 'finger' cursor when hovering over this layer.
3276
+ map.U.hoverPointer('mylayer');
3277
+
3278
+ // If you pass several layers, it correctly handles moving from one layer to another
3279
+ // Use the mouse 'finger' cursor when hovering over this layer.
3280
+ map.U.hoverPointer(['regions-border', 'regions-fill']);
3281
+
3282
+ // Sets a "hover" feature-state to be true or false as the mouse moves over features in this layer.
3283
+ // Requires that features have an `id`.
3284
+ map.U.hoverFeatureState('mylayer');
3285
+
3286
+ // Want to apply the hover feature-state to a different source?
3287
+ // For instance, you hover over a label, but want to highlight the surrounding boundary.
3288
+ map.U.hoverFeatureState('town-labels', 'boundaries', 'town-boundaries');
3289
+
3290
+ // You can also add additional event handlers:
3291
+ map.U.hoverFeatureState('mylayer', 'mysource', 'mysourcelayer',
3292
+ e => console.log(`Entered ${e.features[0].id}`),
3293
+ e => console.log(`Left ${e.oldFeatureid}`);
3294
+
3295
+ // Shows a popup when a feature is hovered over or clicked.
3296
+ // The third argument is an options object, passed to the Popup constructor.
3297
+ // callback is called as: (feature, popup) => htmlString
3298
+ // Make sure you passed the mapboxgl library itself when initialising: U.init(map, mapboxgl).
3299
+ map.U.hoverPopup('mylayer', f => `<h3> ${f.properties.Name}</h3> ${f.properties.Description}`, { anchor: 'left' });
3300
+ map.U.clickPopup('mylayer', f => `<h3> ${f.properties.Name}</h3> ${f.properties.Description}`, { maxWidth: 500 });
3301
+
3302
+ // clickLayer() is like .on('click)', but can take an array and adds a 'features' member
3303
+ // to the event, for what got clicked on.
3304
+ map.U.clickLayer(['towns', 'town-labels'], e => panel.selectedId = e.features[0].id);
3305
+
3306
+ // clickOneLayer tests multiple layers in order, firing callback on the first one that
3307
+ // is hit. The callback is passed { feature, features, layer, event }.
3308
+ map.U.clickOneLayer(['town-labels', 'state-boundaries'], e => {
3309
+ if (e.layer === 'town-labels') {
3310
+ setView('town');
3311
+ panel.selectedId = e.features[0].id;
3312
+ } else if (e.layer === 'state-boundaries') {
3313
+ setView('state');
3314
+ panel.selectedId = e.features[0].id;
3315
+ }
3316
+ });
3317
+
3318
+ // Optionally pass in an extra callback which is fired for clicks that miss all layers:
3319
+ map.U.clickOneLayer(['town-labels', 'state-boundaries'], e => {...}, e => {
3320
+ console.log('Missed everything');
3321
+ });
3322
+
3323
+ // All these functions return an "undo" function that removes the handlers added:
3324
+ const remove = map.U.hoverPopup('mylayer', showPopupFunc);
3325
+ //...
3326
+ remove(); // no more hover popup
3327
+ </ code > </ pre >
3152
3328
< h3 > Other functions</ h3 >
3329
+ < pre > < code > // Like on('load') but fires immediately (and reliably) any time after map already loaded.
3330
+ map.U.onLoad(callback);
3331
+ // returns a promise if no callback:
3332
+ await map.U.onLoad();
3333
+
3334
+ // Gets the layer definition. Mapbox's `getLayer()` has weird paint and layout properties.
3335
+ const layer = map.U.getLayerStyle('mylayer');
3336
+
3337
+ // Resets all other properties to default first. Ignores non-paint, non-layout properties.
3338
+ map.setLayerStyle('mylayer', {
3339
+ lineWidth: 3
3340
+ });
3341
+
3342
+ // properties() converts an object to a layer object accepted by Mapbox-GL-JS
3343
+ map.addLayer(map.U.properties({
3344
+ id: 'mylayer',
3345
+ source: 'mysource',
3346
+ type: 'line',
3347
+ lineWidth: 3,
3348
+ lineCap: 'round',
3349
+ minzoom: 11,
3350
+ filter: ['==', 'status', 'confirmed']
3351
+ }));
3352
+
3353
+ // layerStyle() is flexible, pass as many or as few of id, source, and type (in that order) as you like:
3354
+ map.U.layerStyle('mylayer', 'mysource', 'line', { ... })
3355
+ map.U.layerStyle('mylayer', 'mysource', { ... })
3356
+ map.U.layerStyle('mylayer', { ... })
3357
+ map.U.layerStyle({ ... })
3358
+
3359
+
3360
+ // Hide/show/toggle all the layers attached to this source
3361
+ map.U.hideSource('buildings');
3362
+ map.U.showSource('buildings');
3363
+ map.U.toggleSource('buildings', true);
3364
+
3365
+ // Update several filters at once.
3366
+ map.U.setFilter(['buildings-fill', 'buildings-outline', 'buildings-label'], [...]);
3367
+
3368
+ // Conveniently load an image into the map in one step
3369
+ map.U.loadImage('marker', '/assets/marker-pin.png');
3370
+ map.U.loadImage('marker', '/assets/
[email protected] ', { pixelRatio: 2}).then(/* ... */;
3371
+
3372
+
3373
+ // Update the map style's root "transition" property
3374
+ map.U.setTransition({ delay: 1000, delay: 0});
3375
+
3376
+ // Get a list of fonts used in symbol layers with fontsUsed(). Useful for quickly getting some text displaying.
3377
+ const fonts = map.U.fontsInUse();
3378
+ map.U.addSymbolLayer('labels', 'mysource', { textFont: fonts[0], textField: '{label}' });
3379
+ </ code > </ pre >
3153
3380
< h3 > Contrived example</ h3 >
3381
+ < pre > < code > map.U.onload(() => {
3382
+ map.U.addGeoJSON('towns');
3383
+ map.U.addCircleLayer('small-towns', 'towns', { circleColor: 'green', filter: ['==', 'size', 'small']});
3384
+ map.U.addCircleLayer('large-towns', 'towns', {
3385
+ circleColor: 'red',
3386
+ filter: ['==', 'size', ['large']],
3387
+ circleStrokeWidth: ['case', ['to-boolean', ['feature-state', 'hover']], 5, 1]
3388
+ );
3389
+ map.U.setCircleRadius(['small-towns', 'large-towns'], 12);
3390
+ map.U.hoverPointer(['small-towns', 'large-towns']);
3391
+ map.U.hoverFeatureState('large-towns');
3392
+ // update the source layer when data is available
3393
+ d3.json('http://example.com/towns.json', data => map.U.setData('towns', data));
3394
+ });
3395
+ </ code > </ pre >
3154
3396
< h2 > Credits</ h2 >
3155
3397
< p > Map-GL-Utils was written by, and maintained, by Steve Bennett, a < a href ="https://hire.stevebennett.me "> freelance map developer</ a > .</ p >
3156
3398
< p > Documentation built with < a href ="https://github.com/documentationjs/documentation "> documentation.js</ a > .</ p >
0 commit comments