diff --git a/js/render/drawraster.js b/js/render/drawraster.js index 4fa4803584..7461c2ad02 100644 --- a/js/render/drawraster.js +++ b/js/render/drawraster.js @@ -109,7 +109,7 @@ function findParent(tile) { var source = tile.source; if (!source) return; var parentTiles = {}; - source._findLoadedParent(tile.id, source.options.minZoom, parentTiles); + source._findLoadedParent(tile.id, source.minzoom, parentTiles); return source.tiles[Object.keys(parentTiles)[0]]; } diff --git a/js/source/geojsonsource.js b/js/source/geojsonsource.js index a8b2afc4ea..1f99fd68af 100644 --- a/js/source/geojsonsource.js +++ b/js/source/geojsonsource.js @@ -13,10 +13,8 @@ var GeoJSONSource = module.exports = function(options) { this.maxTileZoom = this.zooms[this.zooms.length - 1]; this.loadNewTiles = true; - this.tileJSON = { - minZoom: 1, - maxZoom: 13 - }; + this.minzoom = 1; + this.maxzoom = 13; this.data = options.data; }; diff --git a/js/source/source.js b/js/source/source.js index 0862f0d4c8..651f7ceb3a 100644 --- a/js/source/source.js +++ b/js/source/source.js @@ -14,15 +14,18 @@ module.exports = Source; function Source(options) { this.enabled = false; - this.type = options.type; - if (this.type === 'vector' && options.tileSize && options.tileSize !== 512) { + + util.extend(this, util.pick(options, + 'type', 'url', 'tileSize')); + + if (this.type === 'vector' && this.tileSize !== 512) { throw new Error('vector tile sources must have a tileSize of 512'); } + this.Tile = this.type === 'vector' ? VectorTile : RasterTile; - this.options = util.inherit(this.options, options); this._tiles = {}; - this._cache = new Cache(this.options.cacheSize, function(tile) { + this._cache = new Cache(this.cacheSize, function(tile) { tile.remove(); }); @@ -32,7 +35,9 @@ function Source(options) { if (!tileJSON.tiles) throw new Error('missing tiles property'); - this.tileJSON = util.extend({ minzoom: 0, maxzoom: 22 }, tileJSON); + util.extend(this, util.pick(tileJSON, + 'tiles', 'minzoom', 'maxzoom', 'attribution')); + this.loadNewTiles = true; this.enabled = true; this.update(); @@ -40,8 +45,8 @@ function Source(options) { if (this.map) this.map.fire('source.add', {source: this}); }.bind(this); - if (options.url) { - ajax.getJSON(normalizeURL(options.url), loaded); + if (this.url) { + ajax.getJSON(normalizeURL(this.url), loaded); } else { loaded(null, options); } @@ -50,10 +55,10 @@ function Source(options) { } Source.prototype = util.inherit(Evented, { - options: { - tileSize: 512, - cacheSize: 20 - }, + minzoom: 0, + maxzoom: 22, + tileSize: 512, + cacheSize: 20, onAdd: function(map) { this.map = map; @@ -121,16 +126,16 @@ Source.prototype = util.inherit(Evented, { // get the zoom level adjusted for the difference in map and source tilesizes _getZoom: function() { - var zOffset = Math.log(this.map.transform.tileSize/this.options.tileSize) / Math.LN2; + var zOffset = Math.log(this.map.transform.tileSize / this.tileSize) / Math.LN2; return this.map.transform.zoom + zOffset; }, _coveringZoomLevel: function(zoom) { - for (var z = this.tileJSON.maxzoom; z >= this.tileJSON.minzoom; z--) { + for (var z = this.maxzoom; z >= this.minzoom; z--) { if (z <= zoom) { if (this.type === 'raster') { // allow underscaling by rounding to the nearest zoom level - if (z < this.tileJSON.maxzoom) { + if (z < this.maxzoom) { z += Math.round(zoom - z); } } @@ -141,8 +146,8 @@ Source.prototype = util.inherit(Evented, { }, _childZoomLevel: function(zoom) { - zoom = Math.max(this.tileJSON.minzoom, zoom + 1); - return zoom <= this.tileJSON.maxzoom ? zoom : null; + zoom = Math.max(this.minzoom, zoom + 1); + return zoom <= this.maxzoom ? zoom : null; }, _getCoveringTiles: function(zoom) { @@ -254,8 +259,8 @@ Source.prototype = util.inherit(Evented, { var tile; // Determine the overzooming/underzooming amounts. - var minCoveringZoom = Math.max(this.tileJSON.minzoom, zoom - 10); - var maxCoveringZoom = this.tileJSON.minzoom; + var minCoveringZoom = Math.max(this.minzoom, zoom - 10); + var maxCoveringZoom = this.minzoom; while (maxCoveringZoom < zoom + 1) { var level = this._childZoomLevel(maxCoveringZoom); if (level === null) break; @@ -335,7 +340,7 @@ Source.prototype = util.inherit(Evented, { if (pos.w === 0) { // console.time('loading ' + pos.z + '/' + pos.x + '/' + pos.y); - var url = TileCoord.url(id, this.tileJSON.tiles); + var url = TileCoord.url(id, this.tiles); tile = this._tiles[id] = new this.Tile(id, this, url, tileComplete); } else { var wrapped = TileCoord.toID(pos.z, pos.x, pos.y, 0); diff --git a/js/source/vectortile.js b/js/source/vectortile.js index 9d7ecbc0f7..1d15f92131 100644 --- a/js/source/vectortile.js +++ b/js/source/vectortile.js @@ -15,12 +15,11 @@ function VectorTile(id, source, url, callback) { this.url = url; this.zoom = TileCoord.fromID(id).z; this.map = source.map; - this.options = source.options; this.id = util.uniqueId(); this.callback = callback; this.source = source; - if (this.zoom >= source.tileJSON.maxzoom) { + if (this.zoom >= source.maxzoom) { this.depth = this.map.options.maxZoom - this.zoom; } else { this.depth = 1; @@ -37,8 +36,8 @@ VectorTile.prototype = util.inherit(Tile, { url: this.url, id: this.id, zoom: this.zoom, - maxZoom: this.source.tileJSON.maxzoom, - tileSize: this.options.tileSize, + maxZoom: this.source.maxzoom, + tileSize: this.source.tileSize, source: this.source.id, depth: this.depth }, function(err, data) { diff --git a/js/ui/control/attribution.js b/js/ui/control/attribution.js index 0fac519987..3007e28b91 100644 --- a/js/ui/control/attribution.js +++ b/js/ui/control/attribution.js @@ -26,8 +26,8 @@ Attribution.prototype = util.inherit(Control, { var attrObj = {}; for (var id in this._map.sources) { var source = this._map.sources[id]; - if (source.tileJSON && source.tileJSON.attribution) { - attrObj[source.tileJSON.attribution] = true; + if (source.attribution) { + attrObj[source.attribution] = true; } } var attributions = []; diff --git a/js/util/util.js b/js/util/util.js index d4f7e589c2..65ed9efd22 100644 --- a/js/util/util.js +++ b/js/util/util.js @@ -68,6 +68,17 @@ exports.inherit = function (parent, props) { return proto; }; +exports.pick = function (src) { + var result = {}; + for (var i = 1; i < arguments.length; i++) { + var k = arguments[i]; + if (k in src) { + result[k] = src[k]; + } + } + return result; +}; + var id = 1; exports.uniqueId = function () { diff --git a/test/fixtures/source.json b/test/fixtures/source.json index c5478ddc25..7f4181f4b1 100644 --- a/test/fixtures/source.json +++ b/test/fixtures/source.json @@ -1,3 +1,6 @@ { - "tiles": ["http://example.com/{z}/{x}/{y}.png"] + "tiles": ["http://example.com/{z}/{x}/{y}.png"], + "minzoom": 1, + "maxzoom": 10, + "attribution": "Mapbox" } diff --git a/test/js/source/source.test.js b/test/js/source/source.test.js index 5fda8f99e8..18bdb7f2e7 100644 --- a/test/js/source/source.test.js +++ b/test/js/source/source.test.js @@ -15,11 +15,17 @@ test('Source', function(t) { t.test('can be constructed from TileJSON', function(t) { var source = new Source({ type: "vector", + minzoom: 1, + maxzoom: 10, + attribution: "Mapbox", tiles: ["http://example.com/{z}/{x}/{y}.png"] }); t.ok(source.enabled); - t.deepEqual(source.tileJSON.tiles, ["http://example.com/{z}/{x}/{y}.png"]); + t.deepEqual(source.tiles, ["http://example.com/{z}/{x}/{y}.png"]); + t.deepEqual(source.minzoom, 1); + t.deepEqual(source.maxzoom, 10); + t.deepEqual(source.attribution, "Mapbox"); t.end(); }); @@ -32,7 +38,10 @@ test('Source', function(t) { source.map = { fire: function() { t.ok(source.enabled); - t.deepEqual(source.tileJSON.tiles, ["http://example.com/{z}/{x}/{y}.png"]); + t.deepEqual(source.tiles, ["http://example.com/{z}/{x}/{y}.png"]); + t.deepEqual(source.minzoom, 1); + t.deepEqual(source.maxzoom, 10); + t.deepEqual(source.attribution, "Mapbox"); t.end(); } };