diff --git a/js/source/geojson_source.js b/js/source/geojson_source.js index 0581ff7ba4c..002d9d79ed7 100644 --- a/js/source/geojson_source.js +++ b/js/source/geojson_source.js @@ -12,7 +12,7 @@ module.exports = GeoJSONSource; * Create a GeoJSON data source instance given an options object * @class GeoJSONSource * @param {Object} [options] - * @param {Object|string} options.data A GeoJSON data object or URL to it. The latter is preferable in case of large GeoJSON files. + * @param {Object|string} options.data A GeoJSON data object, a JSON.stringified GeoJSON data object (slightly faster than former option), or URL to it (preferable in case of large GeoJSON files). * @param {number} [options.maxzoom=14] Maximum zoom to preserve detail at. * @param {number} [options.buffer] Tile buffer on each side. * @param {number} [options.tolerance] Simplification tolerance (higher means simpler). @@ -81,7 +81,7 @@ GeoJSONSource.prototype = util.inherit(Evented, /** @lends GeoJSONSource.prototy /** * Update source geojson data and rerender map * - * @param {Object|string} data A GeoJSON data object or URL to it. The latter is preferable in case of large GeoJSON files. + * @param {Object|string} data A GeoJSON data object, a JSON.stringified GeoJSON data object (slightly faster than former option), or URL to it (preferable in case of large GeoJSON files). * @returns {GeoJSONSource} this */ setData: function(data) { @@ -129,7 +129,7 @@ GeoJSONSource.prototype = util.inherit(Evented, /** @lends GeoJSONSource.prototy _updateData: function() { this._dirty = false; var data = this._data; - if (typeof data === 'string' && typeof window != 'undefined') { + if (typeof data === 'string' && typeof window != 'undefined' && data.charAt(0) !== '{') { data = urlResolve(window.location.href, data); } this.workerID = this.dispatcher.send('parse geojson', { diff --git a/js/source/worker.js b/js/source/worker.js index 9f5533fb006..e52971b600d 100644 --- a/js/source/worker.js +++ b/js/source/worker.js @@ -122,7 +122,11 @@ util.extend(Worker.prototype, { // ie: /foo/bar.json or http://example.com/bar.json // but not ../foo/bar.json if (typeof params.data === 'string') { - ajax.getJSON(params.data, indexData); + if (params.data.charAt(0) === '{') { + indexData(null, JSON.parse(params.data)); + } else { + ajax.getJSON(params.data, indexData); + } } else indexData(null, params.data); }, diff --git a/test/js/source/worker.test.js b/test/js/source/worker.test.js index e3d9a549c97..a923cf9610b 100644 --- a/test/js/source/worker.test.js +++ b/test/js/source/worker.test.js @@ -77,6 +77,54 @@ test('remove tile', function(t) { }); }); +test('geojson', function(t) { + var geojson = { + "type": "FeatureCollection", + "features": [{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [-122.48369693756104, 37.83381888486939], + [-122.48348236083984, 37.83317489144141] + ] + } + }] + }; + + // test parsing of GeoJSON in native and stringified form. + [geojson, JSON.stringify(geojson)].forEach(function (data) { + t.test('parses geojson', function(t) { + var worker = new Worker(_self); + + worker.loaded = { + source: { + '0': {} + } + }; + + t.deepEqual(worker.geoJSONIndexes, {}); + worker['parse geojson']({ + data: data, + tileSize: 512, + source: "test", + geojsonVtOptions: { maxZoom: 20 }, + cluster: false, + superclusterOptions: { + maxZoom: 19, + extent: 4096, + radius: 400, + log: false + } + }, function() { + t.notDeepEqual(worker.geoJSONIndexes, {}); + t.end(); + }); + }); + }); +}); + test('after', function(t) { server.close(t.end); });