maplibre-gl 3.3.1 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/maplibre-gl-csp-worker.js +1 -1
- package/dist/maplibre-gl-csp-worker.js.map +1 -1
- package/dist/maplibre-gl-csp.js +1 -1
- package/dist/maplibre-gl-csp.js.map +1 -1
- package/dist/maplibre-gl-dev.js +202 -80
- package/dist/maplibre-gl-dev.js.map +1 -1
- package/dist/maplibre-gl.d.ts +14 -6
- package/dist/maplibre-gl.js +4 -4
- package/dist/maplibre-gl.js.map +1 -1
- package/package.json +41 -41
- package/src/data/dem_data.test.ts +120 -165
- package/src/data/dem_data.ts +38 -18
- package/src/source/image_source.test.ts +17 -24
- package/src/source/raster_dem_tile_source.ts +15 -2
- package/src/source/raster_dem_tile_worker_source.ts +2 -2
- package/src/source/raster_tile_source.test.ts +1 -1
- package/src/source/raster_tile_source.ts +1 -1
- package/src/source/terrain_source_cache.test.ts +1 -1
- package/src/source/vector_tile_source.test.ts +1 -1
- package/src/source/vector_tile_worker_source.test.ts +45 -1
- package/src/source/vector_tile_worker_source.ts +19 -6
- package/src/source/worker_source.ts +6 -2
- package/src/style/load_glyph_range.test.ts +6 -8
- package/src/style/load_sprite.test.ts +48 -71
- package/src/style/style.test.ts +19 -49
- package/src/style/style_layer/line_style_layer.test.ts +50 -0
- package/src/style/style_layer/line_style_layer.ts +8 -4
- package/src/ui/handler/scroll_zoom.ts +6 -0
- package/src/ui/handler_manager.ts +2 -1
- package/src/ui/map.ts +1 -0
- package/src/ui/marker.test.ts +25 -0
- package/src/ui/marker.ts +8 -1
- package/src/util/ajax.test.ts +1 -1
- package/src/util/image_request.test.ts +1 -1
- package/src/util/test/util.ts +12 -0
package/src/style/style.test.ts
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from '../source/rtl_text_plugin';
|
|
14
14
|
import {browser} from '../util/browser';
|
|
15
15
|
import {OverscaledTileID} from '../source/tile_id';
|
|
16
|
-
import {
|
|
16
|
+
import {fakeServer, type FakeServer} from 'nise';
|
|
17
17
|
|
|
18
18
|
import {EvaluationParameters} from './evaluation_parameters';
|
|
19
19
|
import {LayerSpecification, GeoJSONSourceSpecification, FilterSpecification, SourceSpecification} from '@maplibre/maplibre-gl-style-spec';
|
|
@@ -78,21 +78,17 @@ function createStyle(map = getStubMap()) {
|
|
|
78
78
|
return style;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
let
|
|
82
|
-
let sinonFakeServer;
|
|
81
|
+
let server: FakeServer;
|
|
83
82
|
let mockConsoleError;
|
|
84
83
|
|
|
85
84
|
beforeEach(() => {
|
|
86
85
|
global.fetch = null;
|
|
87
|
-
|
|
88
|
-
sinonFakeXMLServer = fakeXhr.useFakeXMLHttpRequest();
|
|
89
|
-
|
|
86
|
+
server = fakeServer.create();
|
|
90
87
|
mockConsoleError = jest.spyOn(console, 'error').mockImplementation(() => { });
|
|
91
88
|
});
|
|
92
89
|
|
|
93
90
|
afterEach(() => {
|
|
94
|
-
|
|
95
|
-
sinonFakeServer.restore();
|
|
91
|
+
server.restore();
|
|
96
92
|
mockConsoleError.mockRestore();
|
|
97
93
|
});
|
|
98
94
|
|
|
@@ -115,12 +111,12 @@ describe('Style', () => {
|
|
|
115
111
|
|
|
116
112
|
test('loads plugin immediately if already registered', done => {
|
|
117
113
|
clearRTLTextPlugin();
|
|
118
|
-
|
|
114
|
+
server.respondWith('/plugin.js', 'doesn\'t matter');
|
|
119
115
|
setRTLTextPlugin('/plugin.js', (error) => {
|
|
120
116
|
expect(error).toMatch(/Cannot set the state of the rtl-text-plugin when not in the web-worker context/);
|
|
121
117
|
done();
|
|
122
118
|
});
|
|
123
|
-
|
|
119
|
+
server.respond();
|
|
124
120
|
new Style(getStubMap());
|
|
125
121
|
});
|
|
126
122
|
|
|
@@ -152,7 +148,7 @@ describe('Style', () => {
|
|
|
152
148
|
jest.spyOn(style.sourceCaches['vector'], 'reload');
|
|
153
149
|
|
|
154
150
|
clearRTLTextPlugin();
|
|
155
|
-
|
|
151
|
+
server.respondWith('/plugin.js', 'doesn\'t matter');
|
|
156
152
|
const _broadcast = style.dispatcher.broadcast;
|
|
157
153
|
style.dispatcher.broadcast = function (type, state, callback) {
|
|
158
154
|
if (type === 'syncRTLPluginState') {
|
|
@@ -171,7 +167,7 @@ describe('Style', () => {
|
|
|
171
167
|
done();
|
|
172
168
|
}, 0);
|
|
173
169
|
});
|
|
174
|
-
|
|
170
|
+
server.respond();
|
|
175
171
|
});
|
|
176
172
|
});
|
|
177
173
|
});
|
|
@@ -211,15 +207,15 @@ describe('Style#loadURL', () => {
|
|
|
211
207
|
});
|
|
212
208
|
|
|
213
209
|
style.loadURL('style.json');
|
|
214
|
-
|
|
215
|
-
|
|
210
|
+
server.respondWith(JSON.stringify(createStyleJSON({version: 'invalid'})));
|
|
211
|
+
server.respond();
|
|
216
212
|
});
|
|
217
213
|
|
|
218
214
|
test('cancels pending requests if removed', () => {
|
|
219
215
|
const style = new Style(getStubMap());
|
|
220
216
|
style.loadURL('style.json');
|
|
221
217
|
style._remove();
|
|
222
|
-
expect(
|
|
218
|
+
expect((server.lastRequest as any).aborted).toBe(true);
|
|
223
219
|
});
|
|
224
220
|
});
|
|
225
221
|
|
|
@@ -266,21 +262,8 @@ describe('Style#loadJSON', () => {
|
|
|
266
262
|
// stub Image so we can invoke 'onload'
|
|
267
263
|
// https://github.com/jsdom/jsdom/commit/58a7028d0d5b6aacc5b435daee9fd8f9eacbb14c
|
|
268
264
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
const requests = [];
|
|
272
|
-
sinonFakeXMLServer.onCreate = req => { requests.push(req); };
|
|
273
|
-
const respond = () => {
|
|
274
|
-
let req = requests.find(req => req.url === 'http://example.com/sprite.png');
|
|
275
|
-
req.setStatus(200);
|
|
276
|
-
req.response = new ArrayBuffer(8);
|
|
277
|
-
req.onload();
|
|
278
|
-
|
|
279
|
-
req = requests.find(req => req.url === 'http://example.com/sprite.json');
|
|
280
|
-
req.setStatus(200);
|
|
281
|
-
req.response = '{}';
|
|
282
|
-
req.onload();
|
|
283
|
-
};
|
|
265
|
+
server.respondWith('GET', 'http://example.com/sprite.png', new ArrayBuffer(8));
|
|
266
|
+
server.respondWith('GET', 'http://example.com/sprite.json', '{}');
|
|
284
267
|
|
|
285
268
|
const style = new Style(getStubMap());
|
|
286
269
|
|
|
@@ -303,7 +286,7 @@ describe('Style#loadJSON', () => {
|
|
|
303
286
|
done();
|
|
304
287
|
});
|
|
305
288
|
|
|
306
|
-
respond();
|
|
289
|
+
server.respond();
|
|
307
290
|
});
|
|
308
291
|
});
|
|
309
292
|
|
|
@@ -315,21 +298,8 @@ describe('Style#loadJSON', () => {
|
|
|
315
298
|
// stub Image so we can invoke 'onload'
|
|
316
299
|
// https://github.com/jsdom/jsdom/commit/58a7028d0d5b6aacc5b435daee9fd8f9eacbb14c
|
|
317
300
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
const requests = [];
|
|
321
|
-
sinonFakeXMLServer.onCreate = req => { requests.push(req); };
|
|
322
|
-
const respond = () => {
|
|
323
|
-
let req = requests.find(req => req.url === 'http://example.com/sprite.png');
|
|
324
|
-
req.setStatus(200);
|
|
325
|
-
req.response = new ArrayBuffer(8);
|
|
326
|
-
req.onload();
|
|
327
|
-
|
|
328
|
-
req = requests.find(req => req.url === 'http://example.com/sprite.json');
|
|
329
|
-
req.setStatus(200);
|
|
330
|
-
req.response = '{"image1": {"width": 1, "height": 1, "x": 0, "y": 0, "pixelRatio": 1.0}}';
|
|
331
|
-
req.onload();
|
|
332
|
-
};
|
|
301
|
+
server.respondWith('GET', 'http://example.com/sprite.png', new ArrayBuffer(8));
|
|
302
|
+
server.respondWith('GET', 'http://example.com/sprite.json', '{"image1": {"width": 1, "height": 1, "x": 0, "y": 0, "pixelRatio": 1.0}}');
|
|
333
303
|
|
|
334
304
|
const style = new Style(getStubMap());
|
|
335
305
|
|
|
@@ -357,7 +327,7 @@ describe('Style#loadJSON', () => {
|
|
|
357
327
|
});
|
|
358
328
|
});
|
|
359
329
|
|
|
360
|
-
respond();
|
|
330
|
+
server.respond();
|
|
361
331
|
});
|
|
362
332
|
});
|
|
363
333
|
|
|
@@ -751,7 +721,7 @@ describe('Style#setState', () => {
|
|
|
751
721
|
});
|
|
752
722
|
|
|
753
723
|
test('Issue #3893: compare new source options against originally provided options rather than normalized properties', done => {
|
|
754
|
-
|
|
724
|
+
server.respondWith('/tilejson.json', JSON.stringify({
|
|
755
725
|
tiles: ['http://tiles.server']
|
|
756
726
|
}));
|
|
757
727
|
const initial = createStyleJSON();
|
|
@@ -767,7 +737,7 @@ describe('Style#setState', () => {
|
|
|
767
737
|
style.setState(initial);
|
|
768
738
|
done();
|
|
769
739
|
});
|
|
770
|
-
|
|
740
|
+
server.respond();
|
|
771
741
|
});
|
|
772
742
|
|
|
773
743
|
test('return true if there is a change', done => {
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {createStyleLayer} from '../create_style_layer';
|
|
2
|
+
import {extend} from '../../util/util';
|
|
3
|
+
import {LineStyleLayer} from './line_style_layer';
|
|
4
|
+
|
|
5
|
+
describe('LineStyleLayer', () => {
|
|
6
|
+
function createLineLayer(layer?) {
|
|
7
|
+
return extend({
|
|
8
|
+
type: 'line',
|
|
9
|
+
source: 'line',
|
|
10
|
+
id: 'line',
|
|
11
|
+
paint: {
|
|
12
|
+
'line-color': 'red',
|
|
13
|
+
'line-width': 14,
|
|
14
|
+
'line-gradient': [
|
|
15
|
+
'interpolate',
|
|
16
|
+
['linear'],
|
|
17
|
+
['line-progress'],
|
|
18
|
+
0,
|
|
19
|
+
'blue',
|
|
20
|
+
1,
|
|
21
|
+
'red'
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
}, layer);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
test('updating with valid line-gradient updates this.gradientVersion', () => {
|
|
28
|
+
const lineLayer = createStyleLayer(createLineLayer()) as LineStyleLayer;
|
|
29
|
+
const gradientVersion = lineLayer.gradientVersion;
|
|
30
|
+
|
|
31
|
+
lineLayer.setPaintProperty('line-gradient', [
|
|
32
|
+
'interpolate',
|
|
33
|
+
['linear'],
|
|
34
|
+
['line-progress'],
|
|
35
|
+
0,
|
|
36
|
+
'red',
|
|
37
|
+
1,
|
|
38
|
+
'blue'
|
|
39
|
+
]);
|
|
40
|
+
expect(lineLayer.gradientVersion).toBeGreaterThan(gradientVersion);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('updating with invalid line-gradient updates this.gradientVersion', () => {
|
|
44
|
+
const lineLayer = createStyleLayer(createLineLayer()) as LineStyleLayer;
|
|
45
|
+
const gradientVersion = lineLayer.gradientVersion;
|
|
46
|
+
|
|
47
|
+
lineLayer.setPaintProperty('line-gradient', null);
|
|
48
|
+
expect(lineLayer.gradientVersion).toBeGreaterThan(gradientVersion);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -9,8 +9,8 @@ import {extend} from '../../util/util';
|
|
|
9
9
|
import {EvaluationParameters} from '../evaluation_parameters';
|
|
10
10
|
import {Transitionable, Transitioning, Layout, PossiblyEvaluated, DataDrivenProperty} from '../properties';
|
|
11
11
|
|
|
12
|
-
import {Step} from '@maplibre/maplibre-gl-style-spec';
|
|
13
|
-
import type {FeatureState,
|
|
12
|
+
import {isZoomExpression, Step} from '@maplibre/maplibre-gl-style-spec';
|
|
13
|
+
import type {FeatureState, LayerSpecification} from '@maplibre/maplibre-gl-style-spec';
|
|
14
14
|
import type {Bucket, BucketParameters} from '../../data/bucket';
|
|
15
15
|
import type {LineLayoutProps, LinePaintProps} from './line_style_layer_properties.g';
|
|
16
16
|
import type {Transform} from '../../geo/transform';
|
|
@@ -60,8 +60,12 @@ export class LineStyleLayer extends StyleLayer {
|
|
|
60
60
|
|
|
61
61
|
_handleSpecialPaintPropertyUpdate(name: string) {
|
|
62
62
|
if (name === 'line-gradient') {
|
|
63
|
-
const expression
|
|
64
|
-
|
|
63
|
+
const expression = this.gradientExpression();
|
|
64
|
+
if (isZoomExpression(expression)) {
|
|
65
|
+
this.stepInterpolant = expression._styleExpression.expression instanceof Step;
|
|
66
|
+
} else {
|
|
67
|
+
this.stepInterpolant = false;
|
|
68
|
+
}
|
|
65
69
|
this.gradientVersion = (this.gradientVersion + 1) % Number.MAX_SAFE_INTEGER;
|
|
66
70
|
}
|
|
67
71
|
}
|
|
@@ -351,5 +351,11 @@ export class ScrollZoomHandler implements Handler {
|
|
|
351
351
|
|
|
352
352
|
reset() {
|
|
353
353
|
this._active = false;
|
|
354
|
+
this._zooming = false;
|
|
355
|
+
delete this._targetZoom;
|
|
356
|
+
if (this._finishTimeout) {
|
|
357
|
+
clearTimeout(this._finishTimeout);
|
|
358
|
+
delete this._finishTimeout;
|
|
359
|
+
}
|
|
354
360
|
}
|
|
355
361
|
}
|
|
@@ -17,6 +17,7 @@ import {DragPanHandler} from './handler/shim/drag_pan';
|
|
|
17
17
|
import {DragRotateHandler} from './handler/shim/drag_rotate';
|
|
18
18
|
import {TwoFingersTouchZoomRotateHandler} from './handler/shim/two_fingers_touch';
|
|
19
19
|
import {extend} from '../util/util';
|
|
20
|
+
import {browser} from '../util/browser';
|
|
20
21
|
import Point from '@mapbox/point-geometry';
|
|
21
22
|
|
|
22
23
|
export type InputEvent = MouseEvent | TouchEvent | KeyboardEvent | WheelEvent;
|
|
@@ -583,7 +584,7 @@ export class HandlerManager {
|
|
|
583
584
|
|
|
584
585
|
const shouldSnapToNorth = bearing => bearing !== 0 && -this._bearingSnap < bearing && bearing < this._bearingSnap;
|
|
585
586
|
|
|
586
|
-
if (inertialEase) {
|
|
587
|
+
if (inertialEase && (inertialEase.essential || !browser.prefersReducedMotion)) {
|
|
587
588
|
if (shouldSnapToNorth(inertialEase.bearing || this._map.getBearing())) {
|
|
588
589
|
inertialEase.bearing = 0;
|
|
589
590
|
}
|
package/src/ui/map.ts
CHANGED
|
@@ -2562,6 +2562,7 @@ export class Map extends Camera {
|
|
|
2562
2562
|
* @param name - The name of the paint property to set.
|
|
2563
2563
|
* @param value - The value of the paint property to set.
|
|
2564
2564
|
* Must be of a type appropriate for the property, as defined in the [MapLibre Style Specification](https://maplibre.org/maplibre-style-spec/).
|
|
2565
|
+
* Pass `null` to unset the existing value.
|
|
2565
2566
|
* @param options - Options object.
|
|
2566
2567
|
* @returns `this`
|
|
2567
2568
|
* @example
|
package/src/ui/marker.test.ts
CHANGED
|
@@ -811,4 +811,29 @@ describe('marker', () => {
|
|
|
811
811
|
|
|
812
812
|
map.remove();
|
|
813
813
|
});
|
|
814
|
+
|
|
815
|
+
test('Marker after the terrain event must listen to the render event till is fully loaded', async () => {
|
|
816
|
+
const map = createMap();
|
|
817
|
+
|
|
818
|
+
new Marker()
|
|
819
|
+
.setLngLat([1, 1])
|
|
820
|
+
.addTo(map);
|
|
821
|
+
|
|
822
|
+
expect(map._oneTimeListeners.render).toBeUndefined();
|
|
823
|
+
|
|
824
|
+
map.fire('terrain');
|
|
825
|
+
expect(map._oneTimeListeners.render).toHaveLength(1);
|
|
826
|
+
|
|
827
|
+
map.fire('render');
|
|
828
|
+
expect(map._oneTimeListeners.render).toHaveLength(1);
|
|
829
|
+
|
|
830
|
+
map.fire('render');
|
|
831
|
+
expect(map._oneTimeListeners.render).toHaveLength(1);
|
|
832
|
+
|
|
833
|
+
// await idle to be fully loaded
|
|
834
|
+
await map.once('idle');
|
|
835
|
+
map.fire('render');
|
|
836
|
+
expect(map._oneTimeListeners.render).toHaveLength(0);
|
|
837
|
+
map.remove();
|
|
838
|
+
});
|
|
814
839
|
});
|
package/src/ui/marker.ts
CHANGED
|
@@ -297,6 +297,8 @@ export class Marker extends Evented {
|
|
|
297
297
|
map.getCanvasContainer().appendChild(this._element);
|
|
298
298
|
map.on('move', this._update);
|
|
299
299
|
map.on('moveend', this._update);
|
|
300
|
+
map.on('terrain', this._update);
|
|
301
|
+
|
|
300
302
|
this.setDraggable(this._draggable);
|
|
301
303
|
this._update();
|
|
302
304
|
|
|
@@ -504,9 +506,14 @@ export class Marker extends Evented {
|
|
|
504
506
|
return this;
|
|
505
507
|
}
|
|
506
508
|
|
|
507
|
-
_update = (e?: { type: 'move' | 'moveend' }) => {
|
|
509
|
+
_update = (e?: { type: 'move' | 'moveend' | 'terrain' | 'render' }) => {
|
|
508
510
|
if (!this._map) return;
|
|
509
511
|
|
|
512
|
+
const isFullyLoaded = this._map.loaded() && !this._map.isMoving();
|
|
513
|
+
if (e?.type === 'terrain' || (e?.type === 'render' && !isFullyLoaded)) {
|
|
514
|
+
this._map.once('render', this._update);
|
|
515
|
+
}
|
|
516
|
+
|
|
510
517
|
if (this._map.transform.renderWorldCopies) {
|
|
511
518
|
this._lngLat = smartWrap(this._lngLat, this._pos, this._map.transform);
|
|
512
519
|
}
|
package/src/util/ajax.test.ts
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
sameOrigin
|
|
7
7
|
} from './ajax';
|
|
8
8
|
|
|
9
|
-
import {fakeServer, FakeServer} from 'nise';
|
|
9
|
+
import {fakeServer, type FakeServer} from 'nise';
|
|
10
10
|
import {destroyFetchMock, FetchMock, RequestMock, setupFetchMock} from './test/mock_fetch';
|
|
11
11
|
|
|
12
12
|
function readAsText(blob) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {config} from './config';
|
|
2
2
|
import {webpSupported} from './webp_supported';
|
|
3
3
|
import {stubAjaxGetImage} from './test/util';
|
|
4
|
-
import {fakeServer, FakeServer} from 'nise';
|
|
4
|
+
import {fakeServer, type FakeServer} from 'nise';
|
|
5
5
|
import {ImageRequest, ImageRequestQueueItem} from './image_request';
|
|
6
6
|
import * as ajax from './ajax';
|
|
7
7
|
|
package/src/util/test/util.ts
CHANGED
|
@@ -132,3 +132,15 @@ export function stubAjaxGetImage(createImageBitmap) {
|
|
|
132
132
|
}
|
|
133
133
|
});
|
|
134
134
|
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* This should be used in test that use nise since the internal buffer returned from a file is not an instance of ArrayBuffer for some reason.
|
|
138
|
+
* @param data - the data read from a file, for example by `fs.readFileSync(...)`
|
|
139
|
+
* @returns a copy of the data in the file in `ArrayBuffer` format
|
|
140
|
+
*/
|
|
141
|
+
export function bufferToArrayBuffer(data: Buffer): ArrayBuffer {
|
|
142
|
+
const newBuffer = new ArrayBuffer(data.buffer.byteLength);
|
|
143
|
+
const view = new Uint8Array(newBuffer);
|
|
144
|
+
data.copy(view);
|
|
145
|
+
return view.buffer;
|
|
146
|
+
}
|