From dc5c3461f8b156ee947d20d55c50877bdfcec90b Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Mon, 13 Dec 2021 20:51:44 +0100 Subject: [PATCH] Formatting, comments, use injected download functionality --- .../PerLayerFeatureSourceSplitter.ts | 2 +- Logic/Osm/Changes.ts | 6 ++ Logic/SimpleMetaTagger.ts | 4 +- Logic/State/UserRelatedState.ts | 2 +- UI/AutomatonGui.ts | 41 ++++++--- UI/Input/DropDown.ts | 2 +- assets/themes/postal_codes/postal_codes.json | 88 ++----------------- 7 files changed, 47 insertions(+), 98 deletions(-) diff --git a/Logic/FeatureSource/PerLayerFeatureSourceSplitter.ts b/Logic/FeatureSource/PerLayerFeatureSourceSplitter.ts index c9c58fff37..078db5fb44 100644 --- a/Logic/FeatureSource/PerLayerFeatureSourceSplitter.ts +++ b/Logic/FeatureSource/PerLayerFeatureSourceSplitter.ts @@ -44,7 +44,7 @@ export default class PerLayerFeatureSourceSplitter { for (const layer of layers.data) { if (layer.layerDef.source.osmTags.matchesProperties(f.feature.properties)) { // We have found our matching layer! - featuresPerLayer.set(layer.layerDef.id, [f]) + featuresPerLayer.get(layer.layerDef.id).push(f) if (!layer.layerDef.passAllFeatures) { // If not 'passAllFeatures', we are done for this feature break; diff --git a/Logic/Osm/Changes.ts b/Logic/Osm/Changes.ts index 9fded4d20b..71a193c1d3 100644 --- a/Logic/Osm/Changes.ts +++ b/Logic/Osm/Changes.ts @@ -374,9 +374,15 @@ export class Changes { for (const change of changes) { const id = change.type + "/" + change.id if (!objects.has(id)) { + // The object hasn't been seen before, so it doesn't exist yet and is newly created by its very definition if (change.id >= 0) { + // Might be a failed fetch for simply this object throw "Did not get an object that should be known: " + id } + if(change.changes === undefined){ + // This object is a change to a newly created object. However, we have not seen the creation changedescription yet! + throw "Not a creation of the object" + } // This is a new object that should be created states.set(id, "created") console.log("Creating object for changeDescription", change) diff --git a/Logic/SimpleMetaTagger.ts b/Logic/SimpleMetaTagger.ts index 9f7edbf47a..ba52ea850b 100644 --- a/Logic/SimpleMetaTagger.ts +++ b/Logic/SimpleMetaTagger.ts @@ -7,6 +7,7 @@ import Title from "../UI/Base/Title"; import {FixedUiElement} from "../UI/Base/FixedUiElement"; import LayerConfig from "../Models/ThemeConfig/LayerConfig"; import {CountryCoder} from "latlon2country" +import ScriptUtils from "../scripts/ScriptUtils"; export class SimpleMetaTagger { @@ -40,8 +41,7 @@ export class SimpleMetaTagger { } export class CountryTagger extends SimpleMetaTagger { - private static readonly coder = new CountryCoder("https://raw.githubusercontent.com/pietervdvn/MapComplete-data/main/latlon2country/"); - + private static readonly coder = new CountryCoder("https://raw.githubusercontent.com/pietervdvn/MapComplete-data/main/latlon2country", ScriptUtils.DownloadJSON); public runningTasks: Set; constructor() { diff --git a/Logic/State/UserRelatedState.ts b/Logic/State/UserRelatedState.ts index 1e70803529..ca69006ac4 100644 --- a/Logic/State/UserRelatedState.ts +++ b/Logic/State/UserRelatedState.ts @@ -36,7 +36,7 @@ export default class UserRelatedState extends ElementsState { public installedThemes: UIEventSource<{ layout: LayoutConfig; definition: string }[]>; - constructor(layoutToUse: LayoutConfig, options:{attemptLogin : true | boolean}) { + constructor(layoutToUse: LayoutConfig, options?:{attemptLogin : true | boolean}) { super(layoutToUse); this.osmConnection = new OsmConnection({ diff --git a/UI/AutomatonGui.ts b/UI/AutomatonGui.ts index 25fdbda896..6c3a4d3a80 100644 --- a/UI/AutomatonGui.ts +++ b/UI/AutomatonGui.ts @@ -39,7 +39,8 @@ class AutomationPanel extends Combine{ if (indices === undefined) { throw ("No tiles loaded - can not automate") } - + const openChangeset = new UIEventSource(undefined); + openChangeset.addCallbackAndRun(cs => console.log("Sync current open changeset to:", cs)) const nextTileToHandle = tileState.map(handledTiles => { for (const index of indices) { @@ -60,7 +61,9 @@ class AutomationPanel extends Combine{ } console.warn("Triggered map on nextTileToHandle",tileIndex) const start = new Date() - return AutomationPanel.TileHandler(layoutToUse, tileIndex, layerId, tagRenderingToAutomate.tagRendering, extraCommentText,(result, logMessage) => { + return AutomationPanel.TileHandler(layoutToUse, tileIndex, layerId, tagRenderingToAutomate.tagRendering, extraCommentText, + openChangeset, + (result, logMessage) => { const end = new Date() const timeNeeded = (end.getTime() - start.getTime()) / 1000; neededTimes.data.push(timeNeeded) @@ -92,15 +95,28 @@ class AutomationPanel extends Combine{ return new Combine(["Handled " + total + "/" + indices.length + " tiles: ", new List(Array.from(perResult.keys()).map(key => key + ": " + perResult.get(key))), - "Handling one tile needs " + (Math.floor(timePerTile * 100) / 100) + "s on average. Estimated time left: " + Math.floor((indices.length - total) * timePerTile) + "s" + "Handling one tile needs " + (Math.floor(timePerTile * 100) / 100) + "s on average. Estimated time left: " + Utils.toHumanTime((indices.length - total) * timePerTile) ]).SetClass("flex flex-col") })) - super([statistics, automaton, new VariableUiElement(logMessages.map(logMessages => new List(logMessages)))]) + super([statistics, automaton, + new SubtleButton(undefined, "Clear fixed").onClick(() => { + const st = tileState.data + for (const tileIndex in st) { + if(st[tileIndex] === "fixed"){ + delete st[tileIndex] + } + } + + tileState.ping(); + }), + new VariableUiElement(logMessages.map(logMessages => new List(logMessages)))]) this.SetClass("flex flex-col") } - private static TileHandler(layoutToUse: LayoutConfig, tileIndex: number, targetLayer: string, targetAction: TagRenderingConfig, extraCommentText: UIEventSource, whenDone: ((result: string, logMessage?: string) => void)): BaseUIElement { + private static TileHandler(layoutToUse: LayoutConfig, tileIndex: number, targetLayer: string, targetAction: TagRenderingConfig, extraCommentText: UIEventSource, + openChangeset: UIEventSource, + whenDone: ((result: string, logMessage?: string) => void)): BaseUIElement { const state = new MapState(layoutToUse, {attemptLogin: false}) extraCommentText.syncWith( state.changes.extraComment) @@ -186,6 +202,13 @@ class AutomationPanel extends Combine{ if (handled === 0) { whenDone("no-action","Inspected "+inspected+" elements: "+log.join("; ")) }else{ + state.osmConnection.AttemptLogin() + const openCS = state.osmConnection.GetPreference("current-open-changeset-"+layoutToUse.id) + openCS.addCallbackAndRun(cs => { + console.log("Current open Changeset is now: ", cs) + openChangeset.setData(cs) + }) + openCS.setData(openChangeset.data) state.changes.flushChanges("handled tile automatically, time to flush!") whenDone("fixed", "Updated " + handled+" elements, inspected "+inspected+": "+log.join("; ")) } @@ -198,8 +221,6 @@ class AutomationPanel extends Combine{ new VariableUiElement(stateToShow)]).SetClass("flex flex-col") } - - } @@ -234,10 +255,10 @@ class AutomatonGui { private static GenerateMainPanel(): BaseUIElement { const themeSelect = new DropDown("Select a theme", - AllKnownLayouts.layoutsList.map(l => ({value: l.id, shown: l.id})) + AllKnownLayouts.layoutsList.map(l => ({value: l.id, shown: l.id})) ) - LocalStorageSource.Get("automation-theme-id").syncWith(themeSelect.GetValue()) + LocalStorageSource.Get("automation-theme-id", "missing_streets").syncWith(themeSelect.GetValue()) const tilepath = ValidatedTextField.InputForType("url", { @@ -299,7 +320,7 @@ class AutomatonGui { tilepath, "Add an extra comment:", extraComment, - new VariableUiElement(extraComment.GetValue().map(c => "Your comment is "+c.length+"/200 characters long")).SetClass("subtle"), + new VariableUiElement(extraComment.GetValue().map(c => "Your comment is "+(c?.length??0)+"/200 characters long")).SetClass("subtle"), new VariableUiElement(tilesToRunOver.map(t => { if (t === undefined) { return "No path given or still loading..." diff --git a/UI/Input/DropDown.ts b/UI/Input/DropDown.ts index fe8f8bc987..58b22e4908 100644 --- a/UI/Input/DropDown.ts +++ b/UI/Input/DropDown.ts @@ -54,9 +54,9 @@ export class DropDown extends InputElement { const select = document.createElement("select") select.classList.add(...(options.select_class.split(" ") ?? [])) for (let i = 0; i < values.length; i++) { - const option = document.createElement("option") option.value = "" + i + console.log(values[i].shown) option.appendChild(Translations.W(values[i].shown).ConstructElement()) select.appendChild(option) } diff --git a/assets/themes/postal_codes/postal_codes.json b/assets/themes/postal_codes/postal_codes.json index 57f5659922..8eebda0cb0 100644 --- a/assets/themes/postal_codes/postal_codes.json +++ b/assets/themes/postal_codes/postal_codes.json @@ -24,90 +24,10 @@ "clustering": false, "overpassTimeout": 180, "layers": [ - { - "id": "postal_code_boundary", - "name": { - "en": "postal codes" - }, - "minzoom": 8, - "title": { - "render": { - "en": "Postal code {postal_code}" - } - }, - "description": {}, - "tagRenderings": [ - { - "id": "postal_code", - "render": { - "en": "The postal code is {postal_code}" - } - } - ], - "source": { - "osmTags": { - "or": [ - "boundary=postal_code", - { - "and": [ - "bounary=administrative", - "postal_code~*" - ] - } - ] - } - }, - "mapRendering": [ - { - "label": "
{postal_code}
", - "location": [ - "point", - "centroid" - ] - }, - { - "color": { - "render": "#00f" - }, - "width": { - "render": "4" - }, - "fill": "no", - "dashArray": "8 8" - } - ], - "isShown": { - "render": "yes", - "mappings": [ - { - "if": "_country!=be", - "then": "no" - } - ] - } - }, - { - "id": "wrong_postal_code", - "source": { - "osmTags": { - "and": [ - "boundary~*", - "addr:postcode~*" - ] - } - }, - "title": "Boundary relation with addr:postcode={addr:postcode}", - "mapRendering": [ - { - "color": "#f00", - "width": 1 - } - ] - }, { "id": "town_hall", "name": { - "en": "town halls" + "en": "town halls and churches" }, "minzoom": 12, "title": { @@ -115,7 +35,7 @@ "en": "Town hall {name}" } }, - "calculatedTags": [ + "#calculatedTags": [ "_postal_code_properties=(() => { const f = feat.overlapWith('postal_code_boundary'); if(f.length===0){return {};}; const p = f[0]?.feat?.properties; return {id:p.id, postal_code: p.postal_code, _closest_town_hall: p._closest_town_hall}; })()", "_postal_code=feat.get('_postal_code_properties')?.postal_code", "_postal_code_center_distance=feat.distanceTo(feat.get('_postal_code_properties').id)" @@ -124,7 +44,9 @@ "tagRenderings": [], "presets": [], "source": { - "osmTags": "amenity=townhall" + "osmTags": { + "or": ["amenity=townhall","building=church"] + } }, "mapRendering": [ {