Skip to content

Commit

Permalink
Use the reloadTile worker method if GeoJSON tile is already loaded (#…
Browse files Browse the repository at this point in the history
…4069)

* Use the `reloadTile` worker method if GeoJSON tile is already loaded

* Reset worker tile cache on setData, and reload appropriately

* Test that GeoJSONWorkerSource properly rebuilds vector data
  • Loading branch information
ezheidtmann authored and mourner committed Jun 10, 2017
1 parent f15eb63 commit 4fcbf38
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 3 deletions.
11 changes: 8 additions & 3 deletions src/source/geojson_source.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,13 @@ class GeoJSONSource extends Evented {
showCollisionBoxes: this.map.showCollisionBoxes
};

tile.workerID = this.dispatcher.send('loadTile', params, (err, data) => {
if (!tile.workerID || tile.state === 'expired') {
tile.workerID = this.dispatcher.send('loadTile', params, done.bind(this), this.workerID);
} else {
tile.workerID = this.dispatcher.send('reloadTile', params, done.bind(this), this.workerID);
}

function done(err, data) {

tile.unloadVectorData();

Expand All @@ -199,8 +205,7 @@ class GeoJSONSource extends Evented {
}

return callback(null);

}, this.workerID);
}
}

abortTile(tile) {
Expand Down
22 changes: 22 additions & 0 deletions src/source/geojson_worker_source.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,35 @@ class GeoJSONWorkerSource extends VectorTileWorkerSource {
this._indexData(data, params, (err, indexed) => {
if (err) { return callback(err); }
this._geoJSONIndexes[params.source] = indexed;
this.loaded[params.source] = {};
callback(null);
});
}.bind(this);

this.loadGeoJSON(params, handleData);
}

/**
* Implements {@link WorkerSource#reloadTile}.
*
* If the tile is loaded, uses the implementation in VectorTileWorkerSource.
* Otherwise, such as after a setData() call, we load the tile fresh.
*
* @param {Object} params
* @param {string} params.source The id of the source for which we're loading this tile.
* @param {string} params.uid The UID for this tile.
*/
reloadTile(params, callback) {
const loaded = this.loaded[params.source],
uid = params.uid;

if (loaded && loaded[uid]) {
return super.reloadTile(params, callback);
} else {
return this.loadTile(params, callback);
}
}

/**
* Fetch and parse GeoJSON according to the given params. Calls `callback`
* with `(err, data)`, where `data` is a parsed GeoJSON object.
Expand Down
80 changes: 80 additions & 0 deletions test/unit/source/geojson_worker_source.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const test = require('mapbox-gl-js-test').test;
const GeoJSONWorkerSource = require('../../../src/source/geojson_worker_source');
const StyleLayerIndex = require('../../../src/style/style_layer_index');
const TileCoord = require('../../../src/source/tile_coord');

test('removeSource', (t) => {
t.test('removes the source from _geoJSONIndexes', (t) => {
Expand Down Expand Up @@ -48,3 +49,82 @@ test('removeSource', (t) => {

t.end();
});

test('reloadTile', (t) => {
t.test('does not rebuild vector data unless data has changed', (t) => {
const layers = [
{
id: 'mylayer',
source: 'sourceId',
type: 'symbol',
}
];
const layerIndex = new StyleLayerIndex(layers);
const source = new GeoJSONWorkerSource(null, layerIndex);
const originalLoadVectorData = source.loadVectorData;
let loadVectorCallCount = 0;
source.loadVectorData = function(params, callback) {
loadVectorCallCount++;
return originalLoadVectorData.call(this, params, callback);
};
const geoJson = {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [0, 0]
}
};
const tileParams = {
source: 'sourceId',
uid: 0,
coord: new TileCoord(0, 0, 0),
maxZoom: 10
};

function addData(callback) {
source.loadData({ source: 'sourceId', data: JSON.stringify(geoJson) }, (err) => {
t.equal(err, null);
callback();
});
}

function reloadTile(callback) {
source.reloadTile(tileParams, (err, data) => {
t.equal(err, null);
return callback(data);
});
}

addData(() => {
// first call should load vector data from geojson
let firstData;
reloadTile(data => {
firstData = data;
});
t.equal(loadVectorCallCount, 1);

// second call won't give us new rawTileData
reloadTile(data => {
t.notOk('rawTileData' in data);
data.rawTileData = firstData.rawTileData;
t.deepEqual(data, firstData);
});

// also shouldn't call loadVectorData again
t.equal(loadVectorCallCount, 1);

// replace geojson data
addData(() => {
// should call loadVectorData again after changing geojson data
reloadTile(data => {
t.ok('rawTileData' in data);
t.deepEqual(data, firstData);
});
t.equal(loadVectorCallCount, 2);
t.end();
});
});
});

t.end();
});

0 comments on commit 4fcbf38

Please sign in to comment.