mapcomplete/UI/Popup/ImportButton.ts

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

163 lines
6 KiB
TypeScript
Raw Normal View History

import BaseUIElement from "../BaseUIElement"
2023-05-30 02:52:22 +02:00
import {Store, UIEventSource} from "../../Logic/UIEventSource"
import Translations from "../i18n/Translations"
2023-05-30 02:52:22 +02:00
import {FixedUiElement} from "../Base/FixedUiElement"
import OsmChangeAction from "../../Logic/Osm/Actions/OsmChangeAction"
import {And} from "../../Logic/Tags/And"
import {Tag} from "../../Logic/Tags/Tag"
import {SpecialVisualization, SpecialVisualizationState} from "../SpecialVisualization"
import {Feature} from "geojson"
import {ImportFlowArguments, ImportFlowUtils} from "./ImportButtons/ImportFlow";
import {MergePointConfig} from "../../Logic/Osm/Actions/CreateWayWithPointReuseAction";
import {GeoOperations} from "../../Logic/GeoOperations";
import ReplaceGeometryAction from "../../Logic/Osm/Actions/ReplaceGeometryAction";
import {TagUtils} from "../../Logic/Tags/TagUtils";
/**
2023-05-30 02:52:22 +02:00
* @deprecated
* A helper class for the various import-flows.
2022-01-25 21:55:51 +01:00
* An import-flow always starts with a 'Import this'-button. Upon click, a custom confirmation panel is provided
*/
2023-05-30 02:52:22 +02:00
export abstract class AbstractImportButton implements SpecialVisualization {
2021-12-09 13:16:40 +01:00
public readonly funcName: string
public readonly docs: string
public readonly args: { name: string; defaultValue?: string; doc: string }[]
private readonly showRemovedTags: boolean
2022-06-08 12:53:04 +02:00
private readonly cannotBeImportedMessage: BaseUIElement | undefined
2022-09-08 21:40:48 +02:00
2022-06-08 12:53:04 +02:00
constructor(
funcName: string,
docsIntro: string,
extraArgs: { name: string; doc: string; defaultValue?: string; required?: boolean }[],
options?: { showRemovedTags?: true | boolean; cannotBeImportedMessage?: BaseUIElement }
) {
2021-12-09 13:16:40 +01:00
this.funcName = funcName
2022-06-08 12:53:04 +02:00
this.showRemovedTags = options?.showRemovedTags ?? true
this.cannotBeImportedMessage = options?.cannotBeImportedMessage
2023-05-30 02:52:22 +02:00
this.docs = `${docsIntro}${ImportFlowUtils.documentationGeneral}`
2021-12-09 13:16:40 +01:00
this.args = [
{
name: "targetLayer",
doc: "The id of the layer where this point should end up. This is not very strict, it will simply result in checking that this layer is shown preventing possible duplicate elements",
required: true,
2021-12-09 13:16:40 +01:00
},
{
name: "tags",
doc: "The tags to add onto the new object - see specification above. If this is a key (a single word occuring in the properties of the object), the corresponding value is taken and expanded instead",
required: true,
2021-12-09 13:16:40 +01:00
},
{
name: "text",
doc: "The text to show on the button",
defaultValue: "Import this data into OpenStreetMap",
},
{
name: "icon",
doc: "A nice icon to show in the button",
defaultValue: "./assets/svg/addSmall.svg",
},
...extraArgs,
]
}
abstract constructElement(
2023-03-28 05:13:48 +02:00
state: SpecialVisualizationState,
2023-05-30 02:52:22 +02:00
args: ImportFlowArguments,
newTags: Store<Tag[]>,
2023-03-28 05:13:48 +02:00
tagSource: UIEventSource<Record<string, string>>,
feature: Feature,
onCancelClicked: () => void
): BaseUIElement
2023-03-28 05:13:48 +02:00
constr(
state: SpecialVisualizationState,
tagSource: UIEventSource<Record<string, string>>,
argsRaw: string[]
) {
2023-05-30 02:52:22 +02:00
return new FixedUiElement("Deprecated")
2021-12-09 13:16:40 +01:00
}
}
export class ConflateButton extends AbstractImportButton {
needsNodeDatabase = true
2023-05-30 02:52:22 +02:00
constructor() {
super(
"conflate_button",
"This button will modify the geometry of an existing OSM way to match the specified geometry. This can conflate OSM-ways with LineStrings and Polygons (only simple polygons with one single ring). An attempt is made to move points with special values to a decent new location (e.g. entrances)",
[
{
name: "way_to_conflate",
doc: "The key, of which the corresponding value is the id of the OSM-way that must be conflated; typically a calculatedTag",
2022-06-08 12:53:04 +02:00
},
],
{
cannotBeImportedMessage: Translations.t.general.add.import.wrongTypeToConflate,
}
)
}
constructElement(
2023-03-28 05:13:48 +02:00
state: SpecialVisualizationState,
args: {
max_snap_distance: string
snap_onto_layers: string
icon: string
text: string
tags: string
newTags: UIEventSource<Tag[]>
targetLayer: string
},
tagSource: UIEventSource<any>,
2023-03-28 05:13:48 +02:00
feature: Feature,
onCancelClicked: () => void
): BaseUIElement {
const nodesMustMatch = args.snap_onto_layers
?.split(";")
?.map((tag, i) => TagUtils.Tag(tag, "TagsSpec for import button " + i))
const mergeConfigs = []
if (nodesMustMatch !== undefined && nodesMustMatch.length > 0) {
const mergeConfig: MergePointConfig = {
mode: args["point_move_mode"] == "move_osm" ? "move_osm_point" : "reuse_osm_point",
ifMatches: new And(nodesMustMatch),
withinRangeOfM: Number(args.max_snap_distance),
}
mergeConfigs.push(mergeConfig)
}
const key = args["way_to_conflate"]
const wayToConflate = tagSource.data[key]
feature = GeoOperations.removeOvernoding(feature)
2023-03-28 05:13:48 +02:00
const action: OsmChangeAction & { getPreview(): Promise<any> } = new ReplaceGeometryAction(
state,
feature,
wayToConflate,
{
theme: state.layout.id,
newTags: args.newTags.data,
}
)
return this.createConfirmPanelForWay(
state,
args,
feature,
tagSource,
action,
onCancelClicked
)
}
2023-05-30 02:52:22 +02:00
protected canBeImported(feature: Feature) {
2022-01-25 21:55:51 +01:00
return (
feature.geometry.type === "LineString" ||
(feature.geometry.type === "Polygon" && feature.geometry.coordinates.length === 1)
2022-09-08 21:40:48 +02:00
)
2022-01-25 21:55:51 +01:00
}
}