diff --git a/src/UI/InputElement/InputHelper.svelte b/src/UI/InputElement/InputHelper.svelte
index 89047aa813..3239ac3627 100644
--- a/src/UI/InputElement/InputHelper.svelte
+++ b/src/UI/InputElement/InputHelper.svelte
@@ -5,6 +5,7 @@
import type { Feature } from "geojson"
import type { SpecialVisualizationState } from "../SpecialVisualization"
+ import type { Validator } from "./Validator"
import DistanceInput from "./Helpers/DistanceInput.svelte"
export let type: ValidatorType
@@ -13,13 +14,11 @@
export let args: (string | number | boolean)[] | any = undefined
export let state: SpecialVisualizationState = undefined
let validator = Validators.get(type)
- let validatorHelper = validator.inputHelper
+ let validatorHelper: Validator = validator.inputHelper
{#if type === "distance"}
{:else if validatorHelper !== undefined}
-{:else}
-
{/if}
diff --git a/src/UI/Map/ShowDataLayer.ts b/src/UI/Map/ShowDataLayer.ts
index 4d80c6c926..434e705fd7 100644
--- a/src/UI/Map/ShowDataLayer.ts
+++ b/src/UI/Map/ShowDataLayer.ts
@@ -459,11 +459,6 @@ export default class ShowDataLayer {
preprocessPoints,
} = this._options
let onClick = this._options.onClick
- if (!onClick && selectedElement && layer.title !== undefined) {
- onClick = (feature: Feature) => {
- selectedElement?.setData(feature)
- }
- }
if (drawLines !== false) {
for (let i = 0; i < layer.lineRendering.length; i++) {
const lineRenderingConfig = layer.lineRendering[i]
diff --git a/src/UI/Popup/AutoApplyButtonVis.ts b/src/UI/Popup/AutoApplyButtonVis.ts
index 9bfa3c3659..8257745e82 100644
--- a/src/UI/Popup/AutoApplyButtonVis.ts
+++ b/src/UI/Popup/AutoApplyButtonVis.ts
@@ -2,8 +2,9 @@ import { Store, Stores, UIEventSource } from "../../Logic/UIEventSource"
import ThemeConfig from "../../Models/ThemeConfig/ThemeConfig"
import { Changes } from "../../Logic/Osm/Changes"
import {
+ SpecialVisualisationArg,
+ SpecialVisualisationParams,
SpecialVisualization,
- SpecialVisualizationState,
SpecialVisualizationSvelte,
} from "../SpecialVisualization"
import { IndexedFeatureSource } from "../../Logic/FeatureSource/FeatureSource"
@@ -31,12 +32,7 @@ export default class AutoApplyButtonVis extends SpecialVisualizationSvelte {
public readonly funcName: string = "auto_apply"
public readonly needsUrls = []
public readonly group = "data_import"
- public readonly args: {
- name: string
- defaultValue?: string
- doc: string
- required?: boolean
- }[] = [
+ public readonly args: SpecialVisualisationArg[] = [
{
name: "target_layer",
doc: "The layer that the target features will reside in",
@@ -54,6 +50,7 @@ export default class AutoApplyButtonVis extends SpecialVisualizationSvelte {
},
{
name: "text",
+ type:"translation",
doc: "The text to show on the button",
required: true,
},
@@ -86,15 +83,11 @@ export default class AutoApplyButtonVis extends SpecialVisualizationSvelte {
4. At last, add this component`
}
- constr(
- state: SpecialVisualizationState,
- tagSource: UIEventSource
>,
- argument: string[]
- ): SvelteUIElement {
- const target_layer_id = argument[0]
- const targetTagRendering = argument[2]
- const text = argument[3]
- const icon = argument[4]
+ constr({ state, tags, args }: SpecialVisualisationParams): SvelteUIElement {
+ const target_layer_id = args[0]
+ const targetTagRendering = args[2]
+ const text = args[3]
+ const icon = args[4]
const options = {
target_layer_id,
targetTagRendering,
@@ -105,7 +98,7 @@ export default class AutoApplyButtonVis extends SpecialVisualizationSvelte {
const to_parse: UIEventSource = new UIEventSource(undefined)
Stores.chronic(500, () => to_parse.data === undefined)
.map(() => {
- const applicable = tagSource.data[argument[1]]
+ const applicable = tags.data[args[1]]
if (typeof applicable === "string") {
return JSON.parse(applicable)
} else {
diff --git a/src/UI/Popup/DataExportVisualisations.ts b/src/UI/Popup/DataExportVisualisations.ts
index 81f5f3747f..dc82a9125e 100644
--- a/src/UI/Popup/DataExportVisualisations.ts
+++ b/src/UI/Popup/DataExportVisualisations.ts
@@ -1,11 +1,5 @@
-import {
- SpecialVisualization,
- SpecialVisualizationState,
- SpecialVisualizationSvelte,
-} from "../SpecialVisualization"
-import { UIEventSource } from "../../Logic/UIEventSource"
+import { SpecialVisualisationParams, SpecialVisualization, SpecialVisualizationSvelte } from "../SpecialVisualization"
import { Feature, LineString } from "geojson"
-import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
import Translations from "../i18n/Translations"
import SvelteUIElement from "../Base/SvelteUIElement"
import ExportFeatureButton from "./ExportFeatureButton.svelte"
@@ -17,13 +11,7 @@ class ExportAsGpxVis extends SpecialVisualizationSvelte {
args = []
needsUrls = []
- constr(
- state: SpecialVisualizationState,
- tags: UIEventSource>,
- argument: string[],
- feature: Feature,
- layer: LayerConfig
- ) {
+ constr({ tags, feature, layer }: SpecialVisualisationParams) {
if (feature.geometry.type !== "LineString") {
return undefined
}
@@ -48,7 +36,7 @@ class ExportAsGeojsonVis extends SpecialVisualizationSvelte {
docs = "Exports the selected feature as GeoJson-file"
args = []
- constr(state, tags, args, feature, layer) {
+ constr({ tags, feature, layer }: SpecialVisualisationParams) {
const t = Translations.t.general.download
return new SvelteUIElement(ExportFeatureButton, {
tags,
@@ -64,7 +52,7 @@ class ExportAsGeojsonVis extends SpecialVisualizationSvelte {
}
export class DataExportVisualisations {
- public static initList(): SpecialVisualization[] {
+ public static initList(): SpecialVisualizationSvelte[] {
return [new ExportAsGpxVis(), new ExportAsGeojsonVis()]
}
}
diff --git a/src/UI/Popup/DataVisualisations.ts b/src/UI/Popup/DataVisualisations.ts
index 5a721e162f..97fd3c10d3 100644
--- a/src/UI/Popup/DataVisualisations.ts
+++ b/src/UI/Popup/DataVisualisations.ts
@@ -1,11 +1,11 @@
import {
+ SpecialVisualisationArg,
+ SpecialVisualisationParams,
SpecialVisualization,
- SpecialVisualizationState,
SpecialVisualizationSvelte,
} from "../SpecialVisualization"
import { HistogramViz } from "./HistogramViz"
-import { Store, UIEventSource } from "../../Logic/UIEventSource"
-import { Feature } from "geojson"
+import { Store } from "../../Logic/UIEventSource"
import BaseUIElement from "../BaseUIElement"
import SvelteUIElement from "../Base/SvelteUIElement"
import DirectionIndicator from "../Base/DirectionIndicator.svelte"
@@ -20,15 +20,18 @@ import NextChangeViz from "../OpeningHours/NextChangeViz.svelte"
import { Unit } from "../../Models/Unit"
import AllFeaturesStatistics from "../Statistics/AllFeaturesStatistics.svelte"
import { LanguageElement } from "./LanguageElement/LanguageElement"
-import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
import { QuestionableTagRenderingConfigJson } from "../../Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson"
import { And } from "../../Logic/Tags/And"
import TagRenderingConfig from "../../Models/ThemeConfig/TagRenderingConfig"
import TagRenderingEditable from "./TagRendering/TagRenderingEditable.svelte"
import AllTagsPanel from "./AllTagsPanel/AllTagsPanel.svelte"
import CollectionTimes from "../CollectionTimes/CollectionTimes.svelte"
+import Tr from "../Base/Tr.svelte"
+import Combine from "../Base/Combine"
+import Marker from "../Map/Marker.svelte"
+import { twJoin } from "tailwind-merge"
-class DirectionIndicatorVis extends SpecialVisualization {
+class DirectionIndicatorVis extends SpecialVisualizationSvelte {
funcName = "direction_indicator"
args = []
@@ -36,13 +39,8 @@ class DirectionIndicatorVis extends SpecialVisualization {
"Gives a distance indicator and a compass pointing towards the location from your GPS-location. If clicked, centers the map on the object"
group = "data"
- constr(
- state: SpecialVisualizationState,
- tagSource: UIEventSource>,
- argument: string[],
- feature: Feature
- ): BaseUIElement {
- return new SvelteUIElement(DirectionIndicator, { state, feature })
+ constr(params: SpecialVisualisationParams): SvelteUIElement {
+ return new SvelteUIElement(DirectionIndicator, params)
}
}
@@ -65,17 +63,15 @@ class DirectionAbsolute extends SpecialVisualization {
]
group = "data"
- constr(
- state: SpecialVisualizationState,
- tagSource: UIEventSource>,
- args: string[]
- ): BaseUIElement {
+ constr({
+ tags,
+ args,
+ }: SpecialVisualisationParams): BaseUIElement {
const key = args[0] === "" ? "_direction:centerpoint" : args[0]
const offset = args[1] === "" ? 0 : Number(args[1])
return new VariableUiElement(
- tagSource
- .map((tags) => {
+ tags.map((tags) => {
console.log("Direction value", tags[key], key)
return tags[key]
})
@@ -117,14 +113,12 @@ class OpeningHoursTableVis extends SpecialVisualizationSvelte {
example =
"A normal opening hours table can be invoked with `{opening_hours_table()}`. A table for e.g. conditional access with opening hours can be `{opening_hours_table(access:conditional, no @ &LPARENS, &RPARENS)}`"
- constr(state, tagSource: UIEventSource, args) {
+ constr({ tags, args }: SpecialVisualisationParams): SvelteUIElement {
const [key, prefix, postfix] = args
const openingHoursStore: Store =
- OH.CreateOhObjectStore(tagSource, key, prefix, postfix)
+ OH.CreateOhObjectStore(tags, key, prefix, postfix)
return new SvelteUIElement(OpeningHoursWithError, {
- tags: tagSource,
- key,
- opening_hours_obj: openingHoursStore,
+ tags, key, opening_hours_obj: openingHoursStore,
})
}
}
@@ -152,11 +146,7 @@ class OpeningHoursState extends SpecialVisualizationSvelte {
},
]
- constr(
- state: SpecialVisualizationState,
- tags: UIEventSource>,
- args: string[]
- ): SvelteUIElement {
+ constr({ state, tags, args }: SpecialVisualisationParams): SvelteUIElement {
const keyToUse = args[0]
const prefix = args[1]
const postfix = args[2]
@@ -187,10 +177,10 @@ class Canonical extends SpecialVisualization {
},
]
- constr(state, tagSource, args) {
+ constr({ state, tags, args }: SpecialVisualisationParams) {
const key = args[0]
return new VariableUiElement(
- tagSource
+ tags
.map((tags) => tags[key])
.map((value) => {
if (value === undefined) {
@@ -203,7 +193,7 @@ class Canonical extends SpecialVisualization {
if (unit === undefined) {
return value
}
- const getCountry = () => tagSource.data._country
+ const getCountry = () => tags.data._country
return unit.asHumanLongValue(value, getCountry)
})
)
@@ -217,26 +207,24 @@ class StatisticsVis extends SpecialVisualizationSvelte {
"Show general statistics about all the elements currently in view. Intended to use on the `current_view`-layer. They will be split per layer"
args = []
- constr(state) {
- return new SvelteUIElement(AllFeaturesStatistics, { state })
+ constr(params: SpecialVisualisationParams) {
+ return new SvelteUIElement(AllFeaturesStatistics, params)
}
}
-class PresetDescription extends SpecialVisualization {
+class PresetDescription extends SpecialVisualizationSvelte {
funcName = "preset_description"
docs =
"Shows the extra description from the presets of the layer, if one matches. It will pick the most specific one (e.g. if preset `A` implies `B`, but `B` does not imply `A`, it'll pick B) or the first one if no ordering can be made. Might be empty"
args = []
+ group = "UI"
- constr(
- state: SpecialVisualizationState,
- tagSource: UIEventSource>
- ): BaseUIElement {
- const translation = tagSource.map((tags) => {
+ constr({ state, tags }: SpecialVisualisationParams): SvelteUIElement {
+ const translation = tags.map((tags) => {
const layer = state.theme.getMatchingLayer(tags)
return layer?.getMostMatchingPreset(tags)?.description
})
- return new VariableUiElement(translation)
+ return new SvelteUIElement(Tr, { t: translation })
}
}
@@ -244,14 +232,9 @@ class PresetTypeSelect extends SpecialVisualizationSvelte {
funcName = "preset_type_select"
docs = "An editable tag rendering which allows to change the type"
args = []
+ group = "ui"
- constr(
- state: SpecialVisualizationState,
- tags: UIEventSource>,
- argument: string[],
- selectedElement: Feature,
- layer: LayerConfig
- ): SvelteUIElement {
+ constr({ state, tags, feature, layer }: SpecialVisualisationParams,): SvelteUIElement {
const t = Translations.t.preset_type
if (layer._basedOn !== layer.id) {
console.warn("Trying to use the _original_ layer")
@@ -277,7 +260,7 @@ class PresetTypeSelect extends SpecialVisualizationSvelte {
return new SvelteUIElement(TagRenderingEditable, {
config,
tags,
- selectedElement,
+ selectedElement: feature,
state,
layer,
})
@@ -290,8 +273,8 @@ class AllTagsVis extends SpecialVisualizationSvelte {
args = []
group = "data"
- constr(state, tags: UIEventSource>, _, __, layer: LayerConfig) {
- return new SvelteUIElement(AllTagsPanel, { tags, layer })
+ constr(params: SpecialVisualisationParams) {
+ return new SvelteUIElement(AllTagsPanel, params)
}
}
@@ -302,23 +285,18 @@ class PointsInTimeVis extends SpecialVisualization {
args = [
{
name: "key",
+ type:"key",
required: true,
doc: "The key out of which the points_in_time will be parsed",
},
]
- constr(
- state: SpecialVisualizationState,
- tagSource: UIEventSource>,
- args: string[],
- feature: Feature,
- layer: LayerConfig
- ): BaseUIElement {
+ constr({ tags, args }: SpecialVisualisationParams): BaseUIElement {
const key = args[0]
- const points_in_time = tagSource.map((tags) => tags[key])
+ const points_in_time = tags.map((tags) => tags[key])
const times = points_in_time.map(
- (times) => OH.createOhObject(tagSource.data, times, tagSource.data["_country"], 1),
- [tagSource]
+ (times) => OH.createOhObject(tags.data, times, tags.data["_country"], 1),
+ [tags]
)
return new VariableUiElement(
times.map((times) => new SvelteUIElement(CollectionTimes, { times }))
@@ -326,6 +304,60 @@ class PointsInTimeVis extends SpecialVisualization {
}
}
+class KnownIcons extends SpecialVisualization {
+ docs = "Displays all icons from the specified tagRenderings (if they are known and have an icon) together, e.g. to give a summary of the dietary options"
+ needsUrls = []
+ group = "UI"
+ funcName = "show_icons"
+ args: SpecialVisualisationArg[] = [{
+ name: "labels",
+ doc: "A ';'-separated list of labels and/or ids of tagRenderings",
+ type: "key",
+ required: true,
+ }, {
+ name: "class",
+ doc: "CSS-classes of the container, space-separated",
+ type: "css",
+ required: false,
+ defaultValue: "inline-flex mx-4",
+ }]
+
+ private static readonly emojiHeights = {
+ small: "2rem",
+ medium: "3rem",
+ large: "5rem",
+ }
+
+ constr(options: SpecialVisualisationParams): BaseUIElement {
+ const labels = new Set(options.args[0].split(";").map(s => s.trim()))
+ const matchingTrs = options.layer.tagRenderings.filter(
+ tr => labels.has(tr.id) || tr.labels.some(l => labels.has(l)),
+ )
+ return new VariableUiElement(options.tags.map(tags =>
+ new Combine(matchingTrs.map(tr => {
+ const mapping = tr.GetRenderValueWithImage(tags)
+ if (!mapping?.icon) {
+ return undefined
+ }
+
+ return new SvelteUIElement(Marker, {
+ emojiHeight: KnownIcons.emojiHeights[mapping.iconClass] ?? "2rem",
+ clss: `mapping-icon-${mapping.iconClass ?? "small"}`,
+ icons: mapping.icon,
+ size: twJoin(
+ "shrink-0",
+ `mapping-icon-${mapping.iconClass ?? "small"}-height mapping-icon-${
+ mapping.iconClass ?? "small"
+ }-width`),
+
+
+ })
+ })
+ ).SetClass(options.args[1] ?? "inline-flex mx-4")
+ ))
+ }
+}
+
export class DataVisualisations {
public static initList(): SpecialVisualization[] {
return [
@@ -341,6 +373,7 @@ export class DataVisualisations {
new PresetDescription(),
new PresetTypeSelect(),
new AllTagsVis(),
+ new KnownIcons(),
]
}
}
diff --git a/src/UI/Popup/HistogramViz.ts b/src/UI/Popup/HistogramViz.ts
index 679255d652..7cfffd1f4b 100644
--- a/src/UI/Popup/HistogramViz.ts
+++ b/src/UI/Popup/HistogramViz.ts
@@ -1,5 +1,5 @@
import { Store, UIEventSource } from "../../Logic/UIEventSource"
-import { SpecialVisualization, SpecialVisualizationState } from "../SpecialVisualization"
+import { SpecialVisualisationParams, SpecialVisualization, SpecialVisualizationState } from "../SpecialVisualization"
import { Feature } from "geojson"
import SvelteUIElement from "../Base/SvelteUIElement"
import Histogram from "../BigComponents/Histogram.svelte"
@@ -14,6 +14,7 @@ export class HistogramViz extends SpecialVisualization {
args = [
{
name: "key",
+ type:"key",
doc: "The key to be read and to generate a histogram from",
required: true,
},
@@ -35,12 +36,8 @@ export class HistogramViz extends SpecialVisualization {
]
}
- constr(
- state: SpecialVisualizationState,
- tagSource: UIEventSource>,
- args: string[]
- ) {
- const values: Store = tagSource.map((tags) => {
+ constr( {tags, args}: SpecialVisualisationParams): SvelteUIElement {
+ const values: Store = tags.map((tags) => {
const value = tags[args[0]]
try {
if (value === "" || value === undefined) {
diff --git a/src/UI/Popup/ImportButtons/ConflateImportButtonViz.ts b/src/UI/Popup/ImportButtons/ConflateImportButtonViz.ts
index f72497649a..fce251a7dc 100644
--- a/src/UI/Popup/ImportButtons/ConflateImportButtonViz.ts
+++ b/src/UI/Popup/ImportButtons/ConflateImportButtonViz.ts
@@ -1,7 +1,11 @@
-import { SpecialVisualization, SpecialVisualizationState } from "../../SpecialVisualization"
+import {
+ SpecialVisualisationArg,
+ SpecialVisualisationParams,
+ SpecialVisualizationSvelte,
+ SpecialVisualizationUtils,
+} from "../../SpecialVisualization"
import { UIEventSource } from "../../../Logic/UIEventSource"
import { Feature, Geometry, LineString, Polygon } from "geojson"
-import BaseUIElement from "../../BaseUIElement"
import { ImportFlowArguments, ImportFlowUtils } from "./ImportFlow"
import Translations from "../../i18n/Translations"
import { Utils } from "../../../Utils"
@@ -14,6 +18,7 @@ import { Changes } from "../../../Logic/Osm/Changes"
import ThemeConfig from "../../../Models/ThemeConfig/ThemeConfig"
import { OsmConnection } from "../../../Logic/Osm/OsmConnection"
import { OsmTags } from "../../../Models/OsmFeature"
+import Tr from "../../Base/Tr.svelte"
export interface ConflateFlowArguments extends ImportFlowArguments {
way_to_conflate: string
@@ -22,21 +27,17 @@ export interface ConflateFlowArguments extends ImportFlowArguments {
snap_onto_layers?: string
}
-export default class ConflateImportButtonViz extends SpecialVisualization implements AutoAction {
+export default class ConflateImportButtonViz extends SpecialVisualizationSvelte implements AutoAction {
supportsAutoAction: boolean = true
needsUrls = []
group = "data_import"
public readonly funcName: string = "conflate_button"
- public readonly args: {
- name: string
- defaultValue?: string
- doc: string
- required?: boolean
- }[] = [
+ public readonly args: SpecialVisualisationArg[] = [
...ImportFlowUtils.generalArguments,
{
name: "way_to_conflate",
+ type:"key",
doc: "The key, of which the corresponding value is the id of the OSM-way that must be conflated; typically a calculatedTag",
},
]
@@ -84,32 +85,25 @@ export default class ConflateImportButtonViz extends SpecialVisualization implem
await state.changes.applyAction(action)
}
- constr(
- state: SpecialVisualizationState,
- tagSource: UIEventSource,
- argument: string[],
- feature: Feature
- ): BaseUIElement {
+ constr({ state, tags, args, feature }: SpecialVisualisationParams): SvelteUIElement {
const canBeImported =
feature.geometry.type === "LineString" ||
(feature.geometry.type === "Polygon" && feature.geometry.coordinates.length === 1)
if (!canBeImported) {
- return Translations.t.general.add.import.wrongTypeToConflate.SetClass("alert")
+ return new SvelteUIElement(Tr, { t: Translations.t.general.add.import.wrongTypeToConflate, cls: "alert" })
}
- const args: ConflateFlowArguments = Utils.ParseVisArgs(this.args, argument)
- const tagsToApply = ImportFlowUtils.getTagsToApply(tagSource, args)
- const idOfWayToReplaceGeometry = tagSource.data[args.way_to_conflate]
+ const argsParsed: ConflateFlowArguments = SpecialVisualizationUtils.parseArgs(this.args, args)
+ const tagsToApply = ImportFlowUtils.getTagsToApply(>tags, argsParsed)
+ const idOfWayToReplaceGeometry = tags.data[argsParsed.way_to_conflate]
const importFlow = new ConflateImportFlowState(
state,
>feature,
- args,
+ argsParsed,
tagsToApply,
- tagSource,
+ tags,
idOfWayToReplaceGeometry
)
- return new SvelteUIElement(WayImportFlow, {
- importFlow,
- })
+ return new SvelteUIElement(WayImportFlow, { importFlow })
}
getLayerDependencies = (args: string[]) =>
diff --git a/src/UI/Popup/ImportButtons/ImportFlow.ts b/src/UI/Popup/ImportButtons/ImportFlow.ts
index 3deea70ed5..4ad16da1e2 100644
--- a/src/UI/Popup/ImportButtons/ImportFlow.ts
+++ b/src/UI/Popup/ImportButtons/ImportFlow.ts
@@ -66,13 +66,14 @@ ${Utils.special_visualizations_importRequirementDocs}
* Given the tagsstore of the point which represents the challenge, creates a new store with tags that should be applied onto the newly created point,
*/
public static getTagsToApply(
- originalFeatureTags: UIEventSource,
+ originalFeatureTags: Store,
args: { tags: string }
): Store {
if (originalFeatureTags === undefined) {
return undefined
}
let newTags: Store
+ // Listing of the keys that should be transferred
const tags = args.tags
if (
tags.indexOf(" ") < 0 &&
@@ -81,12 +82,6 @@ ${Utils.special_visualizations_importRequirementDocs}
) {
// This is a property to expand...
const items: string = originalFeatureTags.data[tags]
- console.debug(
- "The import button is using tags from properties[" +
- tags +
- "] of this object, namely ",
- items
- )
if (items.startsWith("{")) {
// This is probably a JSON
diff --git a/src/UI/Popup/ImportButtons/PointImportButtonViz.ts b/src/UI/Popup/ImportButtons/PointImportButtonViz.ts
index 9333102682..b36724eb89 100644
--- a/src/UI/Popup/ImportButtons/PointImportButtonViz.ts
+++ b/src/UI/Popup/ImportButtons/PointImportButtonViz.ts
@@ -1,7 +1,5 @@
import { Feature, Point } from "geojson"
-import { UIEventSource } from "../../../Logic/UIEventSource"
-import { SpecialVisualization, SpecialVisualizationState } from "../../SpecialVisualization"
-import BaseUIElement from "../../BaseUIElement"
+import { SpecialVisualisationParams, SpecialVisualizationSvelte } from "../../SpecialVisualization"
import SvelteUIElement from "../../Base/SvelteUIElement"
import PointImportFlow from "./PointImportFlow.svelte"
import { PointImportFlowArguments, PointImportFlowState } from "./PointImportFlowState"
@@ -9,12 +7,14 @@ import { Utils } from "../../../Utils"
import { ImportFlowUtils } from "./ImportFlow"
import Translations from "../../i18n/Translations"
import { GeoOperations } from "../../../Logic/GeoOperations"
+import Tr from "../../Base/Tr.svelte"
+import { UIEventSource } from "../../../Logic/UIEventSource"
import { OsmTags } from "../../../Models/OsmFeature"
/**
* The wrapper to make the special visualisation for the PointImportFlow
*/
-export class PointImportButtonViz extends SpecialVisualization {
+export class PointImportButtonViz extends SpecialVisualizationSvelte {
public readonly funcName = "import_button"
public readonly docs: string =
"This button will copy the point from an external dataset into OpenStreetMap" +
@@ -47,29 +47,24 @@ export class PointImportButtonViz extends SpecialVisualization {
public needsUrls = []
group = "data_import"
- constr(
- state: SpecialVisualizationState,
- tagSource: UIEventSource,
- argument: string[],
- feature: Feature
- ): BaseUIElement {
+ constr({ state, tags, args, feature }: SpecialVisualisationParams): SvelteUIElement {
const to_point_index = this.args.findIndex((arg) => arg.name === "to_point")
- const summarizePointArg = argument[to_point_index].toLowerCase()
+ const summarizePointArg = args[to_point_index].toLowerCase()
if (feature.geometry.type !== "Point") {
if (summarizePointArg !== "no" && summarizePointArg !== "false") {
feature = GeoOperations.centerpoint(feature)
} else {
- return Translations.t.general.add.import.wrongType.SetClass("alert")
+ return new SvelteUIElement(Tr, { t: Translations.t.general.add.import.wrongType.SetClass("alert") })
}
}
- const baseArgs: PointImportFlowArguments = Utils.ParseVisArgs(this.args, argument)
- const tagsToApply = ImportFlowUtils.getTagsToApply(tagSource, baseArgs)
+ const baseArgs: PointImportFlowArguments = Utils.ParseVisArgs(this.args, args)
+ const tagsToApply = ImportFlowUtils.getTagsToApply(>tags, baseArgs)
const importFlow = new PointImportFlowState(
state,
>feature,
baseArgs,
tagsToApply,
- tagSource
+ tags
)
return new SvelteUIElement(PointImportFlow, {
diff --git a/src/UI/Popup/ImportButtons/WayImportButtonViz.ts b/src/UI/Popup/ImportButtons/WayImportButtonViz.ts
index 61272532f8..91106af08f 100644
--- a/src/UI/Popup/ImportButtons/WayImportButtonViz.ts
+++ b/src/UI/Popup/ImportButtons/WayImportButtonViz.ts
@@ -1,10 +1,12 @@
-import { SpecialVisualization, SpecialVisualizationState } from "../../SpecialVisualization"
+import {
+ SpecialVisualisationParams,
+ SpecialVisualizationSvelte,
+ SpecialVisualizationUtils,
+} from "../../SpecialVisualization"
import { AutoAction } from "../AutoApplyButtonVis"
import { Feature, LineString, Polygon } from "geojson"
import { UIEventSource } from "../../../Logic/UIEventSource"
-import BaseUIElement from "../../BaseUIElement"
import { ImportFlowUtils } from "./ImportFlow"
-import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
import SvelteUIElement from "../../Base/SvelteUIElement"
import WayImportFlow from "./WayImportFlow.svelte"
import WayImportFlowState, { WayImportFlowArguments } from "./WayImportFlowState"
@@ -13,12 +15,11 @@ import ThemeConfig from "../../../Models/ThemeConfig/ThemeConfig"
import { Changes } from "../../../Logic/Osm/Changes"
import { IndexedFeatureSource } from "../../../Logic/FeatureSource/FeatureSource"
import FullNodeDatabaseSource from "../../../Logic/FeatureSource/TiledFeatureSource/FullNodeDatabaseSource"
-import { OsmTags } from "../../../Models/OsmFeature"
/**
* Wrapper around 'WayImportFlow' to make it a special visualisation
*/
-export default class WayImportButtonViz extends SpecialVisualization implements AutoAction {
+export default class WayImportButtonViz extends SpecialVisualizationSvelte implements AutoAction {
public readonly funcName: string = "import_way_button"
needsUrls = []
group = "data_import"
@@ -60,25 +61,20 @@ export default class WayImportButtonViz extends SpecialVisualization implements
public readonly supportsAutoAction = true
public readonly needsNodeDatabase = true
- constr(
- state: SpecialVisualizationState,
- tagSource: UIEventSource,
- argument: string[],
- feature: Feature,
- _: LayerConfig
- ): BaseUIElement {
+ constr({ state, tags, args, feature }: SpecialVisualisationParams): SvelteUIElement {
const geometry = feature.geometry
if (!(geometry.type == "LineString" || geometry.type === "Polygon")) {
- throw "Invalid type to import " + geometry.type
+ throw "Invalid type to import, expected linestring of polygon but got " + geometry.type
}
- const args: WayImportFlowArguments = Utils.ParseVisArgs(this.args, argument)
- const tagsToApply = ImportFlowUtils.getTagsToApply(tagSource, args)
+ const parsedArgs: WayImportFlowArguments = SpecialVisualizationUtils.parseArgs(this.args, args)
+ console.log("Parsed args are", parsedArgs)
+ const tagsToApply = ImportFlowUtils.getTagsToApply(tags, parsedArgs)
const importFlow = new WayImportFlowState(
state,
>feature,
- args,
+ parsedArgs,
tagsToApply,
- tagSource
+ tags,
)
return new SvelteUIElement(WayImportFlow, {
importFlow,
diff --git a/src/UI/Popup/LanguageElement/LanguageElement.ts b/src/UI/Popup/LanguageElement/LanguageElement.ts
index df0deecab5..4d95929e3c 100644
--- a/src/UI/Popup/LanguageElement/LanguageElement.ts
+++ b/src/UI/Popup/LanguageElement/LanguageElement.ts
@@ -1,46 +1,49 @@
-import { SpecialVisualization, SpecialVisualizationState } from "../../SpecialVisualization"
-import BaseUIElement from "../../BaseUIElement"
-import { UIEventSource } from "../../../Logic/UIEventSource"
+import { SpecialVisualisationParams, SpecialVisualizationSvelte } from "../../SpecialVisualization"
import SvelteUIElement from "../../Base/SvelteUIElement"
-import { Feature } from "geojson"
-import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
import { default as LanguageElementSvelte } from "./LanguageElement.svelte"
-export class LanguageElement extends SpecialVisualization {
+export class LanguageElement extends SpecialVisualizationSvelte {
funcName: string = "language_chooser"
needsUrls = []
- docs: string | BaseUIElement =
+ docs: string =
"The language element allows to show and pick all known (modern) languages. The key can be set"
- args: { name: string; defaultValue?: string; doc: string; required?: boolean }[] = [
+ args: { name: string; defaultValue?: string; doc: string; required?: boolean; type?: string }[] = [
{
name: "key",
required: true,
+ type:"key",
doc: "What key to use, e.g. `language`, `tactile_writing:braille:language`, ... If a language is supported, the language code will be appended to this key, resulting in `:nl=yes` if _nl_ is picked ",
},
{
name: "question",
required: true,
+ type: "translation",
doc: "What to ask if no questions are known",
},
{
name: "render_list_item",
+ type: "translation",
+
doc: "How a single language will be shown in the list of languages. Use `{language}` to indicate the language (which it must contain).",
defaultValue: "{language()}",
},
{
name: "render_single_language",
+ type: "translation",
doc: "What will be shown if the feature only supports a single language",
required: true,
},
{
+ type: "translation",
name: "render_all",
- doc: "The full rendering. Use `{list}` to show where the list of languages must come. Optional if mode=single",
+ doc: "The full rendering. U0se `{list}` to show where the list of languages must come. Optional if mode=single",
defaultValue: "{list()}",
},
{
name: "no_known_languages",
+ type: "translation",
doc: "The text that is shown if no languages are known for this key. If this text is omitted, the languages will be prompted instead",
},
]
@@ -59,14 +62,16 @@ export class LanguageElement extends SpecialVisualization {
`
constr(
- state: SpecialVisualizationState,
- tagSource: UIEventSource>,
- argument: string[],
- feature: Feature,
- layer: LayerConfig
- ): BaseUIElement {
+ {
+ state,
+ tags,
+ args,
+ feature,
+ layer,
+ }: SpecialVisualisationParams,
+ ): SvelteUIElement {
let [key, question, item_render, single_render, all_render, on_no_known_languages] =
- argument
+ args
if (item_render === undefined || item_render.trim() === "") {
item_render = "{language()}"
}
@@ -94,7 +99,7 @@ export class LanguageElement extends SpecialVisualization {
return new SvelteUIElement(LanguageElementSvelte, {
key,
- tags: tagSource,
+ tags,
state,
feature,
layer,
diff --git a/src/UI/Popup/MapillaryLinkVis.ts b/src/UI/Popup/MapillaryLinkVis.ts
index 048e99f94c..b3000a697c 100644
--- a/src/UI/Popup/MapillaryLinkVis.ts
+++ b/src/UI/Popup/MapillaryLinkVis.ts
@@ -1,7 +1,6 @@
import { GeoOperations } from "../../Logic/GeoOperations"
-import { ImmutableStore, UIEventSource } from "../../Logic/UIEventSource"
-import { SpecialVisualizationState, SpecialVisualizationSvelte } from "../SpecialVisualization"
-import { Feature } from "geojson"
+import { ImmutableStore } from "../../Logic/UIEventSource"
+import { SpecialVisualisationParams, SpecialVisualizationSvelte } from "../SpecialVisualization"
import SvelteUIElement from "../Base/SvelteUIElement"
import MapillaryLink from "../BigComponents/MapillaryLink.svelte"
@@ -20,12 +19,7 @@ export class MapillaryLinkVis extends SpecialVisualizationSvelte {
},
]
- public constr(
- state: SpecialVisualizationState,
- tagsSource: UIEventSource>,
- args: string[],
- feature: Feature
- ): SvelteUIElement {
+ public constr({ args, feature }: SpecialVisualisationParams): SvelteUIElement {
const [lon, lat] = GeoOperations.centerpointCoordinates(feature)
let zoom = Number(args[0])
if (isNaN(zoom)) {
diff --git a/src/UI/Popup/MinimapViz.svelte b/src/UI/Popup/MinimapViz.svelte
index e91ada4942..25b95242fb 100644
--- a/src/UI/Popup/MinimapViz.svelte
+++ b/src/UI/Popup/MinimapViz.svelte
@@ -1,6 +1,6 @@
diff --git a/src/UI/Popup/MultiApplyViz.ts b/src/UI/Popup/MultiApplyViz.ts
index 4a6254f58e..a44ef8c243 100644
--- a/src/UI/Popup/MultiApplyViz.ts
+++ b/src/UI/Popup/MultiApplyViz.ts
@@ -1,6 +1,6 @@
-import { Store, UIEventSource } from "../../Logic/UIEventSource"
+import { Store } from "../../Logic/UIEventSource"
import { MultiApplyParams } from "./MultiApply"
-import { SpecialVisualizationState, SpecialVisualizationSvelte } from "../SpecialVisualization"
+import { SpecialVisualisationParams, SpecialVisualizationSvelte } from "../SpecialVisualization"
import SvelteUIElement from "../Base/SvelteUIElement"
import MultiApplyButton from "./MultiApplyButton.svelte"
@@ -19,7 +19,9 @@ export class MultiApplyViz extends SpecialVisualizationSvelte {
doc: "One key (or multiple keys, seperated by ';') of the attribute that should be copied onto the other features.",
required: true,
},
- { name: "text", doc: "The text to show on the button" },
+ { name: "text",
+ type: "translation",
+ doc: "The text to show on the button" },
{
name: "autoapply",
doc: "A boolean indicating wether this tagging should be applied automatically if the relevant tags on this object are changed. A visual element indicating the multi_apply is still shown",
@@ -34,17 +36,13 @@ export class MultiApplyViz extends SpecialVisualizationSvelte {
example =
"{multi_apply(_features_with_the_same_name_within_100m, name:etymology:wikidata;name:etymology, Apply etymology information on all nearby objects with the same name)}"
- constr(
- state: SpecialVisualizationState,
- tagsSource: UIEventSource>,
- args: string[]
- ): SvelteUIElement {
+ constr({ state, tags, args }: SpecialVisualisationParams): SvelteUIElement {
const featureIdsKey = args[0]
const keysToApply = args[1].split(";")
const text = args[2]
const autoapply = args[3]?.toLowerCase() === "true"
const overwrite = args[4]?.toLowerCase() === "true"
- const featureIds: Store = tagsSource.map((tags) => {
+ const featureIds: Store = tags.map((tags) => {
const ids = tags[featureIdsKey]
try {
if (ids === undefined) {
@@ -69,7 +67,7 @@ export class MultiApplyViz extends SpecialVisualizationSvelte {
text,
autoapply,
overwrite,
- tagsSource,
+ tagsSource: tags,
state,
}
return new SvelteUIElement(MultiApplyButton, { params })
diff --git a/src/UI/Popup/PlantNetDetectionViz.ts b/src/UI/Popup/PlantNetDetectionViz.ts
index fdfe5dc55f..1b2f2f697d 100644
--- a/src/UI/Popup/PlantNetDetectionViz.ts
+++ b/src/UI/Popup/PlantNetDetectionViz.ts
@@ -1,11 +1,11 @@
-import { Store, UIEventSource } from "../../Logic/UIEventSource"
+import { Store } from "../../Logic/UIEventSource"
import { ProvidedImage } from "../../Logic/ImageProviders/ImageProvider"
import Wikidata from "../../Logic/Web/Wikidata"
import ChangeTagAction from "../../Logic/Osm/Actions/ChangeTagAction"
import { And } from "../../Logic/Tags/And"
import { Tag } from "../../Logic/Tags/Tag"
import AllImageProviders from "../../Logic/ImageProviders/AllImageProviders"
-import { SpecialVisualizationState, SpecialVisualizationSvelte } from "../SpecialVisualization"
+import { SpecialVisualisationParams, SpecialVisualizationSvelte } from "../SpecialVisualization"
import SvelteUIElement from "../Base/SvelteUIElement"
import PlantNet from "../PlantNet/PlantNet.svelte"
import { default as PlantNetCode } from "../../Logic/Web/PlantNet"
@@ -31,16 +31,13 @@ export class PlantNetDetectionViz extends SpecialVisualizationSvelte {
args = [
{
name: "image_key",
+ type:"key",
defaultValue: AllImageProviders.defaultKeys.join(","),
doc: "The keys given to the images, e.g. if image is given, the first picture URL will be added as image, the second as image:0, the third as image:1, etc... Multiple values are allowed if ';'-separated ",
},
]
- public constr(
- state: SpecialVisualizationState,
- tags: UIEventSource>,
- args: string[]
- ): SvelteUIElement {
+ public constr({ state, tags, args }: SpecialVisualisationParams): SvelteUIElement {
let imagePrefixes: string[] = undefined
if (args.length > 0) {
imagePrefixes = [].concat(...args.map((a) => a.split(",")))
diff --git a/src/UI/Popup/ShareLinkViz.ts b/src/UI/Popup/ShareLinkViz.ts
index cc0c86ccc3..15e602ec8e 100644
--- a/src/UI/Popup/ShareLinkViz.ts
+++ b/src/UI/Popup/ShareLinkViz.ts
@@ -1,6 +1,5 @@
-import { UIEventSource } from "../../Logic/UIEventSource"
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
-import { SpecialVisualizationState, SpecialVisualizationSvelte } from "../SpecialVisualization"
+import { SpecialVisualisationParams, SpecialVisualizationSvelte } from "../SpecialVisualization"
import SvelteUIElement from "../Base/SvelteUIElement"
import ShareButton from "../Base/ShareButton.svelte"
@@ -17,25 +16,25 @@ export class ShareLinkViz extends SpecialVisualizationSvelte {
},
{
name: "text",
+ type:"translation",
doc: "The text to show on the button. If none is given, will act as a titleIcon",
},
]
needsUrls = []
- public constr(
- state: SpecialVisualizationState,
- tagSource: UIEventSource>,
- args: string[]
+ public constr({
+ state,
+ tags,
+ args}:SpecialVisualisationParams
) {
const text = args[1]
const generateShareData = () => {
const title = state?.theme?.title?.txt ?? "MapComplete"
-
- const matchingLayer: LayerConfig = state?.theme?.getMatchingLayer(tagSource?.data)
+ const matchingLayer: LayerConfig = state?.theme?.getMatchingLayer(tags?.data)
let name =
- matchingLayer?.title?.GetRenderValue(tagSource.data)?.Subs(tagSource.data)?.txt ??
- tagSource.data?.name ??
+ matchingLayer?.title?.GetRenderValue(tags.data)?.Subs(tags.data)?.txt ??
+ tags.data?.name ??
"POI"
if (name) {
name = `${name} (${title})`
diff --git a/src/UI/Popup/TagRendering/SpecialTranslation.svelte b/src/UI/Popup/TagRendering/SpecialTranslation.svelte
index 7e65bf60f0..9686f3ff9f 100644
--- a/src/UI/Popup/TagRendering/SpecialTranslation.svelte
+++ b/src/UI/Popup/TagRendering/SpecialTranslation.svelte
@@ -38,7 +38,7 @@
let key = "cached_special_spec_" + $language
specs = t[key]
if (specs === undefined) {
- specs = SpecialVisualizations.constructSpecification(txt) ?? []
+ specs = SpecialVisualizations.constructSpecification(txt)
t[key] = specs
}
}
@@ -51,7 +51,7 @@
{
try {
return specpart.func
- .constr(state, tags, specpart.args, feature, layer)
+ .constr({state, tags, args : specpart.args, feature, layer})
?.SetClass(specpart.style)
} catch (e) {
console.error(
@@ -69,9 +69,8 @@
}
}
-{#if specs === undefined}
-
-{:else if lang === "*"}
+
+{#if lang === "*"}
{#each specs as specpart}
{#if typeof specpart === "string"}
diff --git a/src/UI/Popup/UploadToOsmViz.ts b/src/UI/Popup/UploadToOsmViz.ts
index ebabf95ff4..b4d9982ab6 100644
--- a/src/UI/Popup/UploadToOsmViz.ts
+++ b/src/UI/Popup/UploadToOsmViz.ts
@@ -1,4 +1,9 @@
-import { SpecialVisualization, SpecialVisualizationState } from "../SpecialVisualization"
+import {
+ SpecialVisualisationParams,
+ SpecialVisualization,
+ SpecialVisualizationState,
+ SpecialVisualizationSvelte,
+} from "../SpecialVisualization"
import { UIEventSource } from "../../Logic/UIEventSource"
import { GeoOperations } from "../../Logic/GeoOperations"
import Constants from "../../Models/Constants"
@@ -9,18 +14,14 @@ import { ServerSourceInfo } from "../../Models/SourceOverview"
/**
* Wrapper around 'UploadTraceToOsmUI'
*/
-export class UploadToOsmViz extends SpecialVisualization {
+export class UploadToOsmViz extends SpecialVisualizationSvelte {
funcName = "upload_to_osm"
docs =
"Uploads the GPS-history as GPX to OpenStreetMap.org; clears the history afterwards. The actual feature is ignored."
args = []
needsUrls: ServerSourceInfo[] = [Constants.osmAuthConfig]
- constr(
- state: SpecialVisualizationState,
- _: UIEventSource>,
- __: string[]
- ) {
+ constr({ state }: SpecialVisualisationParams): SvelteUIElement {
const locations = state.historicalUserLocations.features.data
return new SvelteUIElement(UploadTraceToOsmUI, {
state,
diff --git a/src/UI/SpecialVisualisations/DataImportSpecialVisualisations.ts b/src/UI/SpecialVisualisations/DataImportSpecialVisualisations.ts
index 13e7fbbddd..df7f1ac973 100644
--- a/src/UI/SpecialVisualisations/DataImportSpecialVisualisations.ts
+++ b/src/UI/SpecialVisualisations/DataImportSpecialVisualisations.ts
@@ -1,4 +1,5 @@
import {
+ SpecialVisualisationParams,
SpecialVisualization,
SpecialVisualizationState,
SpecialVisualizationSvelte,
@@ -47,6 +48,7 @@ class MaprouletteSetStatusVis extends SpecialVisualizationSvelte {
args = [
{
name: "message",
+ type: "translation",
doc: "A message to show to the user",
},
{
@@ -56,6 +58,7 @@ class MaprouletteSetStatusVis extends SpecialVisualizationSvelte {
},
{
name: "message_confirm",
+ type: "translation",
doc: "What to show when the task is closed, either by the user or was already closed.",
},
{
@@ -65,17 +68,19 @@ class MaprouletteSetStatusVis extends SpecialVisualizationSvelte {
},
{
name: "maproulette_id",
+ type:"key",
doc: "The property name containing the maproulette id",
defaultValue: "mr_taskId",
},
{
name: "ask_feedback",
+ type: "translation",
doc: "If not an empty string, this will be used as question to ask some additional feedback. A text field will be added",
defaultValue: "",
},
]
- constr(state, tagsSource, args) {
+ constr({ state, tags, args }: SpecialVisualisationParams): SvelteUIElement {
let [message, image, message_closed, statusToSet, maproulette_id_key, askFeedback] = args
if (image === "") {
image = "confirm"
@@ -86,7 +91,7 @@ class MaprouletteSetStatusVis extends SpecialVisualizationSvelte {
statusToSet = statusToSet ?? "1"
return new SvelteUIElement(MaprouletteSetStatus, {
state,
- tags: tagsSource,
+ tags,
message,
image,
message_closed,
@@ -106,6 +111,7 @@ class LinkedDataFromWebsite extends SpecialVisualization {
{
name: "key",
defaultValue: "website",
+ type:"key",
doc: "Attempt to load ld+json from the specified URL. This can be in an embedded