UNPKG

mapbox-gl

Version:
221 lines (177 loc) 6.66 kB
'use strict'; var Source = require('../source/source'); var StyleLayer = require('./style_layer'); var validateStyle = require('./validate_style'); var styleSpec = require('./style_spec'); function styleBatch(style, work) { if (!style._loaded) { throw new Error('Style is not done loading'); } var batch = Object.create(styleBatch.prototype); batch._style = style; batch._groupLayers = false; batch._broadcastLayers = false; batch._reloadSources = {}; batch._events = []; batch._change = false; work(batch); if (batch._groupLayers) { batch._style._groupLayers(); } if (batch._broadcastLayers) { batch._style._broadcastLayers(); } Object.keys(batch._reloadSources).forEach(function(sourceId) { batch._style._reloadSource(sourceId); }); batch._events.forEach(function(args) { batch._style.fire.apply(batch._style, args); }); if (batch._change) { batch._style.fire('change'); } } styleBatch.prototype = { addLayer: function(layer, before) { if (!(layer instanceof StyleLayer)) { if (validateStyle.emitErrors(this._style, validateStyle.layer({ value: layer, style: this._style.serialize(), styleSpec: styleSpec, // this layer is not in the style.layers array, so we pass an // impossible array index arrayIndex: -1 }))) return this; var refLayer = layer.ref && this._style.getLayer(layer.ref); layer = StyleLayer.create(layer, refLayer); } this._style._validateLayer(layer); layer.on('error', this._style._forwardLayerEvent); this._style._layers[layer.id] = layer; this._style._order.splice(before ? this._style._order.indexOf(before) : Infinity, 0, layer.id); this._groupLayers = true; this._broadcastLayers = true; if (layer.source) { this._reloadSources[layer.source] = true; } this._events.push(['layer.add', {layer: layer}]); this._change = true; return this; }, removeLayer: function(id) { var layer = this._style._layers[id]; if (layer === undefined) { throw new Error('There is no layer with this ID'); } for (var i in this._style._layers) { if (this._style._layers[i].ref === id) { this.removeLayer(i); } } layer.off('error', this._style._forwardLayerEvent); delete this._style._layers[id]; this._style._order.splice(this._style._order.indexOf(id), 1); this._groupLayers = true; this._broadcastLayers = true; this._events.push(['layer.remove', {layer: layer}]); this._change = true; return this; }, setPaintProperty: function(layer, name, value, klass) { this._style.getLayer(layer).setPaintProperty(name, value, klass); this._change = true; return this; }, setLayoutProperty: function(layer, name, value) { layer = this._style.getReferentLayer(layer); layer.setLayoutProperty(name, value); this._broadcastLayers = true; if (layer.source) { this._reloadSources[layer.source] = true; } this._change = true; return this; }, setFilter: function(layer, filter) { if (validateStyle.emitErrors(this._style, validateStyle.filter({ value: filter, style: this._style.serialize(), styleSpec: styleSpec }))) return this; layer = this._style.getReferentLayer(layer); layer.filter = filter; this._broadcastLayers = true; if (layer.source) { this._reloadSources[layer.source] = true; } this._change = true; return this; }, setLayerZoomRange: function(layerId, minzoom, maxzoom) { var layer = this._style.getReferentLayer(layerId); if (minzoom != null) { layer.minzoom = minzoom; } if (maxzoom != null) { layer.maxzoom = maxzoom; } this._broadcastLayers = true; if (layer.source) { this._reloadSources[layer.source] = true; } this._change = true; return this; }, addSource: function(id, source) { if (!this._style._loaded) { throw new Error('Style is not done loading'); } if (this._style.sources[id] !== undefined) { throw new Error('There is already a source with this ID'); } if (!Source.is(source)) { if (validateStyle.emitErrors(this._style, validateStyle.source({ style: this._style.serialize(), value: source, styleSpec: styleSpec }))) return this; } source = Source.create(source); this._style.sources[id] = source; source.id = id; source.style = this._style; source.dispatcher = this._style.dispatcher; source .on('load', this._style._forwardSourceEvent) .on('error', this._style._forwardSourceEvent) .on('change', this._style._forwardSourceEvent) .on('tile.add', this._style._forwardTileEvent) .on('tile.load', this._style._forwardTileEvent) .on('tile.error', this._style._forwardTileEvent) .on('tile.remove', this._style._forwardTileEvent) .on('tile.stats', this._style._forwardTileEvent); this._events.push(['source.add', {source: source}]); this._change = true; return this; }, removeSource: function(id) { if (this._style.sources[id] === undefined) { throw new Error('There is no source with this ID'); } var source = this._style.sources[id]; delete this._style.sources[id]; source .off('load', this._style._forwardSourceEvent) .off('error', this._style._forwardSourceEvent) .off('change', this._style._forwardSourceEvent) .off('tile.add', this._style._forwardTileEvent) .off('tile.load', this._style._forwardTileEvent) .off('tile.error', this._style._forwardTileEvent) .off('tile.remove', this._style._forwardTileEvent) .off('tile.stats', this._style._forwardTileEvent); this._events.push(['source.remove', {source: source}]); this._change = true; return this; } }; module.exports = styleBatch;