forked from MapComplete/MapComplete
		
	chore: refactoring, linting, removing obsolete files
This commit is contained in:
		
							parent
							
								
									b7a4930583
								
							
						
					
					
						commit
						2bc2a6cddf
					
				
					 54 changed files with 125 additions and 457 deletions
				
			
		|  | @ -27,32 +27,30 @@ export class PreferredRasterLayerSelector { | |||
|         this._availableLayers = availableLayers | ||||
|         this._queryParameter = queryParameter | ||||
|         this._preferredBackgroundLayer = preferredBackgroundLayer | ||||
|         const self = this | ||||
| 
 | ||||
|         this._rasterLayerSetting.addCallbackD((layer) => { | ||||
|             this._queryParameter.setData(layer.properties.id) | ||||
|         }) | ||||
| 
 | ||||
|         this._queryParameter.addCallbackAndRunD((_) => { | ||||
|             const isApplied = self.updateLayer() | ||||
|         this._queryParameter.addCallbackAndRunD(() => { | ||||
|             const isApplied = this.updateLayer() | ||||
|             if (!isApplied) { | ||||
|                 // A different layer was set as background
 | ||||
|                 // We remove this queryParameter instead
 | ||||
|                 self._queryParameter.setData(undefined) | ||||
|                 this._queryParameter.setData(undefined) | ||||
|                 return true // Unregister
 | ||||
|             } | ||||
|         }) | ||||
| 
 | ||||
|         this._preferredBackgroundLayer.addCallbackD((_) => self.updateLayer()) | ||||
|         this._preferredBackgroundLayer.addCallbackD(() => this.updateLayer()) | ||||
| 
 | ||||
|         rasterLayerSetting.addCallbackAndRunD((layer) => { | ||||
|             if (AvailableRasterLayers.globalLayers.find((l) => l.id === layer.properties.id)) { | ||||
|                 return | ||||
|             } | ||||
|             this._availableLayers.store.addCallbackD((_) => self.updateLayer()) | ||||
|             this._availableLayers.store.addCallbackD(() => this.updateLayer()) | ||||
|             return true // unregister
 | ||||
|         }) | ||||
|         self.updateLayer() | ||||
|         this.updateLayer() | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  |  | |||
|  | @ -83,10 +83,9 @@ export default class FeaturePropertiesStore { | |||
|     } | ||||
| 
 | ||||
|     public trackFeatureSource(source: FeatureSource) { | ||||
|         const self = this | ||||
|         source.features.addCallbackAndRunD((features) => { | ||||
|             for (const feature of features) { | ||||
|                 self.trackFeature(<any>feature) | ||||
|                 this.trackFeature(<any>feature) | ||||
|             } | ||||
|         }) | ||||
|     } | ||||
|  |  | |||
|  | @ -24,7 +24,7 @@ export default class PerLayerFeatureSourceSplitter<T extends FeatureSource = Fea | |||
|          * Keeps track of the ids that are included per layer. | ||||
|          * Used to know if the downstream feature source needs to be pinged | ||||
|          */ | ||||
|         let layerIndexes: ReadonlySet<string>[] = layers.map((_) => new Set<string>()) | ||||
|         let layerIndexes: ReadonlySet<string>[] = layers.map(() => new Set<string>()) | ||||
|         this.perLayer = knownLayers | ||||
|         const layerSources = new Map<string, UIEventSource<Feature[]>>() | ||||
|         const constructStore = | ||||
|  | @ -47,8 +47,8 @@ export default class PerLayerFeatureSourceSplitter<T extends FeatureSource = Fea | |||
|              * Indexed on layer-position | ||||
|              * Will be true if a new id pops up | ||||
|              */ | ||||
|             const hasChanged: boolean[] = layers.map((_) => false) | ||||
|             const newIndices: Set<string>[] = layers.map((_) => new Set<string>()) | ||||
|             const hasChanged: boolean[] = layers.map(() => false) | ||||
|             const newIndices: Set<string>[] = layers.map(() => new Set<string>()) | ||||
|             const noLayerFound: Feature[] = [] | ||||
| 
 | ||||
|             for (const layer of layers) { | ||||
|  |  | |||
|  | @ -23,11 +23,10 @@ export default class FeatureSourceMerger<Src extends FeatureSource = FeatureSour | |||
|     constructor(...sources: Src[]) { | ||||
|         this._featuresById = new UIEventSource<Map<string, Feature>>(new Map<string, Feature>()) | ||||
|         this.featuresById = this._featuresById | ||||
|         const self = this | ||||
|         sources = Utils.NoNull(sources) | ||||
|         for (const source of sources) { | ||||
|             source.features.addCallback(() => { | ||||
|                 self.addDataFromSources(sources) | ||||
|                 this.addDataFromSources(sources) | ||||
|             }) | ||||
|         } | ||||
|         this._sources = sources | ||||
|  |  | |||
|  | @ -38,8 +38,7 @@ export class NewGeometryFromChangesFeatureSource implements WritableFeatureSourc | |||
|         this._seenChanges = new Set<ChangeDescription>() | ||||
|         this._features = this.features.data | ||||
|         this._backend = changes.backend | ||||
|         const self = this | ||||
|         changes.pendingChanges.addCallbackAndRunD((changes) => self.handleChanges(changes)) | ||||
|         changes.pendingChanges.addCallbackAndRunD((changes) => this.handleChanges(changes)) | ||||
|     } | ||||
| 
 | ||||
|     private addNewFeature(feature: Feature) { | ||||
|  |  | |||
|  | @ -161,7 +161,6 @@ export default class OsmFeatureSource extends FeatureSourceMerger { | |||
|                 this.options?.fullNodeDatabase?.handleOsmJson(osmJson, z, x, y) | ||||
|                 let features = <Feature<any, { id: string }>[]>OsmToGeoJson( | ||||
|                     osmJson, | ||||
|                     // @ts-ignore
 | ||||
|                     { | ||||
|                         flatProperties: true, | ||||
|                     } | ||||
|  | @ -175,7 +174,7 @@ export default class OsmFeatureSource extends FeatureSourceMerger { | |||
|                 ) | ||||
| 
 | ||||
|                 for (let i = 0; i < features.length; i++) { | ||||
|                     features[i] = await this.patchIncompleteRelations(features[i], osmJson) | ||||
|                     features[i] = await this.patchIncompleteRelations(features[i], <any> osmJson) | ||||
|                 } | ||||
|                 features = Utils.NoNull(features) | ||||
|                 features.forEach((f) => { | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ import { BBox } from "../../BBox" | |||
| import { Utils } from "../../../Utils" | ||||
| import { Feature } from "geojson" | ||||
| import { GeoOperations } from "../../GeoOperations" | ||||
| import DynamicTileSource, { UpdatableDynamicTileSource } from "./DynamicTileSource" | ||||
| import { UpdatableDynamicTileSource } from "./DynamicTileSource" | ||||
| 
 | ||||
| /** | ||||
|  * The PolygonSourceMerger receives various small pieces of bigger polygons and stitches them together. | ||||
|  |  | |||
|  | @ -370,7 +370,7 @@ export class GeoOperations { | |||
|     ): Feature<LineString | MultiLineString>[] { | ||||
|         if (way.geometry.type === "Polygon") { | ||||
|             const poly: Feature<Polygon> = <Feature<Polygon>>way | ||||
|             return poly.geometry.coordinates.map((linestringCoors, i) => { | ||||
|             return poly.geometry.coordinates.map(linestringCoors => { | ||||
|                 return <Feature<LineString>>{ | ||||
|                     type: "Feature", | ||||
|                     geometry: { | ||||
|  |  | |||
|  | @ -46,7 +46,7 @@ export default class GenericImageProvider extends ImageProvider { | |||
|         return undefined | ||||
|     } | ||||
| 
 | ||||
|     public DownloadAttribution(_) { | ||||
|     public DownloadAttribution() { | ||||
|         return undefined | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -46,7 +46,6 @@ export default class InsertPointIntoWayAction { | |||
|         console.log("Attempting to snap:", { geojson, projected, projectedCoor, index }) | ||||
|         // We check that it isn't close to an already existing point
 | ||||
|         let reusedPointId = undefined | ||||
|         let reusedPointCoordinates: [number, number] = undefined | ||||
|         let outerring: [number, number][] | ||||
| 
 | ||||
|         if (geojson.geometry.type === "LineString") { | ||||
|  | @ -62,7 +61,6 @@ export default class InsertPointIntoWayAction { | |||
|         ) { | ||||
|             // We reuse this point instead!
 | ||||
|             reusedPointId = this._snapOnto.nodes[index] | ||||
|             reusedPointCoordinates = this._snapOnto.coordinates[index] | ||||
|         } | ||||
|         const next = outerring[index + 1] | ||||
|         if ( | ||||
|  | @ -71,14 +69,13 @@ export default class InsertPointIntoWayAction { | |||
|         ) { | ||||
|             // We reuse this point instead!
 | ||||
|             reusedPointId = this._snapOnto.nodes[index + 1] | ||||
|             reusedPointCoordinates = this._snapOnto.coordinates[index + 1] | ||||
|         } | ||||
|         if (reusedPointId !== undefined) { | ||||
|             return undefined | ||||
|         } | ||||
| 
 | ||||
|         const locations = [ | ||||
|             ...this._snapOnto.coordinates?.map(([lat, lon]) => <[number, number]>[lon, lat]), | ||||
|             ...(this._snapOnto.coordinates ?? []).map(([lat, lon]) => <[number, number]>[lon, lat]), | ||||
|         ] | ||||
|         const ids = [...this._snapOnto.nodes] | ||||
| 
 | ||||
|  |  | |||
|  | @ -181,7 +181,7 @@ export class InPlaceReplacedmentRTSH extends AbstractRelationSplitHandler { | |||
|         super(input, theme, objectDownloader) | ||||
|     } | ||||
| 
 | ||||
|     async CreateChangeDescriptions(changes: Changes): Promise<ChangeDescription[]> { | ||||
|     async CreateChangeDescriptions(): Promise<ChangeDescription[]> { | ||||
|         const wayId = this._input.originalWayId | ||||
|         const relation = this._input.relation | ||||
|         const members = relation.members | ||||
|  |  | |||
|  | @ -382,7 +382,7 @@ export default class ReplaceGeometryAction extends OsmChangeAction implements Pr | |||
|         >() | ||||
|         { | ||||
|             // Lets check the unused ids: can they be detached or do they signify some relation with the object?
 | ||||
|             unusedIds.forEach(({}, id) => { | ||||
|             unusedIds.forEach((_, id) => { | ||||
|                 const info = nodeInfo.get(id) | ||||
|                 if (!(info.hasTags || info.partOfWay)) { | ||||
|                     // Nothing special here, we detach
 | ||||
|  |  | |||
|  | @ -144,9 +144,6 @@ export default class SplitAction extends OsmChangeAction { | |||
|                 // Copy the tags from the original object onto the new
 | ||||
|                 const kv = [] | ||||
|                 for (const k in originalElement.tags) { | ||||
|                     if (!originalElement.tags.hasOwnProperty(k)) { | ||||
|                         continue | ||||
|                     } | ||||
|                     if (k.startsWith("_") || k === "id") { | ||||
|                         continue | ||||
|                     } | ||||
|  |  | |||
|  | @ -1,200 +0,0 @@ | |||
| export default class AspectedRouting { | ||||
|     public readonly name: string | ||||
|     public readonly description: string | ||||
|     public readonly units: string | ||||
|     public readonly program: any | ||||
| 
 | ||||
|     public constructor(program) { | ||||
|         this.name = program.name | ||||
|         this.description = program.description | ||||
|         this.units = program.unit | ||||
|         this.program = JSON.parse(JSON.stringify(program)) | ||||
|         delete this.program.name | ||||
|         delete this.program.description | ||||
|         delete this.program.unit | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Interprets the given Aspected-routing program for the given properties | ||||
|      */ | ||||
|     public static interpret(program: any, properties: any) { | ||||
|         if (typeof program !== "object") { | ||||
|             return program | ||||
|         } | ||||
| 
 | ||||
|         let functionName /*: string*/ = undefined | ||||
|         let functionArguments /*: any */ = undefined | ||||
|         const otherValues = {} | ||||
|         // @ts-ignore
 | ||||
|         Object.entries(program).forEach((tag) => { | ||||
|             const [key, value] = tag | ||||
|             if (key.startsWith("$")) { | ||||
|                 functionName = key | ||||
|                 functionArguments = value | ||||
|             } else { | ||||
|                 otherValues[key] = value | ||||
|             } | ||||
|         }) | ||||
| 
 | ||||
|         if (functionName === undefined) { | ||||
|             return AspectedRouting.interpretAsDictionary(program, properties) | ||||
|         } | ||||
| 
 | ||||
|         if (functionName === "$multiply") { | ||||
|             return AspectedRouting.multiplyScore(properties, functionArguments) | ||||
|         } else if (functionName === "$firstMatchOf") { | ||||
|             return AspectedRouting.getFirstMatchScore(properties, functionArguments) | ||||
|         } else if (functionName === "$min") { | ||||
|             return AspectedRouting.getMinValue(properties, functionArguments) | ||||
|         } else if (functionName === "$max") { | ||||
|             return AspectedRouting.getMaxValue(properties, functionArguments) | ||||
|         } else if (functionName === "$default") { | ||||
|             return AspectedRouting.defaultV(functionArguments, otherValues, properties) | ||||
|         } else { | ||||
|             console.error( | ||||
|                 `Error: Program ${functionName} is not implemented yet. ${JSON.stringify(program)}` | ||||
|             ) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Given a 'program' without function invocation, interprets it as a dictionary | ||||
|      * | ||||
|      * E.g., given the program | ||||
|      * | ||||
|      * { | ||||
|      *     highway: { | ||||
|      *         residential: 30, | ||||
|      *         living_street: 20 | ||||
|      *     }, | ||||
|      *     surface: { | ||||
|      *         sett : 0.9 | ||||
|      *     } | ||||
|      * | ||||
|      * } | ||||
|      * | ||||
|      * in combination with the tags {highway: residential}, | ||||
|      * | ||||
|      * the result should be [30, undefined]; | ||||
|      * | ||||
|      * For the tags {highway: residential, surface: sett} we should get [30, 0.9] | ||||
|      * | ||||
|      * | ||||
|      * @param program | ||||
|      * @param tags | ||||
|      * @return {(undefined|*)[]} | ||||
|      */ | ||||
|     private static interpretAsDictionary(program, tags) { | ||||
|         // @ts-ignore
 | ||||
|         return Object.entries(tags).map((tag) => { | ||||
|             const [key, value] = tag | ||||
|             const propertyValue = program[key] | ||||
|             if (propertyValue === undefined) { | ||||
|                 return undefined | ||||
|             } | ||||
|             if (typeof propertyValue !== "object") { | ||||
|                 return propertyValue | ||||
|             } | ||||
|             // @ts-ignore
 | ||||
|             return propertyValue[value] | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     private static defaultV(subProgram, otherArgs, tags) { | ||||
|         // @ts-ignore
 | ||||
|         const normalProgram = Object.entries(otherArgs)[0][1] | ||||
|         const value = AspectedRouting.interpret(normalProgram, tags) | ||||
|         if (value !== undefined) { | ||||
|             return value | ||||
|         } | ||||
|         return AspectedRouting.interpret(subProgram, tags) | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Multiplies the default score with the proper values | ||||
|      * @param tags {object} the active tags to check against | ||||
|      * @param subprograms which should generate a list of values | ||||
|      * @returns score after multiplication | ||||
|      */ | ||||
|     private static multiplyScore(tags, subprograms) { | ||||
|         let number = 1 | ||||
| 
 | ||||
|         let subResults: any[] | ||||
|         if (subprograms.length !== undefined) { | ||||
|             subResults = AspectedRouting.concatMap(subprograms, (subprogram) => | ||||
|                 AspectedRouting.interpret(subprogram, tags) | ||||
|             ) | ||||
|         } else { | ||||
|             subResults = AspectedRouting.interpret(subprograms, tags) | ||||
|         } | ||||
| 
 | ||||
|         subResults.filter((r) => r !== undefined).forEach((r) => (number *= parseFloat(r))) | ||||
|         return number.toFixed(2) | ||||
|     } | ||||
| 
 | ||||
|     private static getFirstMatchScore(tags, order: any) { | ||||
|         /*Order should be a list of arguments after evaluation*/ | ||||
|         order = <string[]>AspectedRouting.interpret(order, tags) | ||||
|         for (const key of order) { | ||||
|             // @ts-ignore
 | ||||
|             for (const entry of Object.entries(JSON.parse(tags))) { | ||||
|                 const [tagKey, value] = entry | ||||
|                 if (key === tagKey) { | ||||
|                     // We have a match... let's evaluate the subprogram
 | ||||
|                     const evaluated = AspectedRouting.interpret(value, tags) | ||||
|                     if (evaluated !== undefined) { | ||||
|                         return evaluated | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // Not a single match found...
 | ||||
|         return undefined | ||||
|     } | ||||
| 
 | ||||
|     private static getMinValue(tags, subprogram) { | ||||
|         const minArr = subprogram | ||||
|             .map((part) => { | ||||
|                 if (typeof part === "object") { | ||||
|                     const calculatedValue = this.interpret(part, tags) | ||||
|                     return parseFloat(calculatedValue) | ||||
|                 } else { | ||||
|                     return parseFloat(part) | ||||
|                 } | ||||
|             }) | ||||
|             .filter((v) => !isNaN(v)) | ||||
|         return Math.min(...minArr) | ||||
|     } | ||||
| 
 | ||||
|     private static getMaxValue(tags, subprogram) { | ||||
|         const maxArr = subprogram | ||||
|             .map((part) => { | ||||
|                 if (typeof part === "object") { | ||||
|                     return parseFloat(AspectedRouting.interpret(part, tags)) | ||||
|                 } else { | ||||
|                     return parseFloat(part) | ||||
|                 } | ||||
|             }) | ||||
|             .filter((v) => !isNaN(v)) | ||||
|         return Math.max(...maxArr) | ||||
|     } | ||||
| 
 | ||||
|     private static concatMap(list, f): any[] { | ||||
|         const result = [] | ||||
|         list = list.map(f) | ||||
|         for (const elem of list) { | ||||
|             if (elem.length !== undefined) { | ||||
|                 // This is a list
 | ||||
|                 result.push(...elem) | ||||
|             } else { | ||||
|                 result.push(elem) | ||||
|             } | ||||
|         } | ||||
|         return result | ||||
|     } | ||||
| 
 | ||||
|     public evaluate(properties) { | ||||
|         return AspectedRouting.interpret(this.program, properties) | ||||
|     } | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue