From e404e48f29d13a62888a882c0be230f786366d35 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Mon, 24 Jan 2022 03:09:50 +0100 Subject: [PATCH 1/6] Add 'hide import notes'-filter --- Models/Constants.ts | 2 +- assets/layers/note/note.json | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Models/Constants.ts b/Models/Constants.ts index 4407fbacf..c9188fb45 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -2,7 +2,7 @@ import {Utils} from "../Utils"; export default class Constants { - public static vNumber = "0.14.2"; + public static vNumber = "0.14.3"; public static ImgurApiKey = '7070e7167f0a25a' public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85" diff --git a/assets/layers/note/note.json b/assets/layers/note/note.json index 63c447570..e96829fed 100644 --- a/assets/layers/note/note.json +++ b/assets/layers/note/note.json @@ -201,6 +201,17 @@ } } ] + }, + { + "id": "no_imports", + "options": [ + { + "osmTags": "_is_import_note=", + "question": { + "en": "Hide import notes" + } + } + ] } ] } \ No newline at end of file From 848a05a21f172cf7b8f19bb8a96c7b06483f2606 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Mon, 24 Jan 2022 16:43:50 +0100 Subject: [PATCH 2/6] Quickfix for loading external themes --- Logic/DetermineLayout.ts | 11 +--- Models/Constants.ts | 2 +- .../Conversion/LegacyJsonConvert.ts | 57 +++++++++++-------- 3 files changed, 34 insertions(+), 36 deletions(-) diff --git a/Logic/DetermineLayout.ts b/Logic/DetermineLayout.ts index 8c3907f72..67708a0b9 100644 --- a/Logic/DetermineLayout.ts +++ b/Logic/DetermineLayout.ts @@ -156,17 +156,8 @@ export default class DetermineLayout { try { let parsed = await Utils.downloadJson(link) - console.log("Got ", parsed) - parsed = new FixLegacyTheme().convertStrict({ - tagRenderings: SharedTagRenderings.SharedTagRenderingJson, - sharedLayers: new Map() // FIXME: actually add the layers - }, parsed, "While loading a dynamic theme") - - - parsed.id = link; - - try { + parsed.id = link; const layoutToUse = DetermineLayout.prepCustomTheme(parsed) return new LayoutConfig(layoutToUse,false).patchImages(link, JSON.stringify(layoutToUse)); } catch (e) { diff --git a/Models/Constants.ts b/Models/Constants.ts index c9188fb45..df2e0f0d6 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -2,7 +2,7 @@ import {Utils} from "../Utils"; export default class Constants { - public static vNumber = "0.14.3"; + public static vNumber = "0.14.4"; public static ImgurApiKey = '7070e7167f0a25a' public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85" diff --git a/Models/ThemeConfig/Conversion/LegacyJsonConvert.ts b/Models/ThemeConfig/Conversion/LegacyJsonConvert.ts index 4be0c136a..7b7596646 100644 --- a/Models/ThemeConfig/Conversion/LegacyJsonConvert.ts +++ b/Models/ThemeConfig/Conversion/LegacyJsonConvert.ts @@ -180,20 +180,19 @@ class AddMiniMap extends DesugaringStep { } return false; } - + convert(state: DesugaringContext, layerConfig: LayerConfigJson, context: string): { result: LayerConfigJson; errors: string[]; warnings: string[] } { - - const hasMinimap = layerConfig.tagRenderings?.some(tr => AddMiniMap.hasMinimap( tr)) ?? true + const hasMinimap = layerConfig.tagRenderings?.some(tr => AddMiniMap.hasMinimap(tr)) ?? true if (!hasMinimap) { layerConfig = {...layerConfig} layerConfig.tagRenderings = [...layerConfig.tagRenderings] layerConfig.tagRenderings.push(state.tagRenderings.get("minimap")) } - + return { - errors:[], + errors: [], warnings: [], result: layerConfig }; @@ -448,9 +447,13 @@ export class UpdateLegacyLayer extends DesugaringStep { } } } + + oldThemeConfig.layers = Utils.NoNull(oldThemeConfig.layers) + return { errors: [], warnings: [], @@ -874,8 +880,8 @@ class AddDependencyLayersToTheme extends DesugaringStep { const knownTagRenderings: Map = state.tagRenderings; const errors = []; const warnings = []; - const layers: LayerConfigJson[] = theme.layers; // Layers should be expanded at this point - + const layers: LayerConfigJson[] = theme.layers; // Layers should be expanded at this point + knownTagRenderings.forEach((value, key) => { value.id = key; }) @@ -943,6 +949,7 @@ class SubstituteLayer extends Conversion<(string | LayerConfigJson), LayerConfig convert(state: DesugaringContext, json: string | LayerConfigJson, context: string): { result: LayerConfigJson[]; errors: string[]; warnings: string[] } { const errors = [] const warnings = [] + console.log("Substituting layer ", json) if (typeof json === "string") { const found = state.sharedLayers.get(json) if (found === undefined) { @@ -1011,10 +1018,10 @@ class AddDefaultLayers extends DesugaringStep { for (const publicLayer of AllKnownLayouts.AllPublicLayers()) { const id = publicLayer.id const config = state.sharedLayers.get(id) - if(Constants.added_by_default.indexOf(id) >= 0){ + if (Constants.added_by_default.indexOf(id) >= 0) { continue; } - if(config === undefined){ + if (config === undefined) { // This is a layer which is coded within a public theme, not as separate .json continue } @@ -1031,7 +1038,7 @@ class AddDefaultLayers extends DesugaringStep { } json.layers.push(v) } - + return { result: json, errors, @@ -1042,33 +1049,33 @@ class AddDefaultLayers extends DesugaringStep { } export class ApplyOverrideAll extends DesugaringStep { - + constructor() { - super("Applies 'overrideAll' onto every 'layer'. The 'overrideAll'-field is removed afterwards",["overrideAll","layers"]); + super("Applies 'overrideAll' onto every 'layer'. The 'overrideAll'-field is removed afterwards", ["overrideAll", "layers"]); } convert(state: DesugaringContext, json: LayoutConfigJson, context: string): { result: LayoutConfigJson; errors: string[]; warnings: string[] } { - + const overrideAll = json.overrideAll; - if(overrideAll === undefined){ - return {result :json, warnings: [], errors: []} + if (overrideAll === undefined) { + return {result: json, warnings: [], errors: []} } - + json = {...json} - + delete json.overrideAll const newLayers = [] for (let layer of json.layers) { layer = {...layer} - Utils.Merge(overrideAll, layer) + Utils.Merge(overrideAll, layer) newLayers.push(layer) } json.layers = newLayers - - - return {result :json, warnings: [], errors: []}; + + + return {result: json, warnings: [], errors: []}; } - + } export class PrepareTheme extends Fuse { @@ -1080,7 +1087,7 @@ export class PrepareTheme extends Fuse { new OnEvery("layers", new PrepareLayer()), new ApplyOverrideAll(), new AddDefaultLayers(), - + new AddDependencyLayersToTheme(), new OnEvery("layers", new AddMiniMap()) ); From a1136991f0e6cc339902ddb5049f6c1efc1e7b3e Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Mon, 24 Jan 2022 17:20:40 +0100 Subject: [PATCH 3/6] Remove console.log --- Models/ThemeConfig/Conversion/LegacyJsonConvert.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/Models/ThemeConfig/Conversion/LegacyJsonConvert.ts b/Models/ThemeConfig/Conversion/LegacyJsonConvert.ts index 7b7596646..86bc5e084 100644 --- a/Models/ThemeConfig/Conversion/LegacyJsonConvert.ts +++ b/Models/ThemeConfig/Conversion/LegacyJsonConvert.ts @@ -949,7 +949,6 @@ class SubstituteLayer extends Conversion<(string | LayerConfigJson), LayerConfig convert(state: DesugaringContext, json: string | LayerConfigJson, context: string): { result: LayerConfigJson[]; errors: string[]; warnings: string[] } { const errors = [] const warnings = [] - console.log("Substituting layer ", json) if (typeof json === "string") { const found = state.sharedLayers.get(json) if (found === undefined) { From 06f9f2d94c50714a19c625c7847f28e02ce9d000 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Mon, 24 Jan 2022 19:55:02 +0100 Subject: [PATCH 4/6] Remove image rewriting for custom themes --- Logic/DetermineLayout.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Logic/DetermineLayout.ts b/Logic/DetermineLayout.ts index 67708a0b9..ec2dff7e1 100644 --- a/Logic/DetermineLayout.ts +++ b/Logic/DetermineLayout.ts @@ -159,7 +159,7 @@ export default class DetermineLayout { try { parsed.id = link; const layoutToUse = DetermineLayout.prepCustomTheme(parsed) - return new LayoutConfig(layoutToUse,false).patchImages(link, JSON.stringify(layoutToUse)); + return new LayoutConfig(layoutToUse,false) } catch (e) { console.error(e) DetermineLayout.ShowErrorOnCustomTheme( From b61c0a11807585a1832ff410be362e74ae2a810b Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Tue, 25 Jan 2022 00:46:57 +0100 Subject: [PATCH 5/6] Fix: remember previous, externally loaded themes --- Logic/Osm/OsmPreferences.ts | 32 ++++++++++++++- Logic/State/UserRelatedState.ts | 73 ++++++++++++++++++--------------- test.ts | 6 --- 3 files changed, 71 insertions(+), 40 deletions(-) diff --git a/Logic/Osm/OsmPreferences.ts b/Logic/Osm/OsmPreferences.ts index fadd9c105..356615fe7 100644 --- a/Logic/Osm/OsmPreferences.ts +++ b/Logic/Osm/OsmPreferences.ts @@ -178,12 +178,40 @@ export class OsmPreferences { content: v }, function (error) { if (error) { - console.log(`Could not set preference "${k}"'`, error); + console.warn(`Could not set preference "${k}"'`, error); return; } - console.log(`Preference ${k} written!`); + console.debug(`Preference ${k} written!`); }); } + + public ClearPreferences(){ + let isRunning = false; + const self = this; + this.preferences.addCallbackAndRun(prefs => { + if(Object.keys(prefs).length == 0){ + return; + } + if (isRunning) { + return + } + isRunning = true + const prefixes = ["mapcomplete-installed-theme","mapcomplete-installed-themes-","mapcomplete-current-open-changeset","mapcomplete-personal-theme-layer"] + for (const key in prefs) { + for (const prefix of prefixes) { + // console.log(key) + if (key.startsWith(prefix)) { + console.log("Clearing ", key) + self.GetPreference(key, "").setData("") + + } + } + } + isRunning = false; + return true; + + }) + } } \ No newline at end of file diff --git a/Logic/State/UserRelatedState.ts b/Logic/State/UserRelatedState.ts index d77026845..8bec20f12 100644 --- a/Logic/State/UserRelatedState.ts +++ b/Logic/State/UserRelatedState.ts @@ -32,13 +32,15 @@ export default class UserRelatedState extends ElementsState { /** * WHich other themes the user previously visited */ - public installedThemes: UIEventSource<{ id: string, // The id doubles as the URL + public installedThemes: UIEventSource<{ + id: string, // The id doubles as the URL icon: string, title: any, - shortDescription: any}[]>; + shortDescription: any + }[]>; - constructor(layoutToUse: LayoutConfig, options?:{attemptLogin : true | boolean}) { + constructor(layoutToUse: LayoutConfig, options?: { attemptLogin: true | boolean }) { super(layoutToUse); this.osmConnection = new OsmConnection({ @@ -73,46 +75,53 @@ export default class UserRelatedState extends ElementsState { this.installedThemes = this.osmConnection.GetLongPreference("installed-themes").map( str => { - if(str === undefined || str === ""){ + if (str === undefined || str === "") { return [] } - try{ - return JSON.parse(str) - }catch(e){ - console.warn("Could not parse preference with installed themes due to ", e,"\nThe offending string is",str) + try { + return JSON.parse(str); + } catch (e) { + console.warn("Could not parse preference with installed themes due to ", e, "\nThe offending string is", str) return [] } - }, [],(installed => JSON.stringify(installed)) + }, [], (installed) => JSON.stringify(installed) ) - - + + const self = this; - this.osmConnection.isLoggedIn.addCallbackAndRunD(loggedIn => { - if(!loggedIn){ - return - } - if(this.layoutToUse?.id?.startsWith("http")){ - if(!this.installedThemes.data.some(installed => installed.id === this.layoutToUse.id)){ - - this.installedThemes.data.push({ - id: this.layoutToUse.id, - icon: this.layoutToUse.icon, - title: this.layoutToUse.title.translations, - shortDescription: this.layoutToUse.shortDescription.translations - }) + if (this.layoutToUse?.id?.startsWith("http")) { + this.installedThemes.addCallbackAndRun(currentThemes => { + if (currentThemes === undefined) { + // We wait till we are logged in + return } - this.installedThemes.ping() - console.log("Registered "+this.layoutToUse.id+" as installed themes") - } + + if(self.osmConnection.isLoggedIn.data == false){ + return; + } + + if (currentThemes.some(installed => installed.id === this.layoutToUse.id)) { + // Already added to the 'installed theme' list + return; + } + + console.log("Current installed themes are", this.installedThemes.data) + currentThemes.push({ + id: self.layoutToUse.id, + icon: self.layoutToUse.icon, + title: self.layoutToUse.title.translations, + shortDescription: self.layoutToUse.shortDescription.translations + }) + self.installedThemes.ping() + console.log("Registered " + self.layoutToUse.id + " as installed themes") + + }) + } - return true; - }) - - // Important: the favourite layers are initialized _after_ the installed themes, as these might contain an installedTheme this.favouriteLayers = LocalStorageSource.Get("favouriteLayers") .syncWith(this.osmConnection.GetLongPreference("favouriteLayers")) @@ -121,7 +130,7 @@ export default class UserRelatedState extends ElementsState { [], (layers) => Utils.Dedup(layers)?.join(";") ); - + this.InitializeLanguage(); new SelectedElementTagsUpdater(this) diff --git a/test.ts b/test.ts index 7b98702cd..e69de29bb 100644 --- a/test.ts +++ b/test.ts @@ -1,6 +0,0 @@ -import ValidatedTextField from "./UI/Input/ValidatedTextField"; -import {VariableUiElement} from "./UI/Base/VariableUIElement"; - -const tf = ValidatedTextField.InputForType("url") -tf.AttachTo("maindiv") -new VariableUiElement(tf.GetValue()).AttachTo("extradiv") \ No newline at end of file From 791c6c4f55aa25caa55457f52caeb7be57c47102 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Tue, 25 Jan 2022 18:20:15 +0100 Subject: [PATCH 6/6] Include route=foot in trails --- .../Sources/FilteringFeatureSource.ts | 2 +- Utils.ts | 5 +++- assets/layers/trail/trail.json | 7 ++--- package.json | 1 + scripts/generateCache.ts | 27 ++++++++++++++++--- 5 files changed, 34 insertions(+), 8 deletions(-) diff --git a/Logic/FeatureSource/Sources/FilteringFeatureSource.ts b/Logic/FeatureSource/Sources/FilteringFeatureSource.ts index 125018406..ff6a9a5c4 100644 --- a/Logic/FeatureSource/Sources/FilteringFeatureSource.ts +++ b/Logic/FeatureSource/Sources/FilteringFeatureSource.ts @@ -82,7 +82,7 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer, Ti } } - const tagsFilter = Array.from(layer.appliedFilters.data.values()); + const tagsFilter = Array.from(layer.appliedFilters?.data?.values() ?? []); for (const filter of tagsFilter ?? []) { const neededTags : TagsFilter = filter?.currentFilter if (neededTags !== undefined && !neededTags.matchesProperties(f.feature.properties)) { diff --git a/Utils.ts b/Utils.ts index 25f898575..ee835e2ea 100644 --- a/Utils.ts +++ b/Utils.ts @@ -495,7 +495,10 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be } const data = await Utils.download(url, Utils.Merge({"accept": "application/json"}, headers ?? {})) try { - return JSON.parse(data) + if(typeof data === "string"){ + return JSON.parse(data) + } + return data } catch (e) { console.error("Could not parse ", data, "due to", e, "\n", e.stack) throw e; diff --git a/assets/layers/trail/trail.json b/assets/layers/trail/trail.json index 72e945213..84416e15f 100644 --- a/assets/layers/trail/trail.json +++ b/assets/layers/trail/trail.json @@ -13,9 +13,10 @@ "and": [ { "or": [ - "route=hiking", - "route=bycicle", - "route=horse" + "route~.*foot.*", + "route~.*hiking.*", + "route~.*bycicle.*", + "route~.*horse.*" ] } ] diff --git a/package.json b/package.json index 759fe910d..ee01179db 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "generate:cache:speelplekken:mini": "ts-node scripts/generateCache.ts speelplekken 14 ../MapComplete-data/speelplekken_cache_mini/ 51.181710380278176 4.423413276672363 51.193007664772495 4.444141387939452", "generate:cache:speelplekken": "npm run generate:layeroverview && ts-node scripts/generateCache.ts speelplekken 14 ../MapComplete-data/speelplekken_cache/ 51.20 4.35 51.09 4.56", "generate:cache:natuurpunt": "npm run generate:layeroverview && ts-node scripts/generateCache.ts natuurpunt 12 ../MapComplete-data/natuurpunt_cache/ 50.40 2.1 51.54 6.4 --generate-point-overview nature_reserve,visitor_information_centre", + "generate:cache:natuurpunt:mini": "ts-node scripts/generateCache.ts natuurpunt 12 ../../git/MapComplete-data/natuurpunt_cache_mini/ 51.00792239979105 4.497699737548828 51.0353492224462554 4.539070129394531 --generate-point-overview nature_reserve,visitor_information_centre", "generate:layeroverview": "ts-node scripts/generateLayerOverview.ts --no-fail", "generate:licenses": "ts-node scripts/generateLicenseInfo.ts --no-fail", "query:licenses": "ts-node scripts/generateLicenseInfo.ts --query", diff --git a/scripts/generateCache.ts b/scripts/generateCache.ts index 9980c1959..029e014d7 100644 --- a/scripts/generateCache.ts +++ b/scripts/generateCache.ts @@ -376,9 +376,29 @@ async function main(args: string[]) { const lat1 = Number(args[5]) const lon1 = Number(args[6]) + if(isNaN(lat0)){ + throw "The first number (a latitude) is not a valid number" + } + + if(isNaN(lon0)){ + throw "The second number (a longitude) is not a valid number" + } + if(isNaN(lat1)){ + throw "The third number (a latitude) is not a valid number" + } + + if(isNaN(lon1)){ + throw "The first number (a longitude) is not a valid number" + } + + const tileRange = Tiles.TileRangeBetween(zoomlevel, lat0, lon0, lat1, lon1) + if(isNaN(tileRange.total)){ + throw "Something has gone wrong: tilerange is NAN" + } + if (tileRange.total === 0) { console.log("Tilerange has zero tiles - this is probably an error") return @@ -440,8 +460,9 @@ async function main(args: string[]) { let args = [...process.argv] args.splice(0, 2) try { - main(args).catch(e => console.error("Error building cache:", e)); + main(args) + .then(() => console.log("All done!")) + .catch(e => console.error("Error building cache:", e)); } catch (e) { console.error("Error building cache:", e) -} -console.log("All done!") \ No newline at end of file +} \ No newline at end of file