Full code cleanup

This commit is contained in:
Pieter Vander Vennet 2022-01-26 21:40:38 +01:00
parent 3a4a2a2016
commit fa971ffbbf
300 changed files with 16352 additions and 19284 deletions

View file

@ -14,7 +14,7 @@ class MetatagUpdater {
private source: FeatureSourceForLayer & Tiled;
private readonly params: ExtraFuncParams
private state: { allElements?: ElementStorage };
private readonly isDirty = new UIEventSource(false)
constructor(source: FeatureSourceForLayer & Tiled, state: { allElements?: ElementStorage }, featurePipeline: FeaturePipeline) {
@ -31,14 +31,14 @@ class MetatagUpdater {
if (oldBbox === undefined) {
self.neededLayerBboxes.set(layerId, bbox);
} else if (!bbox.isContainedIn(oldBbox)) {
self.neededLayerBboxes.set(layerId,oldBbox.unionWith(bbox))
self.neededLayerBboxes.set(layerId, oldBbox.unionWith(bbox))
}
return featurePipeline.GetFeaturesWithin(layerId, bbox)
},
memberships: featurePipeline.relationTracker
}
this.isDirty.stabilized(100).addCallback(dirty => {
if(dirty){
if (dirty) {
self.updateMetaTags()
}
})
@ -46,10 +46,10 @@ class MetatagUpdater {
}
public requestUpdate(){
public requestUpdate() {
this.isDirty.setData(true)
}
private updateMetaTags() {
const features = this.source.features.data
@ -74,7 +74,8 @@ export default class MetaTagRecalculator {
};
private _featurePipeline: FeaturePipeline;
private readonly _alreadyRegistered: Set<FeatureSourceForLayer & Tiled> = new Set<FeatureSourceForLayer & Tiled>()
private readonly _notifiers : MetatagUpdater[] = []
private readonly _notifiers: MetatagUpdater[] = []
/**
* The meta tag recalculator receives tiles of layers.
* It keeps track of which sources have had their share calculated, and which should be re-updated if some other data is loaded
@ -92,16 +93,16 @@ private readonly _notifiers : MetatagUpdater[] = []
return;
}
this._alreadyRegistered.add(source)
this._notifiers.push(new MetatagUpdater(source,this._state,this._featurePipeline))
this._notifiers.push(new MetatagUpdater(source, this._state, this._featurePipeline))
const self = this;
source.features.addCallbackAndRunD(_ => {
const layerName = source.layer.layerDef.id
for (const updater of self._notifiers ) {
for (const updater of self._notifiers) {
const neededBbox = updater.neededLayerBboxes.get(layerName)
if(neededBbox == undefined){
if (neededBbox == undefined) {
continue
}
if(source.bbox === undefined || neededBbox.overlapsWith(source.bbox)){
if (source.bbox === undefined || neededBbox.overlapsWith(source.bbox)) {
updater.requestUpdate()
}
}

View file

@ -41,7 +41,7 @@ export default class SaveTileToLocalStorageActor {
})
}
public LoadTilesFromDisk(currentBounds: UIEventSource<BBox>, location: UIEventSource<Loc>,
registerFreshness: (tileId: number, freshness: Date) => void,
registerTile: ((src: FeatureSource & Tiled) => void)) {
@ -55,7 +55,7 @@ export default class SaveTileToLocalStorageActor {
}
currentBounds.addCallbackAndRunD(bbox => {
if(self._layer.minzoomVisible > location.data.zoom){
if (self._layer.minzoomVisible > location.data.zoom) {
// Not enough zoom
return;
}
@ -119,9 +119,9 @@ export default class SaveTileToLocalStorageActor {
}
private SetIdb(tileIndex, data) {
try{
try {
IdbLocalStorage.SetDirectly(this._layer.id + "_" + tileIndex, data)
}catch(e){
} catch (e) {
console.error("Could not save tile to indexed-db: ", e, "tileIndex is:", tileIndex, "for layer", this._layer.id)
}
}

View file

@ -43,40 +43,33 @@ export default class FeaturePipeline {
public readonly timeout: UIEventSource<number>;
public readonly somethingLoaded: UIEventSource<boolean> = new UIEventSource<boolean>(false)
public readonly newDataLoadedSignal: UIEventSource<FeatureSource> = new UIEventSource<FeatureSource>(undefined)
public readonly relationTracker: RelationsTracker
/**
* Keeps track of all raw OSM-nodes.
* Only initialized if 'type_node' is defined as layer
*/
public readonly fullNodeDatabase?: FullNodeDatabaseSource
private readonly overpassUpdater: OverpassFeatureSource
private state: MapState;
public readonly relationTracker: RelationsTracker
private readonly perLayerHierarchy: Map<string, TileHierarchyMerger>;
/**
* Keeps track of the age of the loaded data.
* Has one freshness-Calculator for every layer
* @private
*/
private readonly freshnesses = new Map<string, TileFreshnessCalculator>();
private readonly oldestAllowedDate: Date;
private readonly osmSourceZoomLevel
private readonly localStorageSavers = new Map<string, SaveTileToLocalStorageActor>()
/**
* Keeps track of all raw OSM-nodes.
* Only initialized if 'type_node' is defined as layer
*/
public readonly fullNodeDatabase? : FullNodeDatabaseSource
constructor(
handleFeatureSource: (source: FeatureSourceForLayer & Tiled) => void,
state: MapState,
options? : {
options?: {
/*Used for metatagging - will receive all the sources with changeGeometry applied but without filtering*/
handleRawFeatureSource: (source: FeatureSourceForLayer) => void
}
) {
) {
this.state = state;
const self = this
@ -104,7 +97,7 @@ export default class FeaturePipeline {
return location.zoom >= minzoom;
}
);
const neededTilesFromOsm = this.getNeededTilesFromOsm(this.sufficientlyZoomed)
const perLayerHierarchy = new Map<string, TileHierarchyMerger>()
@ -114,10 +107,10 @@ export default class FeaturePipeline {
function patchedHandleFeatureSource(src: FeatureSourceForLayer & IndexedFeatureSource & Tiled) {
// This will already contain the merged features for this tile. In other words, this will only be triggered once for every tile
const withChanges = new ChangeGeometryApplicator(src, state.changes);
const srcFiltered = new FilteringFeatureSource(state, src.tileIndex,withChanges)
const srcFiltered = new FilteringFeatureSource(state, src.tileIndex, withChanges)
handleFeatureSource(srcFiltered)
if(options?.handleRawFeatureSource){
if (options?.handleRawFeatureSource) {
options.handleRawFeatureSource(withChanges)
}
self.somethingLoaded.setData(true)
@ -267,7 +260,7 @@ export default class FeaturePipeline {
})
})
if(this.fullNodeDatabase !== undefined){
if (this.fullNodeDatabase !== undefined) {
osmFeatureSource.rawDataHandlers.push((osmJson, tileId) => this.fullNodeDatabase.handleOsmJson(osmJson, tileId))
}
@ -289,7 +282,7 @@ export default class FeaturePipeline {
self.localStorageSavers.get(tile.layer.layerDef.id)?.addTile(tile)
perLayerHierarchy.get(source.layer.layerDef.id).registerTile(new RememberingSource(tile))
tile.features.addCallbackAndRunD(f => {
if(f.length === 0){
if (f.length === 0) {
return
}
self.onNewDataLoaded(tile)
@ -298,9 +291,11 @@ export default class FeaturePipeline {
}
}),
updater,
{handleLeftovers: (leftOvers) => {
console.warn("Overpass returned a few non-matched features:", leftOvers)
}})
{
handleLeftovers: (leftOvers) => {
console.warn("Overpass returned a few non-matched features:", leftOvers)
}
})
// Also load points/lines that are newly added.
@ -308,7 +303,7 @@ export default class FeaturePipeline {
newGeometry.features.addCallbackAndRun(geometries => {
console.debug("New geometries are:", geometries)
})
new RegisteringAllFromFeatureSourceActor(newGeometry, state.allElements)
// A NewGeometryFromChangesFeatureSource does not split per layer, so we do this next
new PerLayerFeatureSourceSplitter(state.filteredLayers,
@ -322,9 +317,11 @@ export default class FeaturePipeline {
},
newGeometry,
{handleLeftovers: (leftOvers) => {
console.warn("Got some leftovers from the filteredLayers: ", leftOvers)
}}
{
handleLeftovers: (leftOvers) => {
console.warn("Got some leftovers from the filteredLayers: ", leftOvers)
}
}
)
this.runningQuery = updater.runningQuery.map(
@ -337,10 +334,6 @@ export default class FeaturePipeline {
}
private onNewDataLoaded(src: FeatureSource){
this.newDataLoadedSignal.setData(src)
}
public GetAllFeaturesWithin(bbox: BBox): any[][] {
const self = this
const tiles = []
@ -369,6 +362,10 @@ export default class FeaturePipeline {
})
}
private onNewDataLoaded(src: FeatureSource) {
this.newDataLoadedSignal.setData(src)
}
private freshnessForVisibleLayers(z: number, x: number, y: number): Date {
let oldestDate = undefined;
for (const flayer of this.state.filteredLayers.data) {
@ -378,11 +375,11 @@ export default class FeaturePipeline {
if (this.state.locationControl.data.zoom < flayer.layerDef.minzoom) {
continue;
}
if(flayer.layerDef.maxAgeOfCache === 0){
if (flayer.layerDef.maxAgeOfCache === 0) {
return undefined;
}
const freshnessCalc = this.freshnesses.get(flayer.layerDef.id)
if(freshnessCalc === undefined){
if (freshnessCalc === undefined) {
console.warn("No freshness tracker found for ", flayer.layerDef.id)
return undefined
}

View file

@ -19,8 +19,8 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer, Ti
};
private readonly _alreadyRegistered = new Set<UIEventSource<any>>();
private readonly _is_dirty = new UIEventSource(false)
private previousFeatureSet : Set<any> = undefined;
private previousFeatureSet: Set<any> = undefined;
constructor(
state: {
locationControl: UIEventSource<{ zoom: number }>,
@ -54,7 +54,7 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer, Ti
self.update()
}
})
metataggingUpdated?.addCallback(_ => {
self._is_dirty.setData(true)
})
@ -66,7 +66,7 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer, Ti
const self = this;
const layer = this.upstream.layer;
const features: { feature: any; freshness: Date }[] = (this.upstream.features.data ?? []);
const includedFeatureIds = new Set<string>();
const includedFeatureIds = new Set<string>();
const newFeatures = (features ?? []).filter((f) => {
self.registerCallback(f.feature)
@ -97,29 +97,29 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer, Ti
const previousSet = this.previousFeatureSet;
this._is_dirty.setData(false)
// Is there any difference between the two sets?
if(previousSet !== undefined && previousSet.size === includedFeatureIds.size){
if (previousSet !== undefined && previousSet.size === includedFeatureIds.size) {
// The size of the sets is the same - they _might_ be identical
const newItemFound = Array.from(includedFeatureIds).some(id => !previousSet.has(id))
if(!newItemFound){
if (!newItemFound) {
// We know that:
// - The sets have the same size
// - Every item from the new set has been found in the old set
// which means they are identical!
return;
}
}
// Something new has been found!
this.features.setData(newFeatures);
}
private registerCallback(feature: any) {
const src = this.state?.allElements?.addOrGetElement(feature)
if(src == undefined){
if (src == undefined) {
return
}
if (this._alreadyRegistered.has(src)) {

View file

@ -65,7 +65,7 @@ export class NewGeometryFromChangesFeatureSource implements FeatureSource {
for (const kv of change.tags) {
feat.tags[kv.k] = kv.v
}
const geojson= feat.asGeoJson();
const geojson = feat.asGeoJson();
allElementStorage.addOrGetElement(geojson)
self.features.data.push({feature: geojson, freshness: new Date()})
self.features.ping()
@ -81,7 +81,7 @@ export class NewGeometryFromChangesFeatureSource implements FeatureSource {
continue;
}
try {
const tags = {}
for (const kv of change.tags) {

View file

@ -10,7 +10,7 @@ export default class SimpleFeatureSource implements FeatureSourceForLayer, Tiled
public readonly bbox: BBox = BBox.global;
public readonly tileIndex: number;
constructor(layer: FilteredLayer, tileIndex: number, featureSource?: UIEventSource<{ feature:any; freshness: Date }[]>) {
constructor(layer: FilteredLayer, tileIndex: number, featureSource?: UIEventSource<{ feature: any; freshness: Date }[]>) {
this.name = "SimpleFeatureSource(" + layer.layerDef.id + ")"
this.layer = layer
this.tileIndex = tileIndex ?? 0;

View file

@ -40,7 +40,7 @@ export default class DynamicGeoJsonTileSource extends DynamicTileSource {
json => {
const data = new Map<number, Set<number>>();
for (const x in json) {
if(x === "zoom"){
if (x === "zoom") {
continue
}
data.set(Number(x), new Set(json[x]))
@ -91,7 +91,7 @@ export default class DynamicGeoJsonTileSource extends DynamicTileSource {
public static RegisterWhitelist(url: string, json: any) {
const data = new Map<number, Set<number>>();
for (const x in json) {
if(x === "zoom"){
if (x === "zoom") {
continue
}
data.set(Number(x), new Set(json[x]))

View file

@ -44,11 +44,11 @@ export default class DynamicTileSource implements TileHierarchy<FeatureSourceFor
return undefined
}
const tileRange = Tiles.TileRangeBetween(zoomlevel, bounds.getNorth(), bounds.getEast(), bounds.getSouth(), bounds.getWest())
if(tileRange.total > 10000){
if (tileRange.total > 10000) {
console.error("Got a really big tilerange, bounds and location might be out of sync")
return undefined
}
const needed = Tiles.MapRange(tileRange, (x, y) => Tiles.tile_index(zoomlevel, x, y)).filter(i => !self._loadedTiles.has(i))
if (needed.length === 0) {
return undefined

View file

@ -45,8 +45,8 @@ export default class FullNodeDatabaseSource implements TileHierarchy<FeatureSour
for (const nodeId of osmWay.nodes) {
if (!this.parentWays.has(nodeId)) {
const src = new UIEventSource<OsmWay[]>([])
this.parentWays.set(nodeId,src)
const src = new UIEventSource<OsmWay[]>([])
this.parentWays.set(nodeId, src)
src.addCallback(parentWays => {
const tgs = nodesById.get(nodeId).tags
tgs ["parent_ways"] = JSON.stringify(parentWays.map(w => w.tags))

View file

@ -89,8 +89,8 @@ export default class OsmFeatureSource {
if (z > 20) {
throw "This is an absurd high zoom level"
}
if( z < 14){
if (z < 14) {
throw `Zoom ${z} is too much for OSM to handle! Use a higher zoom level!`
}