From b90e90ceb810fb71b84e72ace0f4c3fd82a19265 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Thu, 20 Apr 2023 23:13:09 +0200 Subject: [PATCH 1/6] scripts: add a small script to download data from overpass directly --- scripts/downloadFromOverpass.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 scripts/downloadFromOverpass.ts diff --git a/scripts/downloadFromOverpass.ts b/scripts/downloadFromOverpass.ts new file mode 100644 index 0000000000..acaedab579 --- /dev/null +++ b/scripts/downloadFromOverpass.ts @@ -0,0 +1,24 @@ +import Script from "./Script"; +import {TagUtils} from "../Logic/Tags/TagUtils"; +import {And} from "../Logic/Tags/And"; +import Constants from "../Models/Constants"; +import {ImmutableStore} from "../Logic/UIEventSource"; +import {BBox} from "../Logic/BBox"; +import {Overpass} from "../Logic/Osm/Overpass"; +const fs = require("fs") +class DownloadFromOverpass extends Script { + + constructor() { + super("Downloads data from openstreetmap, will save this as 'export.geojson'. All arguments will be interpreted as key=value pairs"); + } + async main(args: string[]): Promise { + const tags = new And(args.map(k => TagUtils.Tag(k))) + const overpass = new Overpass(tags,[], Constants.defaultOverpassUrls[0], new ImmutableStore(500)) + const [data, _] = await overpass.queryGeoJson(BBox.global) + fs.writeFileSync("export.geojson", JSON.stringify(data), "utf8") + console.log("Written", data.features.length,"entries") + } + +} + +new DownloadFromOverpass().run() From 6fd481264b98767611fe3ddca2941afd0976ce0c Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Thu, 20 Apr 2023 23:47:51 +0200 Subject: [PATCH 2/6] Chore: maintenance of imageAnalysis script --- scripts/generateImageAnalysis.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/generateImageAnalysis.ts b/scripts/generateImageAnalysis.ts index 7aba9aafb0..4133380a1d 100644 --- a/scripts/generateImageAnalysis.ts +++ b/scripts/generateImageAnalysis.ts @@ -28,7 +28,7 @@ export default class GenerateImageAnalysis extends Script { tag, [], "https://overpass.kumi.systems/api/interpreter", - new ImmutableStore(180), + new ImmutableStore(500), undefined, false ) @@ -110,10 +110,10 @@ export default class GenerateImageAnalysis extends Script { const msg = `${i}/${ allImages.size - } downloaded: ${d},skipped: ${s}, failed: ${f}, running: ${runningSecs}sec, ETA: ${estimatedActualMinutes}:${ + } downloaded: ${d},skipped: ${s}, failed: ${f}, running: ${Math.floor(runningSecs)}sec, ETA: ${estimatedActualMinutes}:${ estimatedActualSeconds % 60 }` - ScriptUtils.erasableLog(msg) + ScriptUtils.erasableLog( " ", msg) if (downloaded) { d++ } else { @@ -227,10 +227,10 @@ export default class GenerateImageAnalysis extends Script { } async main(args: string[]): Promise { - const datapath = args[0] ?? "../MapComplete-data/ImageLicenseInfo" + const datapath = args[0] ?? "../../git/MapComplete-data/ImageLicenseInfo" await this.downloadData(datapath) - //await this.downloadMetadata(datapath) + await this.downloadMetadata(datapath) this.analyze(datapath) } } From 0ff0f29293a119f849aca23304e0f25bbcdbe76b Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Thu, 20 Apr 2023 23:48:53 +0200 Subject: [PATCH 3/6] Docs: improve maproulette integration docs --- Docs/Integrating_Maproulette.md | 8 +++++--- .../maproulette_challenge/maproulette_challenge.json | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Docs/Integrating_Maproulette.md b/Docs/Integrating_Maproulette.md index 701b44e3d1..3cc527fc61 100644 --- a/Docs/Integrating_Maproulette.md +++ b/Docs/Integrating_Maproulette.md @@ -1,9 +1,11 @@ # Integrating MapRoulette -[MapRoulette](https://www.maproulette.org/) is a website which has challenges. A challenge is a collection of _microtasks_, i.e. mapping -tasks which can be solved in a few minutes. +[MapRoulette](https://www.maproulette.org/) is a website which has challenges. A challenge is a collection of _microtasks_, i.e. mapping tasks which can be solved in a few minutes. + +A perfect example of this is to setup such a challenge to e.g. import new points. + +> [Important: always follow the import guidelines if you want to import data.](https://wiki.openstreetmap.org/wiki/Import/Guidelines) -A perfect example of this is to setup such a challenge to e.g. import new points. [Important: always follow the import guidelines if you want to import data.](https://wiki.openstreetmap.org/wiki/Import/Guidelines) (Another approach to set up a guided import is to create a map note for every point with the [import helper](https://mapcomplete.osm.be/import_helper). This however litters the map notes and will upset mappers if used with to much points. However, this flow is easier to setup as no changes to theme files are needed, nor is a maproulette-account needed) ## The API diff --git a/assets/layers/maproulette_challenge/maproulette_challenge.json b/assets/layers/maproulette_challenge/maproulette_challenge.json index 327086c632..3ab70fdd0b 100644 --- a/assets/layers/maproulette_challenge/maproulette_challenge.json +++ b/assets/layers/maproulette_challenge/maproulette_challenge.json @@ -2,7 +2,7 @@ "id": "maproulette_challenge", "name": null, "description": { - "en": "Layer showing tasks of a single MapRoulette challenge. This layer is intended to be reused and extended in themes; refer to the documentation on how to do this.", + "en": "Layer showing tasks of a single MapRoulette challenge. This layer is intended to be reused and extended in themes; refer to [the documentation](https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Integrating_Maproulette.md) on how to do this.", "de": "Ebene mit Aufgaben einer einzelnen MapRoulette-Herausforderung. Diese Ebene soll in Themen wiederverwendet und erweitert werden; Informationen dazu finden Sie in der Dokumentation.", "nl": "Laag met taken van een MapRoulette uitdaging" }, @@ -224,4 +224,4 @@ ] } ] -} \ No newline at end of file +} From aa6902a25c4b27ef9424d0cdfb68a83f44ec7405 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Sun, 23 Apr 2023 12:58:29 +0200 Subject: [PATCH 4/6] Themes: Add 'open_now' filter to bike-shop --- assets/layers/bike_shop/bike_shop.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/assets/layers/bike_shop/bike_shop.json b/assets/layers/bike_shop/bike_shop.json index c9eae8908a..6ce9b5afbe 100644 --- a/assets/layers/bike_shop/bike_shop.json +++ b/assets/layers/bike_shop/bike_shop.json @@ -821,5 +821,8 @@ "render": "1" } } + ], + "filter": [ + "open_now" ] -} \ No newline at end of file +} From 102fe2c5e840610ef5c4ae76bab850aaf7738ef2 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Sun, 23 Apr 2023 13:22:57 +0200 Subject: [PATCH 5/6] Fix search behaviour of theme index, fix #1385 --- UI/BigComponents/MoreScreen.ts | 172 +++++++++++++++-------------- UI/BigComponents/ThemesList.svelte | 22 +--- 2 files changed, 90 insertions(+), 104 deletions(-) diff --git a/UI/BigComponents/MoreScreen.ts b/UI/BigComponents/MoreScreen.ts index 63887079d4..7ae449437e 100644 --- a/UI/BigComponents/MoreScreen.ts +++ b/UI/BigComponents/MoreScreen.ts @@ -1,17 +1,17 @@ import Svg from "../../Svg" import Combine from "../Base/Combine" -import { SubtleButton } from "../Base/SubtleButton" +import {SubtleButton} from "../Base/SubtleButton" import Translations from "../i18n/Translations" import BaseUIElement from "../BaseUIElement" -import LayoutConfig, { LayoutInformation } from "../../Models/ThemeConfig/LayoutConfig" -import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource" +import LayoutConfig, {LayoutInformation} from "../../Models/ThemeConfig/LayoutConfig" +import {ImmutableStore, Store, UIEventSource} from "../../Logic/UIEventSource" import Loc from "../../Models/Loc" import UserRelatedState from "../../Logic/State/UserRelatedState" -import { Utils } from "../../Utils" +import {Utils} from "../../Utils" import Title from "../Base/Title" import themeOverview from "../../assets/generated/theme_overview.json" -import { Translation } from "../i18n/Translation" -import { TextField } from "../Input/TextField" +import {Translation} from "../i18n/Translation" +import {TextField} from "../Input/TextField" import Locale from "../i18n/Locale" import SvelteUIElement from "../Base/SvelteUIElement" import ThemesList from "./ThemesList.svelte" @@ -37,7 +37,7 @@ export default class MoreScreen extends Combine { searchTerm = searchTerm.toLowerCase() if (searchTerm === "personal") { window.location.href = MoreScreen.createUrlFor( - { id: "personal" }, + {id: "personal"}, false, state ).data @@ -59,13 +59,13 @@ export default class MoreScreen extends Combine { (th) => th.hideFromOverview == false && th.id !== "personal" && - MoreScreen.MatchesLayoutFunc(th)(searchTerm) + MoreScreen.MatchesLayout(th, searchTerm) ) if (publicTheme !== undefined) { window.location.href = MoreScreen.createUrlFor(publicTheme, false, state).data } const hiddenTheme = MoreScreen.officialThemes.find( - (th) => th.id !== "personal" && MoreScreen.MatchesLayoutFunc(th)(searchTerm) + (th) => th.id !== "personal" && MoreScreen.MatchesLayout(th, searchTerm) ) if (hiddenTheme !== undefined) { window.location.href = MoreScreen.createUrlFor(hiddenTheme, false, state).data @@ -109,6 +109,85 @@ export default class MoreScreen extends Combine { ]) } + /** + * Creates a button linking to the given theme + * @private + */ + public static createLinkButton( + state: { + locationControl?: UIEventSource + layoutToUse?: LayoutConfig + }, + layout: { + id: string + icon: string + title: any + shortDescription: any + definition?: any + mustHaveLanguage?: boolean + }, + isCustom: boolean = false + ): BaseUIElement { + const url = MoreScreen.createUrlFor(layout, isCustom, state) + let content = new Combine([ + new Translation( + layout.title, + !isCustom && !layout.mustHaveLanguage ? "themes:" + layout.id + ".title" : undefined + ), + new Translation(layout.shortDescription)?.SetClass("subtle") ?? "", + ]).SetClass("overflow-hidden flex flex-col") + + if (state.layoutToUse === undefined) { + // Currently on the index screen: we style the buttons equally large + content = new Combine([content]).SetClass("flex flex-col justify-center h-24") + } + + return new SubtleButton(layout.icon, content, {url, newTab: false}) + } + + public static CreateProffessionalSerivesButton() { + const t = Translations.t.professional.indexPage + return new Combine([ + new Title(t.hook, 4), + t.hookMore, + new SubtleButton(undefined, t.button, {url: "./professional.html"}), + ]).SetClass("flex flex-col border border-gray-300 p-2 rounded-lg") + } + + public static MatchesLayout(layout: { + id: string + title: any + shortDescription: any + keywords?: any[] + }, search: string): boolean { + if(search === undefined){ + return true + } + search = search.toLocaleLowerCase() + if (search.length > 3 && layout.id.toLowerCase().indexOf(search) >= 0) { + return true + } + if(layout.id === "personal"){ + return false + } + const entitiesToSearch = [ + layout.shortDescription, + layout.title, + ...(layout.keywords ?? []), + ] + for (const entity of entitiesToSearch) { + if (entity === undefined) { + continue + } + const term = entity["*"] ?? entity[Locale.language.data] + if (term?.toLowerCase()?.indexOf(search) >= 0) { + return true + } + } + + return false + } + private static createUrlFor( layout: { id: string; definition?: string }, isCustom: boolean, @@ -164,79 +243,4 @@ export default class MoreScreen extends Combine { }) ?? new ImmutableStore(`${linkPrefix}`) ) } - - /** - * Creates a button linking to the given theme - * @private - */ - public static createLinkButton( - state: { - locationControl?: UIEventSource - layoutToUse?: LayoutConfig - }, - layout: { - id: string - icon: string - title: any - shortDescription: any - definition?: any - mustHaveLanguage?: boolean - }, - isCustom: boolean = false - ): BaseUIElement { - const url = MoreScreen.createUrlFor(layout, isCustom, state) - let content = new Combine([ - new Translation( - layout.title, - !isCustom && !layout.mustHaveLanguage ? "themes:" + layout.id + ".title" : undefined - ), - new Translation(layout.shortDescription)?.SetClass("subtle") ?? "", - ]).SetClass("overflow-hidden flex flex-col") - - if (state.layoutToUse === undefined) { - // Currently on the index screen: we style the buttons equally large - content = new Combine([content]).SetClass("flex flex-col justify-center h-24") - } - - return new SubtleButton(layout.icon, content, { url, newTab: false }) - } - - public static CreateProffessionalSerivesButton() { - const t = Translations.t.professional.indexPage - return new Combine([ - new Title(t.hook, 4), - t.hookMore, - new SubtleButton(undefined, t.button, { url: "./professional.html" }), - ]).SetClass("flex flex-col border border-gray-300 p-2 rounded-lg") - } - - private static MatchesLayoutFunc(layout: { - id: string - title: any - shortDescription: any - keywords?: any[] - }): (search: string) => boolean { - return (search: string) => { - search = search.toLocaleLowerCase() - if (layout.id.toLowerCase().indexOf(search) >= 0) { - return true - } - const entitiesToSearch = [ - layout.shortDescription, - layout.title, - ...(layout.keywords ?? []), - ] - for (const entity of entitiesToSearch) { - if (entity === undefined) { - continue - } - const term = entity["*"] ?? entity[Locale.language.data] - if (term?.toLowerCase()?.indexOf(search) >= 0) { - return true - } - } - - return false - } - } } diff --git a/UI/BigComponents/ThemesList.svelte b/UI/BigComponents/ThemesList.svelte index 3f4bc51a58..f4e3abb7c5 100644 --- a/UI/BigComponents/ThemesList.svelte +++ b/UI/BigComponents/ThemesList.svelte @@ -9,6 +9,7 @@ import ProfessionalServicesButton from "./ProfessionalServicesButton.svelte" import ThemeButton from "./ThemeButton.svelte" import { LayoutInformation } from "../../Models/ThemeConfig/LayoutConfig" + import MoreScreen from "./MoreScreen"; export let search: UIEventSource export let themes: LayoutInformation[] @@ -18,26 +19,7 @@ export let hideThemes: boolean = true // Filter theme based on search value - $: filteredThemes = themes.filter((theme) => { - if ($search === undefined || $search === "") return true - - const srch = $search.toLocaleLowerCase() - if (theme.id.toLowerCase().indexOf(srch) >= 0) { - return true - } - const entitiesToSearch = [theme.shortDescription, theme.title, ...(theme.keywords ?? [])] - for (const entity of entitiesToSearch) { - if (entity === undefined) { - continue - } - const term = entity["*"] ?? entity[Locale.language.data] - if (term?.toLowerCase()?.indexOf(search) >= 0) { - return true - } - } - - return false - }) + $: filteredThemes = themes.filter((theme) => MoreScreen.MatchesLayout(theme, $search))
From c674db7ef4d9f3b0998072ac0215ccbd2de76398 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Sun, 23 Apr 2023 14:26:35 +0200 Subject: [PATCH 6/6] Bump version number --- Models/Constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Models/Constants.ts b/Models/Constants.ts index f42f2cad85..1c744046bb 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -1,7 +1,7 @@ import { Utils } from "../Utils" export default class Constants { - public static vNumber = "0.27.1" + public static vNumber = "0.27.2" public static ImgurApiKey = "7070e7167f0a25a" public static readonly mapillary_client_token_v4 =