diff --git a/src/UI/InputElement/InputHelper.svelte b/src/UI/InputElement/InputHelper.svelte
index 3239ac3627..89047aa813 100644
--- a/src/UI/InputElement/InputHelper.svelte
+++ b/src/UI/InputElement/InputHelper.svelte
@@ -5,7 +5,6 @@
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
@@ -14,11 +13,13 @@
export let args: (string | number | boolean)[] | any = undefined
export let state: SpecialVisualizationState = undefined
let validator = Validators.get(type)
- let validatorHelper: Validator = validator.inputHelper
+ let validatorHelper = 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 434e705fd7..4d80c6c926 100644
--- a/src/UI/Map/ShowDataLayer.ts
+++ b/src/UI/Map/ShowDataLayer.ts
@@ -459,6 +459,11 @@ 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 8257745e82..9bfa3c3659 100644
--- a/src/UI/Popup/AutoApplyButtonVis.ts
+++ b/src/UI/Popup/AutoApplyButtonVis.ts
@@ -2,9 +2,8 @@ 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"
@@ -32,7 +31,12 @@ export default class AutoApplyButtonVis extends SpecialVisualizationSvelte {
public readonly funcName: string = "auto_apply"
public readonly needsUrls = []
public readonly group = "data_import"
- public readonly args: SpecialVisualisationArg[] = [
+ public readonly args: {
+ name: string
+ defaultValue?: string
+ doc: string
+ required?: boolean
+ }[] = [
{
name: "target_layer",
doc: "The layer that the target features will reside in",
@@ -50,7 +54,6 @@ export default class AutoApplyButtonVis extends SpecialVisualizationSvelte {
},
{
name: "text",
- type:"translation",
doc: "The text to show on the button",
required: true,
},
@@ -83,11 +86,15 @@ export default class AutoApplyButtonVis extends SpecialVisualizationSvelte {
4. At last, add this component`
}
- constr({ state, tags, args }: SpecialVisualisationParams): SvelteUIElement {
- const target_layer_id = args[0]
- const targetTagRendering = args[2]
- const text = args[3]
- const icon = args[4]
+ 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]
const options = {
target_layer_id,
targetTagRendering,
@@ -98,7 +105,7 @@ export default class AutoApplyButtonVis extends SpecialVisualizationSvelte {
const to_parse: UIEventSource = new UIEventSource(undefined)
Stores.chronic(500, () => to_parse.data === undefined)
.map(() => {
- const applicable = tags.data[args[1]]
+ const applicable = tagSource.data[argument[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 dc82a9125e..81f5f3747f 100644
--- a/src/UI/Popup/DataExportVisualisations.ts
+++ b/src/UI/Popup/DataExportVisualisations.ts
@@ -1,5 +1,11 @@
-import { SpecialVisualisationParams, SpecialVisualization, SpecialVisualizationSvelte } from "../SpecialVisualization"
+import {
+ SpecialVisualization,
+ SpecialVisualizationState,
+ SpecialVisualizationSvelte,
+} from "../SpecialVisualization"
+import { UIEventSource } from "../../Logic/UIEventSource"
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"
@@ -11,7 +17,13 @@ class ExportAsGpxVis extends SpecialVisualizationSvelte {
args = []
needsUrls = []
- constr({ tags, feature, layer }: SpecialVisualisationParams) {
+ constr(
+ state: SpecialVisualizationState,
+ tags: UIEventSource>,
+ argument: string[],
+ feature: Feature,
+ layer: LayerConfig
+ ) {
if (feature.geometry.type !== "LineString") {
return undefined
}
@@ -36,7 +48,7 @@ class ExportAsGeojsonVis extends SpecialVisualizationSvelte {
docs = "Exports the selected feature as GeoJson-file"
args = []
- constr({ tags, feature, layer }: SpecialVisualisationParams) {
+ constr(state, tags, args, feature, layer) {
const t = Translations.t.general.download
return new SvelteUIElement(ExportFeatureButton, {
tags,
@@ -52,7 +64,7 @@ class ExportAsGeojsonVis extends SpecialVisualizationSvelte {
}
export class DataExportVisualisations {
- public static initList(): SpecialVisualizationSvelte[] {
+ public static initList(): SpecialVisualization[] {
return [new ExportAsGpxVis(), new ExportAsGeojsonVis()]
}
}
diff --git a/src/UI/Popup/DataVisualisations.ts b/src/UI/Popup/DataVisualisations.ts
index 97fd3c10d3..5a721e162f 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 } from "../../Logic/UIEventSource"
+import { Store, UIEventSource } from "../../Logic/UIEventSource"
+import { Feature } from "geojson"
import BaseUIElement from "../BaseUIElement"
import SvelteUIElement from "../Base/SvelteUIElement"
import DirectionIndicator from "../Base/DirectionIndicator.svelte"
@@ -20,18 +20,15 @@ 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 SpecialVisualizationSvelte {
+class DirectionIndicatorVis extends SpecialVisualization {
funcName = "direction_indicator"
args = []
@@ -39,8 +36,13 @@ class DirectionIndicatorVis extends SpecialVisualizationSvelte {
"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(params: SpecialVisualisationParams): SvelteUIElement {
- return new SvelteUIElement(DirectionIndicator, params)
+ constr(
+ state: SpecialVisualizationState,
+ tagSource: UIEventSource>,
+ argument: string[],
+ feature: Feature
+ ): BaseUIElement {
+ return new SvelteUIElement(DirectionIndicator, { state, feature })
}
}
@@ -63,15 +65,17 @@ class DirectionAbsolute extends SpecialVisualization {
]
group = "data"
- constr({
- tags,
- args,
- }: SpecialVisualisationParams): BaseUIElement {
+ constr(
+ state: SpecialVisualizationState,
+ tagSource: UIEventSource>,
+ args: string[]
+ ): BaseUIElement {
const key = args[0] === "" ? "_direction:centerpoint" : args[0]
const offset = args[1] === "" ? 0 : Number(args[1])
return new VariableUiElement(
- tags.map((tags) => {
+ tagSource
+ .map((tags) => {
console.log("Direction value", tags[key], key)
return tags[key]
})
@@ -113,12 +117,14 @@ 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({ tags, args }: SpecialVisualisationParams): SvelteUIElement {
+ constr(state, tagSource: UIEventSource, args) {
const [key, prefix, postfix] = args
const openingHoursStore: Store =
- OH.CreateOhObjectStore(tags, key, prefix, postfix)
+ OH.CreateOhObjectStore(tagSource, key, prefix, postfix)
return new SvelteUIElement(OpeningHoursWithError, {
- tags, key, opening_hours_obj: openingHoursStore,
+ tags: tagSource,
+ key,
+ opening_hours_obj: openingHoursStore,
})
}
}
@@ -146,7 +152,11 @@ class OpeningHoursState extends SpecialVisualizationSvelte {
},
]
- constr({ state, tags, args }: SpecialVisualisationParams): SvelteUIElement {
+ constr(
+ state: SpecialVisualizationState,
+ tags: UIEventSource>,
+ args: string[]
+ ): SvelteUIElement {
const keyToUse = args[0]
const prefix = args[1]
const postfix = args[2]
@@ -177,10 +187,10 @@ class Canonical extends SpecialVisualization {
},
]
- constr({ state, tags, args }: SpecialVisualisationParams) {
+ constr(state, tagSource, args) {
const key = args[0]
return new VariableUiElement(
- tags
+ tagSource
.map((tags) => tags[key])
.map((value) => {
if (value === undefined) {
@@ -193,7 +203,7 @@ class Canonical extends SpecialVisualization {
if (unit === undefined) {
return value
}
- const getCountry = () => tags.data._country
+ const getCountry = () => tagSource.data._country
return unit.asHumanLongValue(value, getCountry)
})
)
@@ -207,24 +217,26 @@ 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(params: SpecialVisualisationParams) {
- return new SvelteUIElement(AllFeaturesStatistics, params)
+ constr(state) {
+ return new SvelteUIElement(AllFeaturesStatistics, { state })
}
}
-class PresetDescription extends SpecialVisualizationSvelte {
+class PresetDescription extends SpecialVisualization {
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, tags }: SpecialVisualisationParams): SvelteUIElement {
- const translation = tags.map((tags) => {
+ constr(
+ state: SpecialVisualizationState,
+ tagSource: UIEventSource>
+ ): BaseUIElement {
+ const translation = tagSource.map((tags) => {
const layer = state.theme.getMatchingLayer(tags)
return layer?.getMostMatchingPreset(tags)?.description
})
- return new SvelteUIElement(Tr, { t: translation })
+ return new VariableUiElement(translation)
}
}
@@ -232,9 +244,14 @@ class PresetTypeSelect extends SpecialVisualizationSvelte {
funcName = "preset_type_select"
docs = "An editable tag rendering which allows to change the type"
args = []
- group = "ui"
- constr({ state, tags, feature, layer }: SpecialVisualisationParams,): SvelteUIElement {
+ constr(
+ state: SpecialVisualizationState,
+ tags: UIEventSource>,
+ argument: string[],
+ selectedElement: Feature,
+ layer: LayerConfig
+ ): SvelteUIElement {
const t = Translations.t.preset_type
if (layer._basedOn !== layer.id) {
console.warn("Trying to use the _original_ layer")
@@ -260,7 +277,7 @@ class PresetTypeSelect extends SpecialVisualizationSvelte {
return new SvelteUIElement(TagRenderingEditable, {
config,
tags,
- selectedElement: feature,
+ selectedElement,
state,
layer,
})
@@ -273,8 +290,8 @@ class AllTagsVis extends SpecialVisualizationSvelte {
args = []
group = "data"
- constr(params: SpecialVisualisationParams) {
- return new SvelteUIElement(AllTagsPanel, params)
+ constr(state, tags: UIEventSource>, _, __, layer: LayerConfig) {
+ return new SvelteUIElement(AllTagsPanel, { tags, layer })
}
}
@@ -285,18 +302,23 @@ 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({ tags, args }: SpecialVisualisationParams): BaseUIElement {
+ constr(
+ state: SpecialVisualizationState,
+ tagSource: UIEventSource>,
+ args: string[],
+ feature: Feature,
+ layer: LayerConfig
+ ): BaseUIElement {
const key = args[0]
- const points_in_time = tags.map((tags) => tags[key])
+ const points_in_time = tagSource.map((tags) => tags[key])
const times = points_in_time.map(
- (times) => OH.createOhObject(tags.data, times, tags.data["_country"], 1),
- [tags]
+ (times) => OH.createOhObject(tagSource.data, times, tagSource.data["_country"], 1),
+ [tagSource]
)
return new VariableUiElement(
times.map((times) => new SvelteUIElement(CollectionTimes, { times }))
@@ -304,60 +326,6 @@ 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 [
@@ -373,7 +341,6 @@ 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 7cfffd1f4b..679255d652 100644
--- a/src/UI/Popup/HistogramViz.ts
+++ b/src/UI/Popup/HistogramViz.ts
@@ -1,5 +1,5 @@
import { Store, UIEventSource } from "../../Logic/UIEventSource"
-import { SpecialVisualisationParams, SpecialVisualization, SpecialVisualizationState } from "../SpecialVisualization"
+import { SpecialVisualization, SpecialVisualizationState } from "../SpecialVisualization"
import { Feature } from "geojson"
import SvelteUIElement from "../Base/SvelteUIElement"
import Histogram from "../BigComponents/Histogram.svelte"
@@ -14,7 +14,6 @@ export class HistogramViz extends SpecialVisualization {
args = [
{
name: "key",
- type:"key",
doc: "The key to be read and to generate a histogram from",
required: true,
},
@@ -36,8 +35,12 @@ export class HistogramViz extends SpecialVisualization {
]
}
- constr( {tags, args}: SpecialVisualisationParams): SvelteUIElement {
- const values: Store = tags.map((tags) => {
+ constr(
+ state: SpecialVisualizationState,
+ tagSource: UIEventSource>,
+ args: string[]
+ ) {
+ const values: Store = tagSource.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 fce251a7dc..f72497649a 100644
--- a/src/UI/Popup/ImportButtons/ConflateImportButtonViz.ts
+++ b/src/UI/Popup/ImportButtons/ConflateImportButtonViz.ts
@@ -1,11 +1,7 @@
-import {
- SpecialVisualisationArg,
- SpecialVisualisationParams,
- SpecialVisualizationSvelte,
- SpecialVisualizationUtils,
-} from "../../SpecialVisualization"
+import { SpecialVisualization, SpecialVisualizationState } 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"
@@ -18,7 +14,6 @@ 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
@@ -27,17 +22,21 @@ export interface ConflateFlowArguments extends ImportFlowArguments {
snap_onto_layers?: string
}
-export default class ConflateImportButtonViz extends SpecialVisualizationSvelte implements AutoAction {
+export default class ConflateImportButtonViz extends SpecialVisualization implements AutoAction {
supportsAutoAction: boolean = true
needsUrls = []
group = "data_import"
public readonly funcName: string = "conflate_button"
- public readonly args: SpecialVisualisationArg[] = [
+ public readonly args: {
+ name: string
+ defaultValue?: string
+ doc: string
+ required?: boolean
+ }[] = [
...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",
},
]
@@ -85,25 +84,32 @@ export default class ConflateImportButtonViz extends SpecialVisualizationSvelte
await state.changes.applyAction(action)
}
- constr({ state, tags, args, feature }: SpecialVisualisationParams): SvelteUIElement {
+ constr(
+ state: SpecialVisualizationState,
+ tagSource: UIEventSource,
+ argument: string[],
+ feature: Feature
+ ): BaseUIElement {
const canBeImported =
feature.geometry.type === "LineString" ||
(feature.geometry.type === "Polygon" && feature.geometry.coordinates.length === 1)
if (!canBeImported) {
- return new SvelteUIElement(Tr, { t: Translations.t.general.add.import.wrongTypeToConflate, cls: "alert" })
+ return Translations.t.general.add.import.wrongTypeToConflate.SetClass("alert")
}
- const argsParsed: ConflateFlowArguments = SpecialVisualizationUtils.parseArgs(this.args, args)
- const tagsToApply = ImportFlowUtils.getTagsToApply(>tags, argsParsed)
- const idOfWayToReplaceGeometry = tags.data[argsParsed.way_to_conflate]
+ const args: ConflateFlowArguments = Utils.ParseVisArgs(this.args, argument)
+ const tagsToApply = ImportFlowUtils.getTagsToApply(tagSource, args)
+ const idOfWayToReplaceGeometry = tagSource.data[args.way_to_conflate]
const importFlow = new ConflateImportFlowState(
state,
>feature,
- argsParsed,
+ args,
tagsToApply,
- tags,
+ tagSource,
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 4ad16da1e2..3deea70ed5 100644
--- a/src/UI/Popup/ImportButtons/ImportFlow.ts
+++ b/src/UI/Popup/ImportButtons/ImportFlow.ts
@@ -66,14 +66,13 @@ ${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: Store,
+ originalFeatureTags: UIEventSource,
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 &&
@@ -82,6 +81,12 @@ ${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 b36724eb89..9333102682 100644
--- a/src/UI/Popup/ImportButtons/PointImportButtonViz.ts
+++ b/src/UI/Popup/ImportButtons/PointImportButtonViz.ts
@@ -1,5 +1,7 @@
import { Feature, Point } from "geojson"
-import { SpecialVisualisationParams, SpecialVisualizationSvelte } from "../../SpecialVisualization"
+import { UIEventSource } from "../../../Logic/UIEventSource"
+import { SpecialVisualization, SpecialVisualizationState } from "../../SpecialVisualization"
+import BaseUIElement from "../../BaseUIElement"
import SvelteUIElement from "../../Base/SvelteUIElement"
import PointImportFlow from "./PointImportFlow.svelte"
import { PointImportFlowArguments, PointImportFlowState } from "./PointImportFlowState"
@@ -7,14 +9,12 @@ 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 SpecialVisualizationSvelte {
+export class PointImportButtonViz extends SpecialVisualization {
public readonly funcName = "import_button"
public readonly docs: string =
"This button will copy the point from an external dataset into OpenStreetMap" +
@@ -47,24 +47,29 @@ export class PointImportButtonViz extends SpecialVisualizationSvelte {
public needsUrls = []
group = "data_import"
- constr({ state, tags, args, feature }: SpecialVisualisationParams): SvelteUIElement {
+ constr(
+ state: SpecialVisualizationState,
+ tagSource: UIEventSource,
+ argument: string[],
+ feature: Feature
+ ): BaseUIElement {
const to_point_index = this.args.findIndex((arg) => arg.name === "to_point")
- const summarizePointArg = args[to_point_index].toLowerCase()
+ const summarizePointArg = argument[to_point_index].toLowerCase()
if (feature.geometry.type !== "Point") {
if (summarizePointArg !== "no" && summarizePointArg !== "false") {
feature = GeoOperations.centerpoint(feature)
} else {
- return new SvelteUIElement(Tr, { t: Translations.t.general.add.import.wrongType.SetClass("alert") })
+ return Translations.t.general.add.import.wrongType.SetClass("alert")
}
}
- const baseArgs: PointImportFlowArguments = Utils.ParseVisArgs(this.args, args)
- const tagsToApply = ImportFlowUtils.getTagsToApply(>tags, baseArgs)
+ const baseArgs: PointImportFlowArguments = Utils.ParseVisArgs(this.args, argument)
+ const tagsToApply = ImportFlowUtils.getTagsToApply(tagSource, baseArgs)
const importFlow = new PointImportFlowState(
state,
>feature,
baseArgs,
tagsToApply,
- tags
+ tagSource
)
return new SvelteUIElement(PointImportFlow, {
diff --git a/src/UI/Popup/ImportButtons/WayImportButtonViz.ts b/src/UI/Popup/ImportButtons/WayImportButtonViz.ts
index 91106af08f..61272532f8 100644
--- a/src/UI/Popup/ImportButtons/WayImportButtonViz.ts
+++ b/src/UI/Popup/ImportButtons/WayImportButtonViz.ts
@@ -1,12 +1,10 @@
-import {
- SpecialVisualisationParams,
- SpecialVisualizationSvelte,
- SpecialVisualizationUtils,
-} from "../../SpecialVisualization"
+import { SpecialVisualization, SpecialVisualizationState } 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"
@@ -15,11 +13,12 @@ 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 SpecialVisualizationSvelte implements AutoAction {
+export default class WayImportButtonViz extends SpecialVisualization implements AutoAction {
public readonly funcName: string = "import_way_button"
needsUrls = []
group = "data_import"
@@ -61,20 +60,25 @@ export default class WayImportButtonViz extends SpecialVisualizationSvelte imple
public readonly supportsAutoAction = true
public readonly needsNodeDatabase = true
- constr({ state, tags, args, feature }: SpecialVisualisationParams): SvelteUIElement {
+ constr(
+ state: SpecialVisualizationState,
+ tagSource: UIEventSource,
+ argument: string[],
+ feature: Feature,
+ _: LayerConfig
+ ): BaseUIElement {
const geometry = feature.geometry
if (!(geometry.type == "LineString" || geometry.type === "Polygon")) {
- throw "Invalid type to import, expected linestring of polygon but got " + geometry.type
+ throw "Invalid type to import " + geometry.type
}
- const parsedArgs: WayImportFlowArguments = SpecialVisualizationUtils.parseArgs(this.args, args)
- console.log("Parsed args are", parsedArgs)
- const tagsToApply = ImportFlowUtils.getTagsToApply(tags, parsedArgs)
+ const args: WayImportFlowArguments = Utils.ParseVisArgs(this.args, argument)
+ const tagsToApply = ImportFlowUtils.getTagsToApply(tagSource, args)
const importFlow = new WayImportFlowState(
state,
>feature,
- parsedArgs,
+ args,
tagsToApply,
- tags,
+ tagSource
)
return new SvelteUIElement(WayImportFlow, {
importFlow,
diff --git a/src/UI/Popup/LanguageElement/LanguageElement.ts b/src/UI/Popup/LanguageElement/LanguageElement.ts
index 4d95929e3c..df0deecab5 100644
--- a/src/UI/Popup/LanguageElement/LanguageElement.ts
+++ b/src/UI/Popup/LanguageElement/LanguageElement.ts
@@ -1,49 +1,46 @@
-import { SpecialVisualisationParams, SpecialVisualizationSvelte } from "../../SpecialVisualization"
+import { SpecialVisualization, SpecialVisualizationState } from "../../SpecialVisualization"
+import BaseUIElement from "../../BaseUIElement"
+import { UIEventSource } from "../../../Logic/UIEventSource"
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 SpecialVisualizationSvelte {
+export class LanguageElement extends SpecialVisualization {
funcName: string = "language_chooser"
needsUrls = []
- docs: string =
+ docs: string | BaseUIElement =
"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; type?: string }[] = [
+ args: { name: string; defaultValue?: string; doc: string; required?: boolean }[] = [
{
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. U0se `{list}` to show where the list of languages must come. Optional if mode=single",
+ doc: "The full rendering. Use `{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",
},
]
@@ -62,16 +59,14 @@ export class LanguageElement extends SpecialVisualizationSvelte {
`
constr(
- {
- state,
- tags,
- args,
- feature,
- layer,
- }: SpecialVisualisationParams,
- ): SvelteUIElement {
+ state: SpecialVisualizationState,
+ tagSource: UIEventSource>,
+ argument: string[],
+ feature: Feature,
+ layer: LayerConfig
+ ): BaseUIElement {
let [key, question, item_render, single_render, all_render, on_no_known_languages] =
- args
+ argument
if (item_render === undefined || item_render.trim() === "") {
item_render = "{language()}"
}
@@ -99,7 +94,7 @@ export class LanguageElement extends SpecialVisualizationSvelte {
return new SvelteUIElement(LanguageElementSvelte, {
key,
- tags,
+ tags: tagSource,
state,
feature,
layer,
diff --git a/src/UI/Popup/MapillaryLinkVis.ts b/src/UI/Popup/MapillaryLinkVis.ts
index b3000a697c..048e99f94c 100644
--- a/src/UI/Popup/MapillaryLinkVis.ts
+++ b/src/UI/Popup/MapillaryLinkVis.ts
@@ -1,6 +1,7 @@
import { GeoOperations } from "../../Logic/GeoOperations"
-import { ImmutableStore } from "../../Logic/UIEventSource"
-import { SpecialVisualisationParams, SpecialVisualizationSvelte } from "../SpecialVisualization"
+import { ImmutableStore, UIEventSource } from "../../Logic/UIEventSource"
+import { SpecialVisualizationState, SpecialVisualizationSvelte } from "../SpecialVisualization"
+import { Feature } from "geojson"
import SvelteUIElement from "../Base/SvelteUIElement"
import MapillaryLink from "../BigComponents/MapillaryLink.svelte"
@@ -19,7 +20,12 @@ export class MapillaryLinkVis extends SpecialVisualizationSvelte {
},
]
- public constr({ args, feature }: SpecialVisualisationParams): SvelteUIElement {
+ public constr(
+ state: SpecialVisualizationState,
+ tagsSource: UIEventSource>,
+ args: string[],
+ feature: Feature
+ ): 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 25b95242fb..e91ada4942 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 a44ef8c243..4a6254f58e 100644
--- a/src/UI/Popup/MultiApplyViz.ts
+++ b/src/UI/Popup/MultiApplyViz.ts
@@ -1,6 +1,6 @@
-import { Store } from "../../Logic/UIEventSource"
+import { Store, UIEventSource } from "../../Logic/UIEventSource"
import { MultiApplyParams } from "./MultiApply"
-import { SpecialVisualisationParams, SpecialVisualizationSvelte } from "../SpecialVisualization"
+import { SpecialVisualizationState, SpecialVisualizationSvelte } from "../SpecialVisualization"
import SvelteUIElement from "../Base/SvelteUIElement"
import MultiApplyButton from "./MultiApplyButton.svelte"
@@ -19,9 +19,7 @@ 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",
- type: "translation",
- doc: "The text to show on the button" },
+ { name: "text", 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",
@@ -36,13 +34,17 @@ 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, tags, args }: SpecialVisualisationParams): SvelteUIElement {
+ constr(
+ state: SpecialVisualizationState,
+ tagsSource: UIEventSource>,
+ args: string[]
+ ): 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 = tags.map((tags) => {
+ const featureIds: Store = tagsSource.map((tags) => {
const ids = tags[featureIdsKey]
try {
if (ids === undefined) {
@@ -67,7 +69,7 @@ export class MultiApplyViz extends SpecialVisualizationSvelte {
text,
autoapply,
overwrite,
- tagsSource: tags,
+ tagsSource,
state,
}
return new SvelteUIElement(MultiApplyButton, { params })
diff --git a/src/UI/Popup/PlantNetDetectionViz.ts b/src/UI/Popup/PlantNetDetectionViz.ts
index 1b2f2f697d..fdfe5dc55f 100644
--- a/src/UI/Popup/PlantNetDetectionViz.ts
+++ b/src/UI/Popup/PlantNetDetectionViz.ts
@@ -1,11 +1,11 @@
-import { Store } from "../../Logic/UIEventSource"
+import { Store, UIEventSource } 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 { SpecialVisualisationParams, SpecialVisualizationSvelte } from "../SpecialVisualization"
+import { SpecialVisualizationState, SpecialVisualizationSvelte } from "../SpecialVisualization"
import SvelteUIElement from "../Base/SvelteUIElement"
import PlantNet from "../PlantNet/PlantNet.svelte"
import { default as PlantNetCode } from "../../Logic/Web/PlantNet"
@@ -31,13 +31,16 @@ 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, tags, args }: SpecialVisualisationParams): SvelteUIElement {
+ public constr(
+ state: SpecialVisualizationState,
+ tags: UIEventSource>,
+ args: string[]
+ ): 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 15e602ec8e..cc0c86ccc3 100644
--- a/src/UI/Popup/ShareLinkViz.ts
+++ b/src/UI/Popup/ShareLinkViz.ts
@@ -1,5 +1,6 @@
+import { UIEventSource } from "../../Logic/UIEventSource"
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
-import { SpecialVisualisationParams, SpecialVisualizationSvelte } from "../SpecialVisualization"
+import { SpecialVisualizationState, SpecialVisualizationSvelte } from "../SpecialVisualization"
import SvelteUIElement from "../Base/SvelteUIElement"
import ShareButton from "../Base/ShareButton.svelte"
@@ -16,25 +17,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,
- tags,
- args}:SpecialVisualisationParams
+ public constr(
+ state: SpecialVisualizationState,
+ tagSource: UIEventSource>,
+ args: string[]
) {
const text = args[1]
const generateShareData = () => {
const title = state?.theme?.title?.txt ?? "MapComplete"
- const matchingLayer: LayerConfig = state?.theme?.getMatchingLayer(tags?.data)
+
+ const matchingLayer: LayerConfig = state?.theme?.getMatchingLayer(tagSource?.data)
let name =
- matchingLayer?.title?.GetRenderValue(tags.data)?.Subs(tags.data)?.txt ??
- tags.data?.name ??
+ matchingLayer?.title?.GetRenderValue(tagSource.data)?.Subs(tagSource.data)?.txt ??
+ tagSource.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 9686f3ff9f..7e65bf60f0 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, args : specpart.args, feature, layer})
+ .constr(state, tags, specpart.args, feature, layer)
?.SetClass(specpart.style)
} catch (e) {
console.error(
@@ -69,8 +69,9 @@
}
}
-
-{#if lang === "*"}
+{#if specs === undefined}
+
+{:else 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 b4d9982ab6..ebabf95ff4 100644
--- a/src/UI/Popup/UploadToOsmViz.ts
+++ b/src/UI/Popup/UploadToOsmViz.ts
@@ -1,9 +1,4 @@
-import {
- SpecialVisualisationParams,
- SpecialVisualization,
- SpecialVisualizationState,
- SpecialVisualizationSvelte,
-} from "../SpecialVisualization"
+import { SpecialVisualization, SpecialVisualizationState } from "../SpecialVisualization"
import { UIEventSource } from "../../Logic/UIEventSource"
import { GeoOperations } from "../../Logic/GeoOperations"
import Constants from "../../Models/Constants"
@@ -14,14 +9,18 @@ import { ServerSourceInfo } from "../../Models/SourceOverview"
/**
* Wrapper around 'UploadTraceToOsmUI'
*/
-export class UploadToOsmViz extends SpecialVisualizationSvelte {
+export class UploadToOsmViz extends SpecialVisualization {
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 }: SpecialVisualisationParams): SvelteUIElement {
+ constr(
+ state: SpecialVisualizationState,
+ _: UIEventSource>,
+ __: string[]
+ ) {
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 df7f1ac973..13e7fbbddd 100644
--- a/src/UI/SpecialVisualisations/DataImportSpecialVisualisations.ts
+++ b/src/UI/SpecialVisualisations/DataImportSpecialVisualisations.ts
@@ -1,5 +1,4 @@
import {
- SpecialVisualisationParams,
SpecialVisualization,
SpecialVisualizationState,
SpecialVisualizationSvelte,
@@ -48,7 +47,6 @@ class MaprouletteSetStatusVis extends SpecialVisualizationSvelte {
args = [
{
name: "message",
- type: "translation",
doc: "A message to show to the user",
},
{
@@ -58,7 +56,6 @@ 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.",
},
{
@@ -68,19 +65,17 @@ 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, tags, args }: SpecialVisualisationParams): SvelteUIElement {
+ constr(state, tagsSource, args) {
let [message, image, message_closed, statusToSet, maproulette_id_key, askFeedback] = args
if (image === "") {
image = "confirm"
@@ -91,7 +86,7 @@ class MaprouletteSetStatusVis extends SpecialVisualizationSvelte {
statusToSet = statusToSet ?? "1"
return new SvelteUIElement(MaprouletteSetStatus, {
state,
- tags,
+ tags: tagsSource,
message,
image,
message_closed,
@@ -111,7 +106,6 @@ 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