chore: refactoring, linting, removing obsolete files

This commit is contained in:
Pieter Vander Vennet 2025-06-18 22:31:50 +02:00
parent b7a4930583
commit 2bc2a6cddf
54 changed files with 125 additions and 457 deletions

View file

@ -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()
}
/**

View file

@ -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)
}
})
}

View file

@ -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) {

View file

@ -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

View file

@ -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) {

View file

@ -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) => {

View file

@ -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.

View file

@ -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: {

View file

@ -46,7 +46,7 @@ export default class GenericImageProvider extends ImageProvider {
return undefined
}
public DownloadAttribution(_) {
public DownloadAttribution() {
return undefined
}

View file

@ -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]

View file

@ -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

View file

@ -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

View file

@ -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
}

View file

@ -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)
}
}