Skip to content

Commit 321c416

Browse files
authored
Fix stale tiles being shown when calling VectorTileSource#setTiles while the map is moving (#913)
1 parent c8e8345 commit 321c416

5 files changed

Lines changed: 36 additions & 17 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
### 🐞 Bug fixes
88

9+
- Fix stale tiles being shown when calling VectorTileSource#setTiles while the map is moving.
910
- *...Add new stuff here...*
1011

1112
## 2.1.0

src/source/vector_tile_source.test.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ import fixturesSource from '../../test/fixtures/source.json';
99
import {getMockDispatcher, getWrapDispatcher} from '../util/test/util';
1010
import Map from '../ui/map';
1111

12-
function createSource(options, transformCallback?) {
12+
function createSource(options, transformCallback?, clearTiles = () => {}) {
1313
const source = new VectorTileSource('id', options, getMockDispatcher(), options.eventedParent);
1414
source.onAdd({
1515
transform: {showCollisionBoxes: false},
1616
_getMapId: () => 1,
1717
_requestManager: new RequestManager(transformCallback),
18-
style: {sourceCaches: {id: {clearTiles: () => {}}}},
18+
style: {sourceCaches: {id: {clearTiles}}},
1919
getPixelRatio() { return 1; }
2020
} as any as Map);
2121

@@ -343,4 +343,15 @@ describe('VectorTileSource', () => {
343343
tiles: ['http://example2.com/{z}/{x}/{y}.png']
344344
});
345345
});
346+
347+
test('setTiles only clears the cache once the TileJSON has reloaded', done => {
348+
const clearTiles = jest.fn();
349+
const source = createSource({tiles: ['http://example.com/{z}/{x}/{y}.pbf']}, undefined, clearTiles);
350+
source.setTiles(['http://example2.com/{z}/{x}/{y}.pbf']);
351+
expect(clearTiles.mock.calls).toHaveLength(0);
352+
source.once('data', () => {
353+
expect(clearTiles.mock.calls).toHaveLength(1);
354+
done();
355+
});
356+
});
346357
});

src/source/vector_tile_source.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ class VectorTileSource extends Evented implements Source {
9797
this._tileJSONRequest = loadTileJSON(this._options, this.map._requestManager, (err, tileJSON) => {
9898
this._tileJSONRequest = null;
9999
this._loaded = true;
100+
this.map.style.sourceCaches[this.id].clearTiles();
100101
if (err) {
101102
this.fire(new ErrorEvent(err));
102103
} else if (tileJSON) {
@@ -132,8 +133,6 @@ class VectorTileSource extends Evented implements Source {
132133

133134
callback();
134135

135-
const sourceCache = this.map.style.sourceCaches[this.id];
136-
sourceCache.clearTiles();
137136
this.load();
138137
}
139138

src/style/style.test.ts

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ function createGeoJSONSource() {
4848
}
4949

5050
class StubMap extends Evented {
51+
style: Style;
5152
transform: Transform;
5253
private _requestManager: RequestManager;
5354

@@ -68,6 +69,12 @@ class StubMap extends Evented {
6869

6970
const getStubMap = () => new StubMap() as any;
7071

72+
function createStyle(map = getStubMap()) {
73+
const style = new Style(map);
74+
map.style = style;
75+
return style;
76+
}
77+
7178
let sinonFakeXMLServer;
7279
let sinonFakeServer;
7380
let _self;
@@ -258,7 +265,7 @@ describe('Style#loadJSON', () => {
258265
});
259266

260267
test('creates sources', done => {
261-
const style = new Style(getStubMap());
268+
const style = createStyle();
262269

263270
style.on('style.load', () => {
264271
expect(style.sourceCaches['mapLibre'] instanceof SourceCache).toBeTruthy();
@@ -276,7 +283,7 @@ describe('Style#loadJSON', () => {
276283
});
277284

278285
test('creates layers', done => {
279-
const style = new Style(getStubMap());
286+
const style = createStyle();
280287

281288
style.on('style.load', () => {
282289
expect(style.getLayer('fill') instanceof StyleLayer).toBeTruthy();
@@ -302,7 +309,7 @@ describe('Style#loadJSON', () => {
302309
test('transforms sprite json and image URLs before request', done => {
303310
const map = getStubMap();
304311
const transformSpy = jest.spyOn(map._requestManager, 'transformRequest');
305-
const style = new Style(map);
312+
const style = createStyle(map);
306313

307314
style.on('style.load', () => {
308315
expect(transformSpy).toHaveBeenCalledTimes(2);
@@ -319,7 +326,7 @@ describe('Style#loadJSON', () => {
319326
});
320327

321328
test('emits an error on non-existant vector source layer', done => {
322-
const style = new Style(getStubMap());
329+
const style = createStyle();
323330
style.loadJSON(createStyleJSON({
324331
sources: {
325332
'-source-id-': {type: 'vector', tiles: []}
@@ -407,7 +414,7 @@ describe('Style#_remove', () => {
407414

408415
describe('Style#update', () => {
409416
test('on error', done => {
410-
const style = new Style(getStubMap());
417+
const style = createStyle();
411418
style.loadJSON({
412419
'version': 8,
413420
'sources': {
@@ -449,7 +456,7 @@ describe('Style#setState', () => {
449456
});
450457

451458
test('do nothing if there are no changes', done => {
452-
const style = new Style(getStubMap());
459+
const style = createStyle();
453460
style.loadJSON(createStyleJSON());
454461
jest.spyOn(style, 'addLayer').mockImplementation(() => done('test failed'));
455462
jest.spyOn(style, 'removeLayer').mockImplementation(() => done('test failed'));
@@ -574,7 +581,7 @@ describe('Style#addSource', () => {
574581
});
575582

576583
test('fires "data" event', done => {
577-
const style = new Style(getStubMap());
584+
const style = createStyle();
578585
style.loadJSON(createStyleJSON());
579586
const source = createSource();
580587
style.once('data', () => { done(); });
@@ -585,7 +592,7 @@ describe('Style#addSource', () => {
585592
});
586593

587594
test('throws on duplicates', done => {
588-
const style = new Style(getStubMap());
595+
const style = createStyle();
589596
style.loadJSON(createStyleJSON());
590597
const source = createSource();
591598
style.on('style.load', () => {
@@ -607,7 +614,7 @@ describe('Style#addSource', () => {
607614
done();
608615
}
609616
};
610-
const style = new Style(getStubMap());
617+
const style = createStyle();
611618
style.loadJSON(createStyleJSON({
612619
layers: [{
613620
id: 'background',
@@ -795,7 +802,7 @@ describe('Style#addLayer', () => {
795802
});
796803

797804
test('throws on non-existant vector source layer', done => {
798-
const style = new Style(getStubMap());
805+
const style = createStyle();
799806
style.loadJSON(createStyleJSON({
800807
sources: {
801808
// At least one source must be added to trigger the load event
@@ -864,7 +871,7 @@ describe('Style#addLayer', () => {
864871
});
865872

866873
test('reloads source', done => {
867-
const style = new Style(getStubMap());
874+
const style = createStyle();
868875
style.loadJSON(extend(createStyleJSON(), {
869876
'sources': {
870877
'mapLibre': {
@@ -891,7 +898,7 @@ describe('Style#addLayer', () => {
891898
});
892899

893900
test('#3895 reloads source (instead of clearing) if adding this layer with the same type, immediately after removing it', done => {
894-
const style = new Style(getStubMap());
901+
const style = createStyle();
895902
style.loadJSON(extend(createStyleJSON(), {
896903
'sources': {
897904
'mapLibre': {
@@ -928,7 +935,7 @@ describe('Style#addLayer', () => {
928935
});
929936

930937
test('clears source (instead of reloading) if adding this layer with a different type, immediately after removing it', done => {
931-
const style = new Style(getStubMap());
938+
const style = createStyle();
932939
style.loadJSON(extend(createStyleJSON(), {
933940
'sources': {
934941
'mapLibre': {

src/ui/control/logo_control.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ function createSource(options, logoRequired) {
3434
_skuToken: '1234567890123',
3535
canonicalizeTileset: tileJSON => tileJSON.tiles
3636
},
37+
style: {sourceCaches: {id: {clearTiles() {}}}},
3738
transform: {angle: 0, pitch: 0, showCollisionBoxes: false},
3839
_getMapId: () => 1
3940
}as any as Map);

0 commit comments

Comments
 (0)