From 461a0015528e56560c37b241c009e5fb0e9ccf6b Mon Sep 17 00:00:00 2001 From: Lukas Martinelli Date: Mon, 19 Dec 2016 22:13:22 +0100 Subject: [PATCH] Layer watcher figures out possible fields --- package.json | 2 ++ src/layerwatcher.js | 44 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 0037a71f..7e9cf52d 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,8 @@ "color": "^1.0.3", "file-saver": "^1.3.2", "immutable": "^3.8.1", + "lodash.throttle": "^4.1.1", + "lodash.topairs": "^4.3.0", "mapbox-gl": "^0.28.0", "mapbox-gl-style-spec": "mapbox/mapbox-gl-style-spec#e85407a377510acb647161de6be6357ab4f606dd", "ol-mapbox-style": "0.0.11", diff --git a/src/layerwatcher.js b/src/layerwatcher.js index a8b9aa40..373fdb05 100644 --- a/src/layerwatcher.js +++ b/src/layerwatcher.js @@ -1,26 +1,66 @@ import Immutable from 'immutable' +import throttle from 'lodash.throttle' +import entries from 'lodash.topairs' /** Listens to map events to build up a store of available vector * layers contained in the tiles */ export default class LayerWatcher { constructor() { this._sources = {} + this._vectorLayers = {} + this._map= null + + // Since we scan over all features we want to avoid this as much as + // possible and only do it after a batch of data has loaded because + // we only care eventuall about knowing the fields in the vector layers + this.throttledAnalyzeVectorLayerFields = throttle(this.analyzeVectorLayerFields, 5000) } /** Set the map as soon as the map is initialized */ set map(m) { + + this._map = m //TODO: At some point we need to unsubscribe when new map is set - m.on('data', (e) => { + this._map.on('data', (e) => { if(e.dataType !== 'tile') return + this._sources[e.source.id] = e.source.vectorLayerIds + this.throttledAnalyzeVectorLayerFields() }) } + analyzeVectorLayerFields() { + Object.keys(this._sources).forEach(sourceId => { + this._sources[sourceId].forEach(vectorLayerId => { + const knownProperties = this._vectorLayers[vectorLayerId] || {} + const params = { sourceLayer: vectorLayerId } + this._map.querySourceFeatures(sourceId, params).forEach(feature => { + Object.keys(feature.properties).forEach(propertyName => { + const knownPropertyValues = knownProperties[propertyName] || {} + knownPropertyValues[feature.properties[propertyName]] = {} + knownProperties[propertyName] = knownPropertyValues + }) + }) + + this._vectorLayers[vectorLayerId] = knownProperties + }) + }) + + console.log(this.vectorLayers.toJSON()) + } + /** Access all known sources and their vector tile ids */ get sources() { - console.log(this._sources) return Immutable.Map(Object.keys(this._sources).map(key => { return [key, Immutable.Set(this._sources[key])] })) } + + get vectorLayers() { + return Immutable.Map(entries(this._vectorLayers).map(([key, layer]) => { + return [key, Immutable.Map(entries(layer).map(([propId, values]) => { + return [propId, Immutable.Set(Object.keys(values))] + }))] + })) + } }