From b68bf7b95029a3161b5471daebf12997c767349f Mon Sep 17 00:00:00 2001 From: Arno Deceuninck Date: Thu, 15 Jul 2021 09:34:00 +0200 Subject: [PATCH 01/11] Download cached features as geojson --- InitUiElements.ts | 2 ++ State.ts | 2 ++ UI/BigComponents/LayerSelection.ts | 5 +++++ UI/GeoJsonExport.ts | 15 +++++++++++++++ Utils.ts | 8 ++++++++ 5 files changed, 32 insertions(+) create mode 100644 UI/GeoJsonExport.ts diff --git a/InitUiElements.ts b/InitUiElements.ts index 0f1143eba..97dd2b02c 100644 --- a/InitUiElements.ts +++ b/InitUiElements.ts @@ -427,6 +427,8 @@ export class InitUiElements { state.locationControl, state.selectedElement); + State.state.featurePipeline = source; + new ShowDataLayer(source.features, State.state.leafletMap, State.state.layoutToUse); const selectedFeatureHandler = new SelectedFeatureHandler(Hash.hash, State.state.selectedElement, source, State.state.osmApiFeatureSource); diff --git a/State.ts b/State.ts index 8e4322d65..7793485aa 100644 --- a/State.ts +++ b/State.ts @@ -19,6 +19,7 @@ import TitleHandler from "./Logic/Actors/TitleHandler"; import PendingChangesUploader from "./Logic/Actors/PendingChangesUploader"; import {Relation} from "./Logic/Osm/ExtractRelations"; import OsmApiFeatureSource from "./Logic/FeatureSource/OsmApiFeatureSource"; +import FeaturePipeline from "./Logic/FeatureSource/FeaturePipeline"; /** * Contains the global state: a bunch of UI-event sources @@ -95,6 +96,7 @@ export default class State { public readonly featureSwitchIsDebugging: UIEventSource; public readonly featureSwitchShowAllQuestions: UIEventSource; public readonly featureSwitchApiURL: UIEventSource; + public readonly featurePipeline: FeaturePipeline; /** diff --git a/UI/BigComponents/LayerSelection.ts b/UI/BigComponents/LayerSelection.ts index e28294709..11237fa32 100644 --- a/UI/BigComponents/LayerSelection.ts +++ b/UI/BigComponents/LayerSelection.ts @@ -7,6 +7,8 @@ import Translations from "../i18n/Translations"; import LayerConfig from "../../Customizations/JSON/LayerConfig"; import BaseUIElement from "../BaseUIElement"; import {Translation} from "../i18n/Translation"; +import {SubtleButton} from "../Base/SubtleButton"; +import {exportAsGeoJson} from "../GeoJsonExport"; /** * Shows the panel with all layers and a toggle for each of them @@ -74,6 +76,9 @@ export default class LayerSelection extends Combine { ); } + const downloadButton = new SubtleButton("./assets/svg/floppy.svg", "Download visible data as geojson") + downloadButton.onClick(() => exportAsGeoJson(State.state.featurePipeline)) // TODO: Define this + checkboxes.push(downloadButton) super(checkboxes) this.SetStyle("display:flex;flex-direction:column;") diff --git a/UI/GeoJsonExport.ts b/UI/GeoJsonExport.ts new file mode 100644 index 000000000..c18baed17 --- /dev/null +++ b/UI/GeoJsonExport.ts @@ -0,0 +1,15 @@ +import FeaturePipeline from "../Logic/FeatureSource/FeaturePipeline"; +import {Utils} from "../Utils"; + +export function exportAsGeoJson(featurePipeline: FeaturePipeline, options?: {metadata?: boolean}) { + let defaults = { + metadata: false + } + options = Utils.setDefaults(options, defaults); + // Select all features, ignore the freshness and other data + // TODO: Remove mapcomplete metadata (starting with underscore) + let featureList: JSON[] = featurePipeline? featurePipeline.features.data.map((feature) => feature.feature) : ["I'm empty"]; + let geojson = {type: "FeatureCollection", features: featureList} + + Utils.offerContentsAsDownloadableFile(JSON.stringify(geojson), "Geodata.json"); +} diff --git a/Utils.ts b/Utils.ts index 05ebcbaab..418f1d111 100644 --- a/Utils.ts +++ b/Utils.ts @@ -447,6 +447,14 @@ export class Utils { b: parseInt(hex.substr(5, 2), 16), } } + + public static setDefaults(options, defaults){ + let result = {}; + for (let key of defaults){ + result[key] = key in options ? options[key] : defaults[key]; + } + return result; + } } export interface TileRange { From bd07eed4824afb03d09ebf98c2fab4ce7a8b7f91 Mon Sep 17 00:00:00 2001 From: Arno Deceuninck Date: Thu, 15 Jul 2021 09:58:17 +0200 Subject: [PATCH 02/11] Remove MapComplete metadata from featurelist --- UI/GeoJsonExport.ts | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/UI/GeoJsonExport.ts b/UI/GeoJsonExport.ts index c18baed17..68037eee3 100644 --- a/UI/GeoJsonExport.ts +++ b/UI/GeoJsonExport.ts @@ -1,14 +1,31 @@ import FeaturePipeline from "../Logic/FeatureSource/FeaturePipeline"; import {Utils} from "../Utils"; -export function exportAsGeoJson(featurePipeline: FeaturePipeline, options?: {metadata?: boolean}) { +export function exportAsGeoJson(featurePipeline: FeaturePipeline, options?: { metadata?: boolean }) { let defaults = { metadata: false } options = Utils.setDefaults(options, defaults); // Select all features, ignore the freshness and other data - // TODO: Remove mapcomplete metadata (starting with underscore) - let featureList: JSON[] = featurePipeline? featurePipeline.features.data.map((feature) => feature.feature) : ["I'm empty"]; + let featureList: JSON[] = featurePipeline ? featurePipeline.features.data.map((feature) => feature.feature) : ["I'm empty"]; + + function removeMetaData(featureList: JSON[]) { + for (let i=0; i < featureList.length; i++) { + let feature = featureList[i]; + for (let property in feature.properties) { + if (property[0] == "_") { + delete featureList[i]["properties"][property]; + } + } + } + return featureList; + } + + // Remove the metadata of MapComplete (all properties starting with an underscore) + if (!options.metadata) { + removeMetaData(featureList); + } + let geojson = {type: "FeatureCollection", features: featureList} Utils.offerContentsAsDownloadableFile(JSON.stringify(geojson), "Geodata.json"); From e7ef2fb6d8116fae7edfea16b0488b00d56395c8 Mon Sep 17 00:00:00 2001 From: Arno Deceuninck Date: Thu, 15 Jul 2021 10:56:30 +0200 Subject: [PATCH 03/11] Updated documentation --- UI/BigComponents/LayerSelection.ts | 2 +- UI/GeoJsonExport.ts | 21 ++++++++++++++------- Utils.ts | 7 +++---- tslint.json | 2 +- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/UI/BigComponents/LayerSelection.ts b/UI/BigComponents/LayerSelection.ts index 11237fa32..900be9348 100644 --- a/UI/BigComponents/LayerSelection.ts +++ b/UI/BigComponents/LayerSelection.ts @@ -77,7 +77,7 @@ export default class LayerSelection extends Combine { } const downloadButton = new SubtleButton("./assets/svg/floppy.svg", "Download visible data as geojson") - downloadButton.onClick(() => exportAsGeoJson(State.state.featurePipeline)) // TODO: Define this + downloadButton.onClick(() => exportAsGeoJson(State.state.featurePipeline)) checkboxes.push(downloadButton) super(checkboxes) diff --git a/UI/GeoJsonExport.ts b/UI/GeoJsonExport.ts index 68037eee3..d3e5dc5d6 100644 --- a/UI/GeoJsonExport.ts +++ b/UI/GeoJsonExport.ts @@ -1,14 +1,25 @@ import FeaturePipeline from "../Logic/FeatureSource/FeaturePipeline"; import {Utils} from "../Utils"; -export function exportAsGeoJson(featurePipeline: FeaturePipeline, options?: { metadata?: boolean }) { +/** + * Exports given featurePipeline as a geojson FeatureLists (downloads as a json) + * @param featurePipeline The FeaturePipeline you want to export + * @param options The options object + * @param options.metadata True if you want to include the MapComplete metadata, false otherwise + */ +export function exportAsGeoJson(featurePipeline: FeaturePipeline, options: { metadata?: boolean} = {}) { let defaults = { - metadata: false + metadata: false, } options = Utils.setDefaults(options, defaults); + // Select all features, ignore the freshness and other data let featureList: JSON[] = featurePipeline ? featurePipeline.features.data.map((feature) => feature.feature) : ["I'm empty"]; + /** + * Removes the metadata of MapComplete (all properties starting with an underscore) + * @param featureList JsonList containing features, output object + */ function removeMetaData(featureList: JSON[]) { for (let i=0; i < featureList.length; i++) { let feature = featureList[i]; @@ -18,13 +29,9 @@ export function exportAsGeoJson(featurePipeline: FeaturePipeline, options?: { me } } } - return featureList; } - // Remove the metadata of MapComplete (all properties starting with an underscore) - if (!options.metadata) { - removeMetaData(featureList); - } + if (!options.metadata) removeMetaData(featureList); let geojson = {type: "FeatureCollection", features: featureList} diff --git a/Utils.ts b/Utils.ts index 418f1d111..683e7a8f9 100644 --- a/Utils.ts +++ b/Utils.ts @@ -449,11 +449,10 @@ export class Utils { } public static setDefaults(options, defaults){ - let result = {}; - for (let key of defaults){ - result[key] = key in options ? options[key] : defaults[key]; + for (let key in defaults){ + if (!(key in options)) options[key] = defaults[key]; } - return result; + return options; } } diff --git a/tslint.json b/tslint.json index 6a204a045..85c7437ac 100644 --- a/tslint.json +++ b/tslint.json @@ -1,5 +1,5 @@ { - "defaultSeverity": "error", + "defaultSeverity": "warn", "extends": [ "tslint:recommended", "tslint-no-circular-imports" From 62925a89ba333eb654ac67bb5084788e466050f0 Mon Sep 17 00:00:00 2001 From: Arno Deceuninck Date: Thu, 15 Jul 2021 11:13:00 +0200 Subject: [PATCH 04/11] Text in translation file + refactor --- {UI => Logic/FeatureSource}/GeoJsonExport.ts | 4 ++-- UI/BigComponents/LayerSelection.ts | 4 ++-- langs/en.json | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) rename {UI => Logic/FeatureSource}/GeoJsonExport.ts (93%) diff --git a/UI/GeoJsonExport.ts b/Logic/FeatureSource/GeoJsonExport.ts similarity index 93% rename from UI/GeoJsonExport.ts rename to Logic/FeatureSource/GeoJsonExport.ts index d3e5dc5d6..541e10373 100644 --- a/UI/GeoJsonExport.ts +++ b/Logic/FeatureSource/GeoJsonExport.ts @@ -1,5 +1,5 @@ -import FeaturePipeline from "../Logic/FeatureSource/FeaturePipeline"; -import {Utils} from "../Utils"; +import FeaturePipeline from "./FeaturePipeline"; +import {Utils} from "../../Utils"; /** * Exports given featurePipeline as a geojson FeatureLists (downloads as a json) diff --git a/UI/BigComponents/LayerSelection.ts b/UI/BigComponents/LayerSelection.ts index 900be9348..c48b36163 100644 --- a/UI/BigComponents/LayerSelection.ts +++ b/UI/BigComponents/LayerSelection.ts @@ -8,7 +8,7 @@ import LayerConfig from "../../Customizations/JSON/LayerConfig"; import BaseUIElement from "../BaseUIElement"; import {Translation} from "../i18n/Translation"; import {SubtleButton} from "../Base/SubtleButton"; -import {exportAsGeoJson} from "../GeoJsonExport"; +import {exportAsGeoJson} from "../../Logic/FeatureSource/GeoJsonExport"; /** * Shows the panel with all layers and a toggle for each of them @@ -76,7 +76,7 @@ export default class LayerSelection extends Combine { ); } - const downloadButton = new SubtleButton("./assets/svg/floppy.svg", "Download visible data as geojson") + const downloadButton = new SubtleButton("./assets/svg/floppy.svg", Translations.t.general.layerSelection.downloadGeojson.Clone()) downloadButton.onClick(() => exportAsGeoJson(State.state.featurePipeline)) checkboxes.push(downloadButton) diff --git a/langs/en.json b/langs/en.json index 7f327653c..b604850f8 100644 --- a/langs/en.json +++ b/langs/en.json @@ -147,7 +147,8 @@ "loginOnlyNeededToEdit": "if you want to edit the map", "layerSelection": { "zoomInToSeeThisLayer": "Zoom in to see this layer", - "title": "Select layers" + "title": "Select layers", + "downloadGeojson": "Download layer features as geojson" }, "weekdays": { "abbreviations": { From 46d57edea0dd7a3f4bab5b5febbda033eb2f43e4 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Thu, 15 Jul 2021 21:01:10 +0200 Subject: [PATCH 05/11] Translation sync --- assets/themes/artwork/artwork.json | 2 +- assets/themes/bicycle_library/bicycle_library.json | 6 ++++-- assets/themes/openwindpowermap/openwindpowermap.json | 11 ++++++----- langs/themes/de.json | 8 ++++---- langs/themes/en.json | 7 +++++++ langs/themes/nl.json | 7 +++++++ 6 files changed, 29 insertions(+), 12 deletions(-) diff --git a/assets/themes/artwork/artwork.json b/assets/themes/artwork/artwork.json index 7b8cc876c..c3b7b7c55 100644 --- a/assets/themes/artwork/artwork.json +++ b/assets/themes/artwork/artwork.json @@ -374,7 +374,7 @@ "en": "Is there a website with more information about this artwork?", "nl": "Op welke website kan men meer informatie vinden over dit kunstwerk?", "fr": "Sur quel site web pouvons-nous trouver plus d'informations sur cette œuvre d'art?", - "de": "Auf welcher Website gibt es mehr Informationen über dieses Kunstwerk?", + "de": "Gibt es eine Website mit weiteren Informationen über dieses Kunstwerk?", "it": "Esiste un sito web con maggiori informazioni su quest’opera?", "ru": "Есть ли сайт с более подробной информацией об этой работе?", "ja": "この作品についての詳しい情報はどのウェブサイトにありますか?", diff --git a/assets/themes/bicycle_library/bicycle_library.json b/assets/themes/bicycle_library/bicycle_library.json index 437020a3f..6d0cf61e2 100644 --- a/assets/themes/bicycle_library/bicycle_library.json +++ b/assets/themes/bicycle_library/bicycle_library.json @@ -10,7 +10,8 @@ "ja", "fr", "zh_Hant", - "nb_NO" + "nb_NO", + "de" ], "title": { "en": "Bicycle libraries", @@ -20,7 +21,8 @@ "ja": "自転車ライブラリ", "fr": "Vélothèques", "zh_Hant": "單車圖書館", - "nb_NO": "Sykkelbibliotek" + "nb_NO": "Sykkelbibliotek", + "de": "Fahrradbibliothek" }, "description": { "nl": "Een fietsbibliotheek is een plaats waar men een fiets kan lenen, vaak voor een klein bedrag per jaar. Een typisch voorbeeld zijn kinderfietsbibliotheken, waar men een fiets op maat van het kind kan lenen. Is het kind de fiets ontgroeid, dan kan het te kleine fietsje omgeruild worden voor een grotere.", diff --git a/assets/themes/openwindpowermap/openwindpowermap.json b/assets/themes/openwindpowermap/openwindpowermap.json index b1e4ecaa7..22bba27ef 100644 --- a/assets/themes/openwindpowermap/openwindpowermap.json +++ b/assets/themes/openwindpowermap/openwindpowermap.json @@ -56,7 +56,7 @@ "tagRenderings": [ { "render": { - "en": "The power output of this wind turbine is {canonical(generator:output:electricity)}." + "en": "The power output of this wind turbine is {generator:output:electricity}." }, "question": { "en": "What is the power output of this wind turbine? (e.g. 2.3 MW)" @@ -79,7 +79,7 @@ }, { "render": { - "en": "The total height (including rotor radius) of this wind turbine is {canonical(height)}." + "en": "The total height (including rotor radius) of this wind turbine is {height} metres." }, "question": { "en": "What is the total height of this wind turbine (including rotor radius), in metres?" @@ -91,7 +91,7 @@ }, { "render": { - "en": "The rotor diameter of this wind turbine is {canonical(rotor:diameter)}." + "en": "The rotor diameter of this wind turbine is {rotor:diameter} metres." }, "question": { "en": "What is the rotor diameter of this wind turbine, in metres?" @@ -129,7 +129,7 @@ } ], "units": [ - { + { "appliesToKey": [ "generator:output:electricity" ], @@ -183,7 +183,8 @@ }, { "appliesToKey": [ - "height","rotor:diameter" + "height", + "rotor:diameter" ], "applicableUnits": [ { diff --git a/langs/themes/de.json b/langs/themes/de.json index 95abb60b1..6a0b29fad 100644 --- a/langs/themes/de.json +++ b/langs/themes/de.json @@ -87,6 +87,9 @@ "shortDescription": "Eine Karte aller Sitzbänke", "description": "Diese Karte zeigt alle Sitzbänke, die in OpenStreetMap eingetragen sind: Einzeln stehende Bänke und Bänke, die zu Haltestellen oder Unterständen gehören. Mit einem OpenStreetMap-Account können Sie neue Bänke eintragen oder Detailinformationen existierender Bänke bearbeiten." }, + "bicyclelib": { + "title": "Fahrradbibliothek" + }, "bookcases": { "title": "Öffentliche Bücherschränke Karte", "description": "Ein öffentlicher Bücherschrank ist ein kleiner Bücherschrank am Straßenrand, ein Kasten, eine alte Telefonzelle oder andere Gegenstände, in denen Bücher aufbewahrt werden. Jeder kann ein Buch hinstellen oder mitnehmen. Diese Karte zielt darauf ab, all diese Bücherschränke zu sammeln. Sie können neue Bücherschränke in der Nähe entdecken und mit einem kostenlosen OpenStreetMap-Account schnell Ihre Lieblingsbücherschränke hinzufügen." @@ -327,8 +330,5 @@ "toilets": { "title": "Offene Toilette Karte", "description": "Eine Karte der öffentlichen Toiletten" - }, - "bicyclelib": { - "title": "Fahrradbibliothek" } -} +} \ No newline at end of file diff --git a/langs/themes/en.json b/langs/themes/en.json index 48852d5a4..f5db488b9 100644 --- a/langs/themes/en.json +++ b/langs/themes/en.json @@ -1143,6 +1143,13 @@ "human": " gigawatts" } } + }, + "1": { + "applicableUnits": { + "0": { + "human": " meter" + } + } } } }, diff --git a/langs/themes/nl.json b/langs/themes/nl.json index 7966e9e2d..44bf09b5f 100644 --- a/langs/themes/nl.json +++ b/langs/themes/nl.json @@ -919,6 +919,13 @@ "human": " gigawatt" } } + }, + "1": { + "applicableUnits": { + "0": { + "human": " meter" + } + } } } }, From 294bdbfd9247ef99f5798881cbb5fadb76f0bad4 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Fri, 16 Jul 2021 00:49:50 +0200 Subject: [PATCH 06/11] Add missing license info --- assets/svg/license_info.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/assets/svg/license_info.json b/assets/svg/license_info.json index 1ef8f94c8..db044b683 100644 --- a/assets/svg/license_info.json +++ b/assets/svg/license_info.json @@ -582,5 +582,15 @@ "sources": [ "https://www.mapillary.com/" ] + }, + { + "authors": [ + "The Tango! Desktop Project" + ], + "path": "floppy.svg", + "license": "CC0", + "sources": [ + "https://commons.wikimedia.org/wiki/File:Media-floppy.svg" + ] } ] \ No newline at end of file From 0af3a91fde5c9a72457d565d5a061145eb112eaa Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Fri, 16 Jul 2021 00:57:33 +0200 Subject: [PATCH 07/11] Fix licenses, small improvement to icon --- assets/svg/crosshair-locked.svg | 69 ++++++++++++++++----------------- assets/svg/license_info.json | 14 ++++++- 2 files changed, 47 insertions(+), 36 deletions(-) diff --git a/assets/svg/crosshair-locked.svg b/assets/svg/crosshair-locked.svg index b1a741c28..d8d04340c 100644 --- a/assets/svg/crosshair-locked.svg +++ b/assets/svg/crosshair-locked.svg @@ -25,9 +25,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="2.8284271" - inkscape:cx="67.47399" - inkscape:cy="29.788021" + inkscape:zoom="5.6568542" + inkscape:cx="27.044982" + inkscape:cy="77.667126" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" @@ -68,40 +68,39 @@ inkscape:groupmode="layer" id="layer1" transform="translate(0,-270.54165)"> - - - - - + id="g827"> + + inkscape:connector-curvature="0" + id="path817" + d="M 3.2841366,283.77082 H 1.0418969" + style="fill:none;stroke:#5555ec;stroke-width:2.09723878;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.98823529" /> + + + + diff --git a/assets/svg/license_info.json b/assets/svg/license_info.json index 1ef8f94c8..f82b5fb71 100644 --- a/assets/svg/license_info.json +++ b/assets/svg/license_info.json @@ -162,6 +162,18 @@ "license": "CC0; trivial", "sources": [] }, + { + "authors": [], + "path": "crosshair-empty.svg", + "license": "CC0; trivial", + "sources": [] + }, + { + "authors": [], + "path": "crosshair-locked.svg", + "license": "CC0; trivial", + "sources": [] + }, { "authors": [ "Dave Gandy" @@ -204,7 +216,7 @@ "license": "CC0", "sources": [ "https://commons.wikimedia.org/wiki/File:Media-floppy.svg", - " http://tango.freedesktop.org/Tango_Desktop_Project" + "http://tango.freedesktop.org/Tango_Desktop_Project" ] }, { From abd7db100dd290e9f5a826532bfe7cffb717c116 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Fri, 16 Jul 2021 01:42:09 +0200 Subject: [PATCH 08/11] Finish the export functionality: move logic around a bit, add license information for reusers, wire the functionality as feature switch --- Customizations/JSON/LayoutConfig.ts | 2 ++ Customizations/JSON/LayoutConfigJson.ts | 2 ++ Logic/FeatureSource/FeatureSource.ts | 38 +++++++++++++++++++++++- Logic/FeatureSource/GeoJsonExport.ts | 39 ------------------------- State.ts | 10 +++++-- Svg.ts | 2 +- UI/BigComponents/ExportDataButton.ts | 21 +++++++++++++ UI/BigComponents/LayerControlPanel.ts | 36 ++++++++++++++--------- UI/BigComponents/LayerSelection.ts | 6 ---- langs/en.json | 7 +++-- 10 files changed, 98 insertions(+), 65 deletions(-) delete mode 100644 Logic/FeatureSource/GeoJsonExport.ts create mode 100644 UI/BigComponents/ExportDataButton.ts diff --git a/Customizations/JSON/LayoutConfig.ts b/Customizations/JSON/LayoutConfig.ts index 12b9d5f76..e76c68ac8 100644 --- a/Customizations/JSON/LayoutConfig.ts +++ b/Customizations/JSON/LayoutConfig.ts @@ -42,6 +42,7 @@ export default class LayoutConfig { public readonly enableGeolocation: boolean; public readonly enableBackgroundLayerSelection: boolean; public readonly enableShowAllQuestions: boolean; + public readonly enableExportButton: boolean; public readonly customCss?: string; /* How long is the cache valid, in seconds? @@ -152,6 +153,7 @@ export default class LayoutConfig { this.enableAddNewPoints = json.enableAddNewPoints ?? true; this.enableBackgroundLayerSelection = json.enableBackgroundLayerSelection ?? true; this.enableShowAllQuestions = json.enableShowAllQuestions ?? false; + this.enableExportButton = json.enableExportButton ?? false; this.customCss = json.customCss; this.cacheTimeout = json.cacheTimout ?? (60 * 24 * 60 * 60) diff --git a/Customizations/JSON/LayoutConfigJson.ts b/Customizations/JSON/LayoutConfigJson.ts index 374de70e0..d36a8463d 100644 --- a/Customizations/JSON/LayoutConfigJson.ts +++ b/Customizations/JSON/LayoutConfigJson.ts @@ -15,6 +15,7 @@ import UnitConfigJson from "./UnitConfigJson"; * General remark: a type (string | any) indicates either a fixed or a translatable string. */ export interface LayoutConfigJson { + /** * The id of this layout. * @@ -335,4 +336,5 @@ export interface LayoutConfigJson { enableGeolocation?: boolean; enableBackgroundLayerSelection?: boolean; enableShowAllQuestions?: boolean; + enableExportButton?: boolean; } diff --git a/Logic/FeatureSource/FeatureSource.ts b/Logic/FeatureSource/FeatureSource.ts index ba568271e..171db39f6 100644 --- a/Logic/FeatureSource/FeatureSource.ts +++ b/Logic/FeatureSource/FeatureSource.ts @@ -1,9 +1,45 @@ import {UIEventSource} from "../UIEventSource"; +import {Utils} from "../../Utils"; export default interface FeatureSource { - features: UIEventSource<{feature: any, freshness: Date}[]>; + features: UIEventSource<{ feature: any, freshness: Date }[]>; /** * Mainly used for debuging */ name: string; +} + +export class FeatureSourceUtils { + + /** + * Exports given featurePipeline as a geojson FeatureLists (downloads as a json) + * @param featurePipeline The FeaturePipeline you want to export + * @param options The options object + * @param options.metadata True if you want to include the MapComplete metadata, false otherwise + */ + public static extractGeoJson(featurePipeline: FeatureSource, options: { metadata?: boolean } = {}) { + let defaults = { + metadata: false, + } + options = Utils.setDefaults(options, defaults); + + // Select all features, ignore the freshness and other data + let featureList: any[] = featurePipeline.features.data.map((feature) => feature.feature); + + if (!options.metadata) { + for (let i = 0; i < featureList.length; i++) { + let feature = featureList[i]; + for (let property in feature.properties) { + if (property[0] == "_") { + delete featureList[i]["properties"][property]; + } + } + } + } + return {type: "FeatureCollection", features: featureList} + + + } + + } \ No newline at end of file diff --git a/Logic/FeatureSource/GeoJsonExport.ts b/Logic/FeatureSource/GeoJsonExport.ts deleted file mode 100644 index 541e10373..000000000 --- a/Logic/FeatureSource/GeoJsonExport.ts +++ /dev/null @@ -1,39 +0,0 @@ -import FeaturePipeline from "./FeaturePipeline"; -import {Utils} from "../../Utils"; - -/** - * Exports given featurePipeline as a geojson FeatureLists (downloads as a json) - * @param featurePipeline The FeaturePipeline you want to export - * @param options The options object - * @param options.metadata True if you want to include the MapComplete metadata, false otherwise - */ -export function exportAsGeoJson(featurePipeline: FeaturePipeline, options: { metadata?: boolean} = {}) { - let defaults = { - metadata: false, - } - options = Utils.setDefaults(options, defaults); - - // Select all features, ignore the freshness and other data - let featureList: JSON[] = featurePipeline ? featurePipeline.features.data.map((feature) => feature.feature) : ["I'm empty"]; - - /** - * Removes the metadata of MapComplete (all properties starting with an underscore) - * @param featureList JsonList containing features, output object - */ - function removeMetaData(featureList: JSON[]) { - for (let i=0; i < featureList.length; i++) { - let feature = featureList[i]; - for (let property in feature.properties) { - if (property[0] == "_") { - delete featureList[i]["properties"][property]; - } - } - } - } - - if (!options.metadata) removeMetaData(featureList); - - let geojson = {type: "FeatureCollection", features: featureList} - - Utils.offerContentsAsDownloadableFile(JSON.stringify(geojson), "Geodata.json"); -} diff --git a/State.ts b/State.ts index 7793485aa..90289bcab 100644 --- a/State.ts +++ b/State.ts @@ -96,6 +96,10 @@ export default class State { public readonly featureSwitchIsDebugging: UIEventSource; public readonly featureSwitchShowAllQuestions: UIEventSource; public readonly featureSwitchApiURL: UIEventSource; + public readonly featureSwitchEnableExport: UIEventSource; + + + public readonly featurePipeline: FeaturePipeline; @@ -127,7 +131,7 @@ export default class State { public welcomeMessageOpenedTab = QueryParameters.GetQueryParameter("tab", "0", `The tab that is shown in the welcome-message. 0 = the explanation of the theme,1 = OSM-credits, 2 = sharescreen, 3 = more themes, 4 = about mapcomplete (user must be logged in and have >${Constants.userJourney.mapCompleteHelpUnlock} changesets)`).map( str => isNaN(Number(str)) ? 0 : Number(str), [], n => "" + n ); - + constructor(layoutToUse: LayoutConfig) { const self = this; @@ -201,6 +205,8 @@ export default class State { "Disables/Enables the geolocation button"); this.featureSwitchShowAllQuestions = featSw("fs-all-questions", (layoutToUse) => layoutToUse?.enableShowAllQuestions ?? false, "Always show all questions"); + this.featureSwitchEnableExport = featSw("fs-export",(layoutToUse) => layoutToUse?.enableExportButton ?? false, + "If set, enables the 'download'-button to download everything as geojson") this.featureSwitchIsTesting = QueryParameters.GetQueryParameter("test", "false", "If true, 'dryrun' mode is activated. The app will behave as normal, except that changes to OSM will be printed onto the console instead of actually uploaded to osm.org") @@ -212,7 +218,7 @@ export default class State { this.featureSwitchApiURL = QueryParameters.GetQueryParameter("backend","osm", "The OSM backend to use - can be used to redirect mapcomplete to the testing backend when using 'osm-test'") - + } { // Some other feature switches diff --git a/Svg.ts b/Svg.ts index 0266e43e8..5684fc4b5 100644 --- a/Svg.ts +++ b/Svg.ts @@ -94,7 +94,7 @@ export default class Svg { public static crosshair_empty_svg() { return new Img(Svg.crosshair_empty, true);} public static crosshair_empty_ui() { return new FixedUiElement(Svg.crosshair_empty_img);} - public static crosshair_locked = " image/svg+xml " + public static crosshair_locked = " image/svg+xml " public static crosshair_locked_img = Img.AsImageElement(Svg.crosshair_locked) public static crosshair_locked_svg() { return new Img(Svg.crosshair_locked, true);} public static crosshair_locked_ui() { return new FixedUiElement(Svg.crosshair_locked_img);} diff --git a/UI/BigComponents/ExportDataButton.ts b/UI/BigComponents/ExportDataButton.ts new file mode 100644 index 000000000..9a161de9f --- /dev/null +++ b/UI/BigComponents/ExportDataButton.ts @@ -0,0 +1,21 @@ +import {SubtleButton} from "../Base/SubtleButton"; +import Svg from "../../Svg"; +import Translations from "../i18n/Translations"; +import State from "../../State"; +import {FeatureSourceUtils} from "../../Logic/FeatureSource/FeatureSource"; +import {Utils} from "../../Utils"; +import Combine from "../Base/Combine"; + +export class ExportDataButton extends Combine { + constructor() { + const t = Translations.t.general.download + const button = new SubtleButton(Svg.floppy_ui(), t.downloadGeojson.Clone().SetClass("font-bold")) + .onClick(() => { + const geojson = FeatureSourceUtils.extractGeoJson(State.state.featurePipeline) + const name = State.state.layoutToUse.data.id; + Utils.offerContentsAsDownloadableFile(JSON.stringify(geojson), `MapComplete_${name}_export_${new Date().toISOString().substr(0,19)}.geojson`); + }) + + super([button, t.licenseInfo.Clone().SetClass("link-underline")]) + } +} \ No newline at end of file diff --git a/UI/BigComponents/LayerControlPanel.ts b/UI/BigComponents/LayerControlPanel.ts index 42a3eda12..c8837fbcc 100644 --- a/UI/BigComponents/LayerControlPanel.ts +++ b/UI/BigComponents/LayerControlPanel.ts @@ -2,11 +2,12 @@ import State from "../../State"; import BackgroundSelector from "./BackgroundSelector"; import LayerSelection from "./LayerSelection"; import Combine from "../Base/Combine"; -import {FixedUiElement} from "../Base/FixedUiElement"; import ScrollableFullScreen from "../Base/ScrollableFullScreen"; import Translations from "../i18n/Translations"; import {UIEventSource} from "../../Logic/UIEventSource"; import BaseUIElement from "../BaseUIElement"; +import Toggle from "../Input/Toggle"; +import {ExportDataButton} from "./ExportDataButton"; export default class LayerControlPanel extends ScrollableFullScreen { @@ -14,27 +15,34 @@ export default class LayerControlPanel extends ScrollableFullScreen { super(LayerControlPanel.GenTitle, LayerControlPanel.GeneratePanel, "layers", isShown); } - private static GenTitle():BaseUIElement { + private static GenTitle(): BaseUIElement { return Translations.t.general.layerSelection.title.Clone().SetClass("text-2xl break-words font-bold p-2") } - private static GeneratePanel() : BaseUIElement { - let layerControlPanel: BaseUIElement = new FixedUiElement(""); + private static GeneratePanel(): BaseUIElement { + const elements: BaseUIElement[] = [] + if (State.state.layoutToUse.data.enableBackgroundLayerSelection) { - layerControlPanel = new BackgroundSelector(); - layerControlPanel.SetStyle("margin:1em"); - layerControlPanel.onClick(() => { + const backgroundSelector = new BackgroundSelector(); + backgroundSelector.SetStyle("margin:1em"); + backgroundSelector.onClick(() => { }); + elements.push(backgroundSelector) } - if (State.state.filteredLayers.data.length > 1) { - const layerSelection = new LayerSelection(State.state.filteredLayers); - layerSelection.onClick(() => { - }); - layerControlPanel = new Combine([layerSelection, "
", layerControlPanel]); - } + elements.push(new Toggle( + new LayerSelection(State.state.filteredLayers), + undefined, + State.state.filteredLayers.map(layers => layers.length > 1) + )) - return layerControlPanel; + elements.push(new Toggle( + new ExportDataButton(), + undefined, + State.state.featureSwitchEnableExport + )) + + return new Combine(elements).SetClass("flex flex-col") } } \ No newline at end of file diff --git a/UI/BigComponents/LayerSelection.ts b/UI/BigComponents/LayerSelection.ts index c48b36163..3c7f108e8 100644 --- a/UI/BigComponents/LayerSelection.ts +++ b/UI/BigComponents/LayerSelection.ts @@ -7,8 +7,6 @@ import Translations from "../i18n/Translations"; import LayerConfig from "../../Customizations/JSON/LayerConfig"; import BaseUIElement from "../BaseUIElement"; import {Translation} from "../i18n/Translation"; -import {SubtleButton} from "../Base/SubtleButton"; -import {exportAsGeoJson} from "../../Logic/FeatureSource/GeoJsonExport"; /** * Shows the panel with all layers and a toggle for each of them @@ -76,10 +74,6 @@ export default class LayerSelection extends Combine { ); } - const downloadButton = new SubtleButton("./assets/svg/floppy.svg", Translations.t.general.layerSelection.downloadGeojson.Clone()) - downloadButton.onClick(() => exportAsGeoJson(State.state.featurePipeline)) - checkboxes.push(downloadButton) - super(checkboxes) this.SetStyle("display:flex;flex-direction:column;") diff --git a/langs/en.json b/langs/en.json index b604850f8..aac35335c 100644 --- a/langs/en.json +++ b/langs/en.json @@ -147,8 +147,11 @@ "loginOnlyNeededToEdit": "if you want to edit the map", "layerSelection": { "zoomInToSeeThisLayer": "Zoom in to see this layer", - "title": "Select layers", - "downloadGeojson": "Download layer features as geojson" + "title": "Select layers" + }, + "download": { + "downloadGeojson": "Download visible data as geojson", + "licenseInfo": "

Copyright notice

The provided is available under ODbL. Reusing this data is free for any purpose, but
  • the attribution © OpenStreetMap contributors
  • Any change to this data must be republished under the same license
. Please see the full copyright notice for details" }, "weekdays": { "abbreviations": { From 3bcd2553111e3cb91d470c75abefc389b097c361 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Fri, 16 Jul 2021 02:06:33 +0200 Subject: [PATCH 09/11] Add fake user switch to mimick a logged in user; fixes #432 --- Docs/URL_Parameters.md | 248 +++++++++++++++++++++---------------- Logic/Osm/OsmConnection.ts | 20 ++- State.ts | 39 +++--- preferences.ts | 2 +- test/OsmConnection.spec.ts | 2 +- 5 files changed, 182 insertions(+), 129 deletions(-) diff --git a/Docs/URL_Parameters.md b/Docs/URL_Parameters.md index 6f299adcf..5c3158fd7 100644 --- a/Docs/URL_Parameters.md +++ b/Docs/URL_Parameters.md @@ -20,126 +20,158 @@ the URL-parameters are stated in the part between the `?` and the `#`. There are Finally, the URL-hash is the part after the `#`. It is `node/1234` in this case. - layer-control-toggle ----------------------- - - Whether or not the layer control is shown The default value is _false_ - - - tab ------ - - The tab that is shown in the welcome-message. 0 = the explanation of the theme,1 = OSM-credits, 2 = sharescreen, 3 = more themes, 4 = about mapcomplete (user must be logged in and have >50 changesets) The default value is _0_ - - - z ---- - - The initial/current zoom level The default value is _0_ - - - lat ------ - - The initial/current latitude The default value is _0_ - - - lon ------ - - The initial/current longitude of the app The default value is _0_ - - - fs-userbadge --------------- - - Disables/Enables the user information pill (userbadge) at the top left. Disabling this disables logging in and thus disables editing all together, effectively putting MapComplete into read-only mode. The default value is _true_ - - - fs-search ------------ - - Disables/Enables the search bar The default value is _true_ - - - fs-layers ------------ - - Disables/Enables the layer control The default value is _true_ - - - fs-add-new ------------- - - Disables/Enables the 'add new feature'-popup. (A theme without presets might not have it in the first place) The default value is _true_ - - - fs-welcome-message --------------------- - - Disables/enables the help menu or welcome message The default value is _true_ - - - fs-iframe ------------ - - Disables/Enables the iframe-popup The default value is _false_ - - - fs-more-quests ----------------- - - Disables/Enables the 'More Quests'-tab in the welcome message The default value is _true_ - - - fs-share-screen ------------------ - - Disables/Enables the 'Share-screen'-tab in the welcome message The default value is _true_ - - - fs-geolocation ----------------- - - Disables/Enables the geolocation button The default value is _true_ - - - fs-all-questions ------------------- - - Always show all questions The default value is _false_ - - - test ------- - - If true, 'dryrun' mode is activated. The app will behave as normal, except that changes to OSM will be printed onto the console instead of actually uploaded to osm.org The default value is _false_ - - - debug -------- - - If true, shows some extra debugging help such as all the available tags on every object The default value is _false_ - - - backend +backend --------- - The OSM backend to use - can be used to redirect mapcomplete to the testing backend when using 'osm-test' The default value is _osm_ +The OSM backend to use - can be used to redirect mapcomplete to the testing backend when using 'osm-test' The default value is _osm_ - custom-css +test +------ + +If true, 'dryrun' mode is activated. The app will behave as normal, except that changes to OSM will be printed onto the console instead of actually uploaded to osm.org The default value is _false_ + + +layout +-------- + +The layout to load into MapComplete The default value is __ + + +userlayout ------------ - If specified, the custom css from the given link will be loaded additionaly The default value is __ +If not 'false', a custom (non-official) theme is loaded. This custom layout can be done in multiple ways: + +- The hash of the URL contains a base64-encoded .json-file containing the theme definition +- The hash of the URL contains a lz-compressed .json-file, as generated by the custom theme generator +- The parameter itself is an URL, in which case that URL will be downloaded. It should point to a .json of a theme The default value is _false_ - background +layer-control-toggle +---------------------- + +Whether or not the layer control is shown The default value is _false_ + + +tab +----- + +The tab that is shown in the welcome-message. 0 = the explanation of the theme,1 = OSM-credits, 2 = sharescreen, 3 = more themes, 4 = about mapcomplete (user must be logged in and have >50 changesets) The default value is _0_ + + +z +--- + +The initial/current zoom level The default value is _14_ + + +lat +----- + +The initial/current latitude The default value is _51.2095_ + + +lon +----- + +The initial/current longitude of the app The default value is _3.2228_ + + +fs-userbadge +-------------- + +Disables/Enables the user information pill (userbadge) at the top left. Disabling this disables logging in and thus disables editing all together, effectively putting MapComplete into read-only mode. The default value is _true_ + + +fs-search +----------- + +Disables/Enables the search bar The default value is _true_ + + +fs-layers +----------- + +Disables/Enables the layer control The default value is _true_ + + +fs-add-new ------------ - The id of the background layer to start with The default value is _osm_ +Disables/Enables the 'add new feature'-popup. (A theme without presets might not have it in the first place) The default value is _true_ +fs-welcome-message +-------------------- + +Disables/enables the help menu or welcome message The default value is _true_ + + +fs-iframe +----------- + +Disables/Enables the iframe-popup The default value is _false_ + + +fs-more-quests +---------------- + +Disables/Enables the 'More Quests'-tab in the welcome message The default value is _true_ + + +fs-share-screen +----------------- + +Disables/Enables the 'Share-screen'-tab in the welcome message The default value is _true_ + + +fs-geolocation +---------------- + +Disables/Enables the geolocation button The default value is _true_ + + +fs-all-questions +------------------ + +Always show all questions The default value is _false_ + + +fs-export +----------- + +If set, enables the 'download'-button to download everything as geojson The default value is _false_ + + +fake-user +----------- + +If true, 'dryrun' mode is activated and a fake user account is loaded The default value is _false_ + + +debug +------- + +If true, shows some extra debugging help such as all the available tags on every object The default value is _false_ + + +custom-css +------------ + +If specified, the custom css from the given link will be loaded additionaly The default value is __ + + +background +------------ + +The id of the background layer to start with The default value is _osm_ + + +oauth_token +------------- + +Used to complete the login No default value set layer- ------------------ diff --git a/Logic/Osm/OsmConnection.ts b/Logic/Osm/OsmConnection.ts index 37c8fa1d2..92a0823f6 100644 --- a/Logic/Osm/OsmConnection.ts +++ b/Logic/Osm/OsmConnection.ts @@ -47,6 +47,7 @@ export class OsmConnection { public auth; public userDetails: UIEventSource; public isLoggedIn: UIEventSource + private fakeUser: boolean; _dryRun: boolean; public preferencesHandler: OsmPreferences; public changesetHandler: ChangesetHandler; @@ -59,12 +60,15 @@ export class OsmConnection { url: string }; - constructor(dryRun: boolean, oauth_token: UIEventSource, + constructor(dryRun: boolean, + fakeUser: boolean, + oauth_token: UIEventSource, // Used to keep multiple changesets open and to write to the correct changeset layoutName: string, singlePage: boolean = true, osmConfiguration: "osm" | "osm-test" = 'osm' ) { + this.fakeUser = fakeUser; this._singlePage = singlePage; this._oauth_config = OsmConnection.oauth_configs[osmConfiguration] ?? OsmConnection.oauth_configs.osm; console.debug("Using backend", this._oauth_config.url) @@ -72,7 +76,15 @@ export class OsmConnection { this._iframeMode = Utils.runningFromConsole ? false : window !== window.top; this.userDetails = new UIEventSource(new UserDetails(this._oauth_config.url), "userDetails"); - this.userDetails.data.dryRun = dryRun; + this.userDetails.data.dryRun = dryRun || fakeUser; + if(fakeUser){ + const ud = this.userDetails.data; + ud.csCount = 5678 + ud.loggedIn= true; + ud.unreadMessages = 0 + ud.name = "Fake user" + ud.totalMessages = 42; + } const self =this; this.isLoggedIn = this.userDetails.map(user => user.loggedIn).addCallback(isLoggedIn => { if(self.userDetails.data.loggedIn == false && isLoggedIn == true){ @@ -138,6 +150,10 @@ export class OsmConnection { } public AttemptLogin() { + if(this.fakeUser){ + console.log("AttemptLogin called, but ignored as fakeUser is set") + return; + } const self = this; console.log("Trying to log in..."); this.updateAuthObject(); diff --git a/State.ts b/State.ts index 90289bcab..a5bad6706 100644 --- a/State.ts +++ b/State.ts @@ -59,8 +59,8 @@ export default class State { public favouriteLayers: UIEventSource; public layerUpdater: OverpassFeatureSource; - - public osmApiFeatureSource : OsmApiFeatureSource ; + + public osmApiFeatureSource: OsmApiFeatureSource; public filteredLayers: UIEventSource<{ @@ -81,7 +81,7 @@ export default class State { * Keeps track of relations: which way is part of which other way? * Set by the overpass-updater; used in the metatagging */ - public readonly knownRelations = new UIEventSource>(undefined, "Relation memberships") + public readonly knownRelations = new UIEventSource>(undefined, "Relation memberships") public readonly featureSwitchUserbadge: UIEventSource; public readonly featureSwitchSearch: UIEventSource; @@ -96,8 +96,8 @@ export default class State { public readonly featureSwitchIsDebugging: UIEventSource; public readonly featureSwitchShowAllQuestions: UIEventSource; public readonly featureSwitchApiURL: UIEventSource; - public readonly featureSwitchEnableExport: UIEventSource; - + public readonly featureSwitchEnableExport: UIEventSource; + public readonly featureSwitchFakeUser: UIEventSource; public readonly featurePipeline: FeaturePipeline; @@ -131,7 +131,7 @@ export default class State { public welcomeMessageOpenedTab = QueryParameters.GetQueryParameter("tab", "0", `The tab that is shown in the welcome-message. 0 = the explanation of the theme,1 = OSM-credits, 2 = sharescreen, 3 = more themes, 4 = about mapcomplete (user must be logged in and have >${Constants.userJourney.mapCompleteHelpUnlock} changesets)`).map( str => isNaN(Number(str)) ? 0 : Number(str), [], n => "" + n ); - + constructor(layoutToUse: LayoutConfig) { const self = this; @@ -205,20 +205,24 @@ export default class State { "Disables/Enables the geolocation button"); this.featureSwitchShowAllQuestions = featSw("fs-all-questions", (layoutToUse) => layoutToUse?.enableShowAllQuestions ?? false, "Always show all questions"); - this.featureSwitchEnableExport = featSw("fs-export",(layoutToUse) => layoutToUse?.enableExportButton ?? false, + this.featureSwitchEnableExport = featSw("fs-export", (layoutToUse) => layoutToUse?.enableExportButton ?? false, "If set, enables the 'download'-button to download everything as geojson") this.featureSwitchIsTesting = QueryParameters.GetQueryParameter("test", "false", "If true, 'dryrun' mode is activated. The app will behave as normal, except that changes to OSM will be printed onto the console instead of actually uploaded to osm.org") .map(str => str === "true", [], b => "" + b); - - this.featureSwitchIsDebugging = QueryParameters.GetQueryParameter("debug","false", + + this.featureSwitchFakeUser = QueryParameters.GetQueryParameter("fake-user", "false", + "If true, 'dryrun' mode is activated and a fake user account is loaded") + .map(str => str === "true", [], b => "" + b); + + this.featureSwitchIsDebugging = QueryParameters.GetQueryParameter("debug", "false", "If true, shows some extra debugging help such as all the available tags on every object") .map(str => str === "true", [], b => "" + b) - this.featureSwitchApiURL = QueryParameters.GetQueryParameter("backend","osm", + this.featureSwitchApiURL = QueryParameters.GetQueryParameter("backend", "osm", "The OSM backend to use - can be used to redirect mapcomplete to the testing backend when using 'osm-test'") - + } { // Some other feature switches @@ -229,18 +233,19 @@ export default class State { this.backgroundLayerId = QueryParameters.GetQueryParameter("background", - layoutToUse?.defaultBackgroundId ?? "osm", - "The id of the background layer to start with") + layoutToUse?.defaultBackgroundId ?? "osm", + "The id of the background layer to start with") } - - - if(Utils.runningFromConsole){ + + + if (Utils.runningFromConsole) { return; } this.osmConnection = new OsmConnection( this.featureSwitchIsTesting.data, + this.featureSwitchFakeUser.data, QueryParameters.GetQueryParameter("oauth_token", undefined, "Used to complete the login"), layoutToUse?.id, @@ -253,7 +258,7 @@ export default class State { this.allElements = new ElementStorage(); this.changes = new Changes(); this.osmApiFeatureSource = new OsmApiFeatureSource() - + new PendingChangesUploader(this.changes, this.selectedElement); this.mangroveIdentity = new MangroveIdentity( diff --git a/preferences.ts b/preferences.ts index 1c1773a14..a7ae07ded 100644 --- a/preferences.ts +++ b/preferences.ts @@ -12,7 +12,7 @@ import BaseUIElement from "./UI/BaseUIElement"; import Table from "./UI/Base/Table"; -const connection = new OsmConnection(false, new UIEventSource(undefined), ""); +const connection = new OsmConnection(false, false, new UIEventSource(undefined), ""); let rendered = false; diff --git a/test/OsmConnection.spec.ts b/test/OsmConnection.spec.ts index ffcb4840c..2253e56c3 100644 --- a/test/OsmConnection.spec.ts +++ b/test/OsmConnection.spec.ts @@ -15,7 +15,7 @@ export default class OsmConnectionSpec extends T { super("OsmConnectionSpec-test", [ ["login on dev", () => { - const osmConn = new OsmConnection(false, + const osmConn = new OsmConnection(false,false, new UIEventSource(undefined), "Unit test", true, From d0293fb2320123548c10fb6dc555fc2880887852 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Fri, 16 Jul 2021 02:13:41 +0200 Subject: [PATCH 10/11] Fix chrome styling bug --- UI/Popup/FeatureInfoBox.ts | 2 +- UI/Popup/TagRenderingAnswer.ts | 38 +++++++++++++++++----------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/UI/Popup/FeatureInfoBox.ts b/UI/Popup/FeatureInfoBox.ts index f35f73ceb..b456c0ab9 100644 --- a/UI/Popup/FeatureInfoBox.ts +++ b/UI/Popup/FeatureInfoBox.ts @@ -36,7 +36,7 @@ export default class FeatureInfoBox extends ScrollableFullScreen { .SetClass("break-words font-bold sm:p-0.5 md:p-1 sm:p-1.5 md:p-2"); const titleIcons = new Combine( layerConfig.titleIcons.map(icon => new TagRenderingAnswer(tags, icon, - "block w-8 h-8 align-baseline box-content sm:p-0.5") + "block w-8 h-8 align-baseline box-content sm:p-0.5", "width: 2rem;") )) .SetClass("flex flex-row flex-wrap pt-0.5 sm:pt-1 items-center mr-2") diff --git a/UI/Popup/TagRenderingAnswer.ts b/UI/Popup/TagRenderingAnswer.ts index 6c8fd257e..c8953dd01 100644 --- a/UI/Popup/TagRenderingAnswer.ts +++ b/UI/Popup/TagRenderingAnswer.ts @@ -16,31 +16,31 @@ export default class TagRenderingAnswer extends VariableUiElement { throw "Trying to generate a tagRenderingAnswer without configuration..." } super(tagsSource.map(tags => { - if(tags === undefined){ + if (tags === undefined) { return undefined; } - - if(configuration.condition){ - if(!configuration.condition.matchesProperties(tags)){ + + if (configuration.condition) { + if (!configuration.condition.matchesProperties(tags)) { return undefined; } } - - const trs = Utils.NoNull(configuration.GetRenderValues(tags)); - if(trs.length === 0){ - return undefined; - } - - const valuesToRender: BaseUIElement[] = trs.map(tr => new SubstitutedTranslation(tr, tagsSource)) - if(valuesToRender.length === 1){ - return valuesToRender[0]; - }else if(valuesToRender.length > 1){ - return new List(valuesToRender) - } - return undefined; - }).map((element : BaseUIElement) => element?.SetClass(contentClasses)?.SetStyle(contentStyle))) - this.SetClass("flex items-center flex-row text-lg link-underline tag-renering-answer") + const trs = Utils.NoNull(configuration.GetRenderValues(tags)); + if (trs.length === 0) { + return undefined; + } + + const valuesToRender: BaseUIElement[] = trs.map(tr => new SubstitutedTranslation(tr, tagsSource)) + if (valuesToRender.length === 1) { + return valuesToRender[0]; + } else if (valuesToRender.length > 1) { + return new List(valuesToRender) + } + return undefined; + }).map((element: BaseUIElement) => element?.SetClass(contentClasses)?.SetStyle(contentStyle))) + + this.SetClass("flex items-center flex-row text-lg link-underline") this.SetStyle("word-wrap: anywhere;"); } From d8287ba1c5b95dde22de0b11089ea00433eb86ed Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Fri, 16 Jul 2021 02:24:27 +0200 Subject: [PATCH 11/11] Fix minimaps --- UI/Base/Minimap.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UI/Base/Minimap.ts b/UI/Base/Minimap.ts index 2c38e8b74..a7066c9ee 100644 --- a/UI/Base/Minimap.ts +++ b/UI/Base/Minimap.ts @@ -82,7 +82,7 @@ export default class Minimap extends BaseUIElement { doubleClickZoom: this._allowMoving, keyboard: this._allowMoving, touchZoom: this._allowMoving, - zoomAnimation: this._allowMoving, + // Disabling this breaks the geojson layer - don't ask me why! zoomAnimation: this._allowMoving, fadeAnimation: this._allowMoving });