mirror of
https://github.com/maputnik/editor.git
synced 2026-07-25 23:37:27 +00:00
Migrate all the non react components code to typescript (#847)
This completes the migration to typescript of all the non react components code. The only changes introduced besides types are the type checks using `"something" in object` which narrows down types in typescript.
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
import throttle from 'lodash.throttle'
|
||||
import isEqual from 'lodash.isequal'
|
||||
import { Map } from 'maplibre-gl';
|
||||
|
||||
export type LayerWatcherOptions = {
|
||||
onSourcesChange?: (sources: { [sourceId: string]: string[] }) => void;
|
||||
onVectorLayersChange?: (vectorLayers: { [vectorLayerId: string]: { [propertyName: string]: { [propertyValue: string]: {} } } }) => void;
|
||||
}
|
||||
|
||||
/** Listens to map events to build up a store of available vector
|
||||
* layers contained in the tiles */
|
||||
export default class LayerWatcher {
|
||||
onSourcesChange: (sources: { [sourceId: string]: string[] }) => void;
|
||||
onVectorLayersChange: (vectorLayers: { [vectorLayerId: string]: { [propertyName: string]: { [propertyValue: string]: {} } } }) => void;
|
||||
throttledAnalyzeVectorLayerFields: (map: any) => void;
|
||||
_sources: { [sourceId: string]: string[] };
|
||||
_vectorLayers: { [vectorLayerId: string]: { [propertyName: string]: { [propertyValue: string]: {} } } };
|
||||
|
||||
constructor(opts: LayerWatcherOptions = {}) {
|
||||
this.onSourcesChange = opts.onSourcesChange || (() => {})
|
||||
this.onVectorLayersChange = opts.onVectorLayersChange || (() => {})
|
||||
|
||||
this._sources = {}
|
||||
this._vectorLayers = {}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
analyzeMap(map: Map) {
|
||||
const previousSources = { ...this._sources }
|
||||
|
||||
Object.keys(map.style.sourceCaches).forEach(sourceId => {
|
||||
//NOTE: This heavily depends on the internal API of Maplibre GL
|
||||
//so this breaks between Maplibre GL JS releases
|
||||
this._sources[sourceId] = map.style.sourceCaches[sourceId]._source.vectorLayerIds as string[];
|
||||
})
|
||||
|
||||
if(!isEqual(previousSources, this._sources)) {
|
||||
this.onSourcesChange(this._sources)
|
||||
}
|
||||
|
||||
this.throttledAnalyzeVectorLayerFields(map)
|
||||
}
|
||||
|
||||
analyzeVectorLayerFields(map: Map) {
|
||||
const previousVectorLayers = { ...this._vectorLayers }
|
||||
|
||||
Object.keys(this._sources).forEach(sourceId => {
|
||||
(this._sources[sourceId] || []).forEach(vectorLayerId => {
|
||||
const knownProperties = this._vectorLayers[vectorLayerId] || {}
|
||||
const params = { sourceLayer: vectorLayerId }
|
||||
map.querySourceFeatures(sourceId, params as any).forEach(feature => {
|
||||
Object.keys(feature.properties).forEach(propertyName => {
|
||||
const knownPropertyValues = knownProperties[propertyName] || {}
|
||||
knownPropertyValues[feature.properties[propertyName]] = {}
|
||||
knownProperties[propertyName] = knownPropertyValues
|
||||
})
|
||||
})
|
||||
|
||||
this._vectorLayers[vectorLayerId] = knownProperties
|
||||
})
|
||||
})
|
||||
|
||||
if(!isEqual(previousVectorLayers, this._vectorLayers)) {
|
||||
this.onVectorLayersChange(this._vectorLayers)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Access all known sources and their vector tile ids */
|
||||
get sources() {
|
||||
return this._sources
|
||||
}
|
||||
|
||||
get vectorLayers() {
|
||||
return this._vectorLayers
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user