mapcomplete/UI/Popup/ImportButtons/PointImportFlowState.ts

101 lines
4 KiB
TypeScript

import ImportFlow, { ImportFlowArguments } from "./ImportFlow"
import { SpecialVisualizationState } from "../../SpecialVisualization"
import { Store, UIEventSource } from "../../../Logic/UIEventSource"
import { OsmObject, OsmWay } from "../../../Logic/Osm/OsmObject"
import CreateNewNodeAction from "../../../Logic/Osm/Actions/CreateNewNodeAction"
import { Feature, Point } from "geojson"
import Maproulette from "../../../Logic/Maproulette"
import { GeoOperations } from "../../../Logic/GeoOperations"
import { Tag } from "../../../Logic/Tags/Tag"
export interface PointImportFlowArguments extends ImportFlowArguments {
max_snap_distance?: string
snap_onto_layers?: string
icon?: string
targetLayer: string
note_id?: string
maproulette_id?: string
}
export class PointImportFlowState extends ImportFlow<PointImportFlowArguments> {
public readonly startCoordinate: [number, number]
private readonly _originalFeature: Feature<Point>
constructor(
state: SpecialVisualizationState,
originalFeature: Feature<Point>,
args: PointImportFlowArguments,
tagsToApply: Store<Tag[]>,
originalFeatureTags: UIEventSource<Record<string, string>>
) {
super(state, args, tagsToApply, originalFeatureTags)
this._originalFeature = originalFeature
this.startCoordinate = GeoOperations.centerpointCoordinates(originalFeature)
}
/**
* Creates a new point on OSM, closes (if applicable) the OSM-note or the MapRoulette-challenge
*
* Gives back the id of the newly created element
*/
async onConfirm(
location: { lat: number; lon: number },
snapOntoWayId: string
): Promise<string> {
const tags = this.tagsToApply.data
const originalFeatureTags = this._originalFeatureTags
originalFeatureTags.data["_imported"] = "yes"
originalFeatureTags.ping() // will set isImported as per its definition
let snapOnto: OsmObject | "deleted" = undefined
if (snapOntoWayId !== undefined) {
snapOnto = await this.state.osmObjectDownloader.DownloadObjectAsync(snapOntoWayId)
}
if (snapOnto === "deleted") {
snapOnto = undefined
}
let specialMotivation = undefined
let note_id = this.args.note_id
if (note_id !== undefined && isNaN(Number(note_id))) {
note_id = originalFeatureTags.data[this.args.note_id]
specialMotivation = "source: https://osm.org/note/" + note_id
}
const newElementAction = new CreateNewNodeAction(tags, location.lat, location.lon, {
theme: this.state.layout.id,
changeType: "import",
snapOnto: <OsmWay>snapOnto,
specialMotivation: specialMotivation,
})
await this.state.changes.applyAction(newElementAction)
this.state.selectedElement.setData(
this.state.indexedFeatures.featuresById.data.get(newElementAction.newElementId)
)
if (note_id !== undefined) {
await this.state.osmConnection.closeNote(note_id, "imported")
originalFeatureTags.data["closed_at"] = new Date().toISOString()
originalFeatureTags.ping()
}
let maproulette_id = originalFeatureTags.data[this.args.maproulette_id]
if (maproulette_id !== undefined) {
if (this.state.featureSwitchIsTesting.data) {
console.log(
"Not marking maproulette task " +
maproulette_id +
" as fixed, because we are in testing mode"
)
} else {
console.log("Marking maproulette task as fixed")
await Maproulette.singleton.closeTask(Number(maproulette_id))
originalFeatureTags.data["mr_taskStatus"] = "Fixed"
originalFeatureTags.ping()
}
}
this.state.mapProperties.location.setData(location)
return newElementAction.newElementId
}
}