diff --git a/src/__mocks__/mapbox-gl.js b/src/__mocks__/mapbox-gl.js index 8a78968..bcd3a49 100644 --- a/src/__mocks__/mapbox-gl.js +++ b/src/__mocks__/mapbox-gl.js @@ -7,6 +7,12 @@ function Map() { this._sources = {}; this._layers = []; + this.style = { + sources: this._sources, + layers: this._layers, + sourceCaches: {} + }; + this.flyTo = jest.fn(); this.easeTo = jest.fn(); this.jumpTo = jest.fn(); @@ -36,10 +42,7 @@ Map.prototype.on = function on(_, listener, fn) { Map.prototype.off = jest.fn(); Map.prototype.getStyle = function getStyle() { - return { - sources: this._sources, - layers: this._layers - }; + return this.style; }; Map.prototype.setStyle = jest.fn(); @@ -53,7 +56,7 @@ Map.prototype.getSource = function getSource(name) { return undefined; } - return { ...this._sources[name], setData: jest.fn() }; + return { ...this._sources[name], setData: jest.fn(), load: jest.fn() }; }; Map.prototype.removeSource = function removeSource(name) { diff --git a/src/components/Source/index.js b/src/components/Source/index.js index 796d56f..4a378d9 100644 --- a/src/components/Source/index.js +++ b/src/components/Source/index.js @@ -3,7 +3,6 @@ import { PureComponent, createElement } from 'react'; import type MapboxMap from 'mapbox-gl/src/ui/map'; import type { - StyleSpecification, SourceSpecification, VectorSourceSpecification, GeoJSONSourceSpecification @@ -55,19 +54,7 @@ class Source extends PureComponent { return; } - if (this._map.getSource(this.props.id)) { - const { id } = this.props; - const { layers } = this._map.getStyle(); - if (layers) { - layers.forEach((layer) => { - if (layer.source === id) { - this._map.removeLayer(layer.id); - } - }); - } - - this._map.removeSource(this.props.id); - } + this._removeSource(); } _updateGeoJSONSource = ( @@ -80,22 +67,45 @@ class Source extends PureComponent { } }; + // https://github.com/mapbox/mapbox-gl-js/pull/8048 _updateVectorSource = ( id: string, prevSource: VectorSourceSpecification, newSource: VectorSourceSpecification ) => { - if (newSource.url !== prevSource.url) { - this._map.removeSource(id); - this._map.addSource(id, newSource); - return; + const source = this._map.getSource(id); + + /* eslint-disable no-underscore-dangle */ + if (source._tileJSONRequest) { + source._tileJSONRequest.cancel(); + } + + source.url = newSource.url; + source.scheme = newSource.scheme; + source._options = { ...source._options, ...newSource }; + /* eslint-enable no-underscore-dangle */ + + const sourceCache = this._map.style.sourceCaches[id]; + if (sourceCache) { + sourceCache.clearTiles(); } - if (newSource.tiles !== prevSource.tiles) { - const style: StyleSpecification = this._map.getStyle(); - // $FlowFixMe - style.sources[id].tiles = newSource.tiles; - this._map.setStyle(style); + source.load(); + }; + + _removeSource = () => { + const { id } = this.props; + if (this._map.getSource(id)) { + const { layers } = this._map.getStyle(); + if (layers) { + layers.forEach((layer) => { + if (layer.source === id) { + this._map.removeLayer(layer.id); + } + }); + } + + this._map.removeSource(id); } };