forked from MapComplete/MapComplete
Further development of split-road feature; refactoring of change-handling
This commit is contained in:
parent
dc4cdda3b5
commit
96ecded0b9
37 changed files with 967 additions and 568 deletions
|
@ -3,7 +3,7 @@ import State from "../../State";
|
|||
import Toggle from "../Input/Toggle";
|
||||
import Translations from "../i18n/Translations";
|
||||
import Svg from "../../Svg";
|
||||
import DeleteAction from "../../Logic/Osm/DeleteAction";
|
||||
import DeleteAction from "../../Logic/Osm/Actions/DeleteAction";
|
||||
import {Tag} from "../../Logic/Tags/Tag";
|
||||
import {UIEventSource} from "../../Logic/UIEventSource";
|
||||
import {TagsFilter} from "../../Logic/Tags/TagsFilter";
|
||||
|
@ -19,6 +19,7 @@ import {Changes} from "../../Logic/Osm/Changes";
|
|||
import {And} from "../../Logic/Tags/And";
|
||||
import Constants from "../../Models/Constants";
|
||||
import DeleteConfig from "../../Customizations/JSON/DeleteConfig";
|
||||
import ChangeTagAction from "../../Logic/Osm/Actions/ChangeTagAction";
|
||||
|
||||
export default class DeleteWizard extends Toggle {
|
||||
/**
|
||||
|
@ -58,7 +59,9 @@ export default class DeleteWizard extends Toggle {
|
|||
})
|
||||
}
|
||||
(State.state?.changes ?? new Changes())
|
||||
.addTag(id, new And(tagsToApply.map(kv => new Tag(kv.k, kv.v))), tagsSource);
|
||||
.applyAction(new ChangeTagAction(
|
||||
id, new And(tagsToApply.map(kv => new Tag(kv.k, kv.v))), tagsSource.data
|
||||
))
|
||||
}
|
||||
|
||||
function doDelete(selected: TagsFilter) {
|
||||
|
|
|
@ -13,6 +13,7 @@ import SharedTagRenderings from "../../Customizations/SharedTagRenderings";
|
|||
import BaseUIElement from "../BaseUIElement";
|
||||
import {VariableUiElement} from "../Base/VariableUIElement";
|
||||
import DeleteWizard from "./DeleteWizard";
|
||||
import SplitRoadWizard from "./SplitRoadWizard";
|
||||
|
||||
export default class FeatureInfoBox extends ScrollableFullScreen {
|
||||
|
||||
|
@ -66,10 +67,6 @@ export default class FeatureInfoBox extends ScrollableFullScreen {
|
|||
renderings.push(questionBox);
|
||||
}
|
||||
|
||||
const hasMinimap = layerConfig.tagRenderings.some(tr => tr.hasMinimap())
|
||||
if (!hasMinimap) {
|
||||
renderings.push(new TagRenderingAnswer(tags, SharedTagRenderings.SharedTagRendering.get("minimap")))
|
||||
}
|
||||
|
||||
if (layerConfig.deletion) {
|
||||
renderings.push(
|
||||
|
@ -81,6 +78,19 @@ export default class FeatureInfoBox extends ScrollableFullScreen {
|
|||
))
|
||||
}
|
||||
|
||||
if (layerConfig.allowSplit) {
|
||||
renderings.push(
|
||||
new VariableUiElement(tags.map(tags => tags.id).map(id =>
|
||||
new SplitRoadWizard(id))
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
const hasMinimap = layerConfig.tagRenderings.some(tr => tr.hasMinimap())
|
||||
if (!hasMinimap) {
|
||||
renderings.push(new TagRenderingAnswer(tags, SharedTagRenderings.SharedTagRendering.get("minimap")))
|
||||
}
|
||||
|
||||
renderings.push(
|
||||
new VariableUiElement(
|
||||
State.state.osmConnection.userDetails
|
||||
|
|
|
@ -11,7 +11,9 @@ import Combine from "../Base/Combine";
|
|||
import {Button} from "../Base/Button";
|
||||
import Translations from "../i18n/Translations";
|
||||
import LayoutConfig from "../../Customizations/JSON/LayoutConfig";
|
||||
import SplitAction from "../../Logic/Osm/SplitAction";
|
||||
import SplitAction from "../../Logic/Osm/Actions/SplitAction";
|
||||
import {OsmObject, OsmWay} from "../../Logic/Osm/OsmObject";
|
||||
import Title from "../Base/Title";
|
||||
|
||||
export default class SplitRoadWizard extends Toggle {
|
||||
private static splitLayout = new UIEventSource(SplitRoadWizard.GetSplitLayout())
|
||||
|
@ -26,24 +28,25 @@ export default class SplitRoadWizard extends Toggle {
|
|||
const t = Translations.t.split;
|
||||
|
||||
// Contains the points on the road that are selected to split on - contains geojson points with extra properties such as 'location' with the distance along the linestring
|
||||
const splitPoints = new UIEventSource<{feature: any, freshness: Date}[]>([]);
|
||||
const splitPoints = new UIEventSource<{ feature: any, freshness: Date }[]>([]);
|
||||
|
||||
const hasBeenSplit = new UIEventSource(false)
|
||||
|
||||
// Toggle variable between show split button and map
|
||||
const splitClicked = new UIEventSource<boolean>(false);
|
||||
|
||||
// Minimap on which you can select the points to be splitted
|
||||
const miniMap = new Minimap({background: State.state.backgroundLayer});
|
||||
miniMap.SetStyle("width: 100%; height: 50rem;");
|
||||
const miniMap = new Minimap({background: State.state.backgroundLayer, allowMoving: false});
|
||||
miniMap.SetStyle("width: 100%; height: 24rem;");
|
||||
|
||||
// Define how a cut is displayed on the map
|
||||
|
||||
// Load the road with given id on the minimap
|
||||
const roadElement = State.state.allElements.ContainingFeatures.get(id)
|
||||
const splitAction = new SplitAction(roadElement)
|
||||
const roadEventSource = new UIEventSource([{feature: roadElement, freshness: new Date()}]);
|
||||
// Datalayer displaying the road and the cut points (if any)
|
||||
new ShowDataLayer(roadEventSource, miniMap.leafletMap, State.state.layoutToUse, false, true);
|
||||
new ShowDataLayer(splitPoints, miniMap.leafletMap, SplitRoadWizard.splitLayout, false, false)
|
||||
new ShowDataLayer(roadEventSource, miniMap.leafletMap, State.state.layoutToUse, false, true, "splitRoadWay");
|
||||
new ShowDataLayer(splitPoints, miniMap.leafletMap, SplitRoadWizard.splitLayout, false, false, "splitRoad: splitpoints")
|
||||
|
||||
/**
|
||||
* Handles a click on the overleaf map.
|
||||
|
@ -60,7 +63,7 @@ export default class SplitRoadWizard extends Toggle {
|
|||
|
||||
// let the state remember the point, to be able to retrieve it later by id
|
||||
State.state.allElements.addOrGetElement(pointOnRoad);
|
||||
|
||||
|
||||
// Add it to the list of all points and notify observers
|
||||
splitPoints.data.push({feature: pointOnRoad, freshness: new Date()}); // show the point on the data layer
|
||||
splitPoints.ping(); // not updated using .setData, so manually ping observers
|
||||
|
@ -73,7 +76,7 @@ export default class SplitRoadWizard extends Toggle {
|
|||
}))
|
||||
|
||||
// Toggle between splitmap
|
||||
const splitButton = new SubtleButton(Svg.scissors_ui(), "Split road");
|
||||
const splitButton = new SubtleButton(Svg.scissors_ui(), t.inviteToSplit.Clone());
|
||||
splitButton.onClick(
|
||||
() => {
|
||||
splitClicked.setData(true)
|
||||
|
@ -83,45 +86,63 @@ export default class SplitRoadWizard extends Toggle {
|
|||
// Only show the splitButton if logged in, else show login prompt
|
||||
const splitToggle = new Toggle(
|
||||
splitButton,
|
||||
t.loginToSplit.Clone().onClick(State.state.osmConnection.AttemptLogin),
|
||||
t.loginToSplit.Clone().onClick(() => State.state.osmConnection.AttemptLogin()),
|
||||
State.state.osmConnection.isLoggedIn)
|
||||
|
||||
// Save button
|
||||
const saveButton = new Button("Split here", () => splitAction.DoSplit(splitPoints.data));
|
||||
const saveButton = new Button(t.split.Clone(), () => {
|
||||
hasBeenSplit.setData(true)
|
||||
OsmObject.DownloadObject(id).addCallbackAndRunD(way => {
|
||||
OsmObject.DownloadReferencingRelations(id).addCallbackAndRunD(
|
||||
partOf => {
|
||||
const splitAction = new SplitAction(
|
||||
<OsmWay>way, way.asGeoJson(), partOf, splitPoints.data.map(ff => ff.feature)
|
||||
)
|
||||
State.state.changes.applyAction(splitAction)
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
});
|
||||
saveButton.SetClass("block btn btn-primary");
|
||||
const disabledSaveButton = new Button("Split here", undefined);
|
||||
disabledSaveButton.SetClass("block btn btn-disabled");
|
||||
// Only show the save button if there are split points defined
|
||||
const saveToggle = new Toggle(disabledSaveButton, saveButton, splitPoints.map((data) => data.length === 0))
|
||||
|
||||
const cancelButton = new Button("Cancel", () => {
|
||||
const cancelButton = new Button(Translations.t.general.cancel.Clone(), () => {
|
||||
splitClicked.setData(false);
|
||||
splitPoints.setData([]);
|
||||
splitClicked.setData(false)
|
||||
});
|
||||
|
||||
cancelButton.SetClass("block btn btn-secondary");
|
||||
|
||||
const splitTitle = t.splitTitle;
|
||||
|
||||
const mapView = new Combine([splitTitle, miniMap, cancelButton, saveToggle]);
|
||||
super(mapView, splitToggle, splitClicked);
|
||||
const splitTitle = new Title(t.splitTitle);
|
||||
|
||||
const mapView = new Combine([splitTitle, miniMap, new Combine([cancelButton, saveToggle])]);
|
||||
mapView.SetClass("question")
|
||||
const confirm = new Toggle(mapView, splitToggle, splitClicked);
|
||||
super(t.hasBeenSplit.Clone(), confirm, hasBeenSplit)
|
||||
}
|
||||
|
||||
private static GetSplitLayout(): LayoutConfig {
|
||||
return new LayoutConfig({
|
||||
maintainer: "mapcomplete",
|
||||
language: [],
|
||||
language: ["en"],
|
||||
startLon: 0,
|
||||
startLat: 0,
|
||||
description: undefined,
|
||||
description: "Split points visualisations - built in at SplitRoadWizard.ts",
|
||||
icon: "", startZoom: 0,
|
||||
title: "Split locations",
|
||||
version: "",
|
||||
|
||||
id: "splitpositions",
|
||||
layers: [{id: "splitpositions", source: {osmTags: "_cutposition=yes"}, icon: "./assets/svg/plus.svg"}]
|
||||
}, true, "split road wizard layout")
|
||||
}, true, "(BUILTIN) SplitRoadWizard.ts")
|
||||
|
||||
}
|
||||
}
|
|
@ -25,6 +25,7 @@ import BaseUIElement from "../BaseUIElement";
|
|||
import {DropDown} from "../Input/DropDown";
|
||||
import {Unit} from "../../Customizations/JSON/Denomination";
|
||||
import InputElementWrapper from "../Input/InputElementWrapper";
|
||||
import ChangeTagAction from "../../Logic/Osm/Actions/ChangeTagAction";
|
||||
|
||||
/**
|
||||
* Shows the question element.
|
||||
|
@ -56,7 +57,9 @@ export default class TagRenderingQuestion extends Combine {
|
|||
const selection = inputElement.GetValue().data;
|
||||
if (selection) {
|
||||
(State.state?.changes ?? new Changes())
|
||||
.addTag(tags.data.id, selection, tags);
|
||||
.applyAction(new ChangeTagAction(
|
||||
tags.data.id, selection, tags.data
|
||||
))
|
||||
}
|
||||
|
||||
if (options.afterSave) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue