forked from MapComplete/MapComplete
		
	Further work on the move flow
This commit is contained in:
		
							parent
							
								
									11d5ccf93f
								
							
						
					
					
						commit
						95867635e0
					
				
					 10 changed files with 763 additions and 63 deletions
				
			
		
							
								
								
									
										17
									
								
								Logic/Osm/Actions/ChangeLocationAction.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								Logic/Osm/Actions/ChangeLocationAction.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | |||
| import {ChangeDescription} from "./ChangeDescription"; | ||||
| import OsmChangeAction from "./OsmChangeAction"; | ||||
| import {Changes} from "../Changes"; | ||||
| 
 | ||||
| export default class ChangeLocationAction extends OsmChangeAction { | ||||
|     constructor(id: string, newLonLat: [number, number], meta: { | ||||
|         theme: string, | ||||
|         reason: string | ||||
|     }) { | ||||
|         super(); | ||||
|         throw "TODO" | ||||
|     } | ||||
| 
 | ||||
|     protected CreateChangeDescriptions(changes: Changes): Promise<ChangeDescription[]> { | ||||
|         return Promise.resolve([]); | ||||
|     } | ||||
| } | ||||
|  | @ -150,6 +150,7 @@ export default class SimpleAddUI extends Toggle { | |||
|                 maxSnapDistance: preset.preciseInput.maxSnapDistance, | ||||
|                 bounds: mapBounds | ||||
|             }) | ||||
|             preciseInput.installBounds(0.15, true) | ||||
|             preciseInput.SetClass("h-32 rounded-xl overflow-hidden border border-gray").SetStyle("height: 12rem;") | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -43,9 +43,13 @@ export default class LocationInput extends InputElement<Loc> implements MinimapO | |||
|     private readonly _bounds: UIEventSource<BBox>; | ||||
|     public readonly _matching_layer: LayerConfig; | ||||
|     private readonly map: BaseUIElement & MinimapObj; | ||||
|     public readonly leafletMap: UIEventSource<any> | ||||
| 
 | ||||
|     private readonly clickLocation: UIEventSource<Loc>; | ||||
|     private readonly _minZoom: number; | ||||
| 
 | ||||
|     constructor(options: { | ||||
|         minZoom?: number, | ||||
|         mapBackground?: UIEventSource<BaseLayer>, | ||||
|         snapTo?: UIEventSource<{ feature: any }[]>, | ||||
|         maxSnapDistance?: number, | ||||
|  | @ -60,6 +64,7 @@ export default class LocationInput extends InputElement<Loc> implements MinimapO | |||
|         this._centerLocation = options.centerLocation; | ||||
|         this._snappedPointTags = options.snappedPointTags | ||||
|         this._bounds = options.bounds; | ||||
|         this._minZoom = options.minZoom | ||||
|         if (this._snapTo === undefined) { | ||||
|             this._value = this._centerLocation; | ||||
|         } else { | ||||
|  | @ -142,6 +147,7 @@ export default class LocationInput extends InputElement<Loc> implements MinimapO | |||
|                 bounds: this._bounds | ||||
|             } | ||||
|         ) | ||||
|         this.leafletMap = this.map.leafletMap | ||||
|     } | ||||
| 
 | ||||
|     GetValue(): UIEventSource<Loc> { | ||||
|  | @ -154,10 +160,9 @@ export default class LocationInput extends InputElement<Loc> implements MinimapO | |||
| 
 | ||||
|     protected InnerConstructElement(): HTMLElement { | ||||
|         try { | ||||
|             const self = this; | ||||
|             this.clickLocation.addCallbackAndRunD(location => this._centerLocation.setData(location)) | ||||
|             this.map.installBounds(0.15, true); | ||||
| 
 | ||||
|             if (this._snapTo !== undefined) { | ||||
|              if (this._snapTo !== undefined) { | ||||
|                  | ||||
|                 // Show the lines to snap to
 | ||||
|                 new ShowDataMultiLayer({ | ||||
|  | @ -191,7 +196,7 @@ export default class LocationInput extends InputElement<Loc> implements MinimapO | |||
|                 } | ||||
| 
 | ||||
|                 leaflet.setMaxZoom(layer.max_zoom) | ||||
|                 leaflet.setMinZoom(layer.max_zoom - 2) | ||||
|                 leaflet.setMinZoom(self._minZoom ?? layer.max_zoom - 2) | ||||
|                 leaflet.setZoom(layer.max_zoom - 1) | ||||
| 
 | ||||
|             }, [this.map.leafletMap]) | ||||
|  | @ -223,7 +228,6 @@ export default class LocationInput extends InputElement<Loc> implements MinimapO | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     readonly leafletMap: UIEventSource<any> = this.map.leafletMap | ||||
|     | ||||
|     installBounds(factor: number | BBox, showRange?: boolean): void { | ||||
|         this.map.installBounds(factor, showRange) | ||||
|  |  | |||
|  | @ -11,45 +11,47 @@ import BaseUIElement from "../BaseUIElement"; | |||
| import LocationInput from "../Input/LocationInput"; | ||||
| import Loc from "../../Models/Loc"; | ||||
| import {GeoOperations} from "../../Logic/GeoOperations"; | ||||
| import {OsmObject} from "../../Logic/Osm/OsmObject"; | ||||
| import {Changes} from "../../Logic/Osm/Changes"; | ||||
| import ChangeLocationAction from "../../Logic/Osm/Actions/ChangeLocationAction"; | ||||
| import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; | ||||
| 
 | ||||
| interface MoveReason  {text: Translation | string, | ||||
| interface MoveReason { | ||||
|     text: Translation | string, | ||||
|     icon: string | BaseUIElement, | ||||
|     changesetCommentValue: string, | ||||
|     lockBounds: true | boolean, | ||||
|     background: undefined | "map" | "photo", | ||||
|     startZoom: number} | ||||
|     startZoom: number, | ||||
|     minZoom: number | ||||
| } | ||||
| 
 | ||||
| export default class MoveWizard extends Toggle { | ||||
|     /** | ||||
|      * The UI-element which helps moving a point | ||||
|      */ | ||||
|     constructor( | ||||
|         featureToMove : any, | ||||
|         featureToMove: any, | ||||
|         state: { | ||||
|         osmConnection: OsmConnection, | ||||
|         featureSwitchUserbadge: UIEventSource<boolean> | ||||
|     },options?: { | ||||
|         reasons?: {text: Translation | string,  | ||||
|             icon: string | BaseUIElement,  | ||||
|             changesetCommentValue: string, | ||||
|             lockBounds?: true | boolean, | ||||
|             background?: undefined | "map" | "photo", | ||||
|             startZoom?: number | 15 | ||||
|         }[] | ||||
|         disableDefaultReasons?: false | boolean | ||||
|             osmConnection: OsmConnection, | ||||
|             featureSwitchUserbadge: UIEventSource<boolean>, | ||||
|             changes: Changes, | ||||
|             layoutToUse: LayoutConfig | ||||
|         }, options?: { | ||||
|             reasons?: MoveReason[] | ||||
|             disableDefaultReasons?: false | boolean | ||||
| 
 | ||||
|     }) { | ||||
|         //State.state.featureSwitchUserbadge
 | ||||
|        // state = State.state
 | ||||
|         }) { | ||||
|         options = options ?? {} | ||||
|        const  t = Translations.t.move | ||||
| 
 | ||||
|         const t = Translations.t.move | ||||
|         const loginButton = new Toggle( | ||||
|           t.loginToMove.Clone()  .SetClass("btn").onClick(() => state.osmConnection.AttemptLogin()), | ||||
|             t.loginToMove.Clone().SetClass("btn").onClick(() => state.osmConnection.AttemptLogin()), | ||||
|             undefined, | ||||
|             state.featureSwitchUserbadge | ||||
|         ) | ||||
| 
 | ||||
|         const currentStep = new UIEventSource<"start" | "reason" | "pick_location">("start") | ||||
|         const currentStep = new UIEventSource<"start" | "reason" | "pick_location" | "moved">("start") | ||||
|         const moveReason = new UIEventSource<MoveReason>(undefined) | ||||
|         const moveButton = new SubtleButton( | ||||
|             Svg.move_ui(), | ||||
|  | @ -58,16 +60,24 @@ export default class MoveWizard extends Toggle { | |||
|             currentStep.setData("reason") | ||||
|         }) | ||||
| 
 | ||||
|         const moveAgainButton = new SubtleButton( | ||||
|             Svg.move_ui(), | ||||
|             t.inviteToMoveAgain.Clone() | ||||
|         ).onClick(() => { | ||||
|             currentStep.setData("reason") | ||||
|         }) | ||||
| 
 | ||||
|         const reasons : MoveReason[] = [] | ||||
|         if(!options.disableDefaultReasons){ | ||||
| 
 | ||||
|         const reasons: MoveReason[] = [] | ||||
|         if (!options.disableDefaultReasons) { | ||||
|             reasons.push({ | ||||
|                 text: t.reasonRelocation.Clone(), | ||||
|                 icon: Svg.relocation_svg(), | ||||
|                 changesetCommentValue: "relocated", | ||||
|                 lockBounds: false, | ||||
|                 background: undefined, | ||||
|                 startZoom: 12 | ||||
|                 startZoom: 12, | ||||
|                 minZoom: 6 | ||||
|             }) | ||||
| 
 | ||||
|             reasons.push({ | ||||
|  | @ -76,7 +86,8 @@ export default class MoveWizard extends Toggle { | |||
|                 changesetCommentValue: "improve_accuracy", | ||||
|                 lockBounds: true, | ||||
|                 background: "photo", | ||||
|                 startZoom: 17 | ||||
|                 startZoom: 17, | ||||
|                 minZoom: 16 | ||||
|             }) | ||||
|         } | ||||
|         for (const reason of options.reasons ?? []) { | ||||
|  | @ -86,7 +97,8 @@ export default class MoveWizard extends Toggle { | |||
|                 changesetCommentValue: reason.changesetCommentValue, | ||||
|                 lockBounds: reason.lockBounds ?? true, | ||||
|                 background: reason.background, | ||||
|                 startZoom: reason.startZoom ?? 15 | ||||
|                 startZoom: reason.startZoom ?? 15, | ||||
|                 minZoom: reason.minZoom | ||||
|             }) | ||||
|         } | ||||
| 
 | ||||
|  | @ -98,34 +110,99 @@ export default class MoveWizard extends Toggle { | |||
|         const cancelButton = new SubtleButton(Svg.close_svg(), t.cancel).onClick(() => currentStep.setData("start")) | ||||
| 
 | ||||
| 
 | ||||
|          | ||||
|         const [lon, lat] = GeoOperations.centerpointCoordinates(featureToMove) | ||||
|         const locationInput = new LocationInput({ | ||||
|             centerLocation: new UIEventSource<Loc>({ | ||||
|         const locationInput = moveReason.map(reason => { | ||||
|             if (reason === undefined) { | ||||
|                 return undefined | ||||
|             } | ||||
|             const loc = new UIEventSource<Loc>({ | ||||
|                 lon: lon, | ||||
|                 lat: lat, | ||||
|                 zoom: moveReason.data.startZoom | ||||
|             }), | ||||
|                 zoom: reason?.startZoom ?? 16 | ||||
|             }) | ||||
| 
 | ||||
|         }) | ||||
|         locationInput.SetStyle("height: 25rem") | ||||
|         super( | ||||
| 
 | ||||
|             const locationInput = new LocationInput({ | ||||
|                 minZoom: reason.minZoom, | ||||
|                 centerLocation: loc | ||||
|             }) | ||||
| 
 | ||||
|             if (reason.lockBounds) { | ||||
|                 locationInput.installBounds(0.05, true) | ||||
|             } | ||||
| 
 | ||||
|             locationInput.SetStyle("height: 17.5rem") | ||||
| 
 | ||||
|             const confirmMove = new SubtleButton(Svg.move_confirm_svg(), t.confirmMove) | ||||
|             confirmMove.onClick(() => { | ||||
|                 state.changes.applyAction(new ChangeLocationAction(featureToMove.properties.id, [locationInput.GetValue().data.lon, locationInput.GetValue().data.lat], { | ||||
|                     reason: Translations.WT(reason.text).textFor("en"), | ||||
|                     theme: state.layoutToUse.icon | ||||
|                 })) | ||||
|                 currentStep.setData("moved") | ||||
|             }) | ||||
|             const zoomInFurhter = t.zoomInFurther.Clone().SetClass("alert block m-6") | ||||
|             return new Combine([ | ||||
|                 locationInput, | ||||
|                 new Toggle(confirmMove, zoomInFurhter, locationInput.GetValue().map(l => l.zoom >= 19)) | ||||
|             ]).SetClass("flex flex-col") | ||||
|         }); | ||||
| 
 | ||||
|         const dialogClasses = "p-2 md:p-4 m-2 border border-gray-400 rounded-xl flex flex-col" | ||||
| 
 | ||||
|         const moveFlow = new Toggle( | ||||
|             new VariableUiElement(currentStep.map(currentStep => { | ||||
|                 switch (currentStep){ | ||||
|                 switch (currentStep) { | ||||
|                     case "start": | ||||
|                         return moveButton; | ||||
|                     case "reason": | ||||
|                         return new Combine([selectReason, cancelButton]); | ||||
|                         return new Combine([t.whyMove.Clone().SetClass("text-lg font-bold"), selectReason, cancelButton]).SetClass(dialogClasses); | ||||
|                     case "pick_location": | ||||
|                         return new Combine([locationInput]) | ||||
|                         return new Combine([t.moveTitle.Clone().SetClass("text-lg font-bold"), new VariableUiElement(locationInput), cancelButton]).SetClass(dialogClasses) | ||||
|                     case "moved": | ||||
|                         return new Combine([t.pointIsMoved.Clone().SetClass("thanks"), moveAgainButton]).SetClass("flex flex-col"); | ||||
| 
 | ||||
|                 } | ||||
| 
 | ||||
| 
 | ||||
|                  | ||||
|                  | ||||
|             })), | ||||
|             loginButton, | ||||
|             state.osmConnection.isLoggedIn | ||||
|         ) | ||||
|         let id = featureToMove.properties.id | ||||
|         const backend = state.osmConnection._oauth_config.url | ||||
|         if (id.startsWith(backend)) { | ||||
|             id = id.substring(backend.length) | ||||
|         } | ||||
| 
 | ||||
|         const moveDisallowedReason = new UIEventSource<BaseUIElement>(undefined) | ||||
|         if (id.startsWith("way")) { | ||||
|             moveDisallowedReason.setData(t.isWay.Clone()) | ||||
|         } else if (id.startsWith("relation")) { | ||||
|             moveDisallowedReason.setData(t.isRelation.Clone()) | ||||
|         } else { | ||||
|              | ||||
|             OsmObject.DownloadReferencingWays(id).then(referencing => { | ||||
|                 if (referencing.length > 0) { | ||||
|                     console.log("Got a referencing way, move not allowed") | ||||
|                     moveDisallowedReason.setData(t.partOfAWay.Clone()) | ||||
|                 } | ||||
|             }) | ||||
|             OsmObject.DownloadReferencingRelations(id).then(partOf => { | ||||
|                 if(partOf.length > 0){ | ||||
|                 moveDisallowedReason.setData(t.partOfRelation.Clone()) | ||||
|                 } | ||||
|             }) | ||||
|         } | ||||
|         super( | ||||
|             moveFlow, | ||||
|             new Combine([ | ||||
|                 Svg.move_not_allowed_svg().SetStyle("height: 2rem"), | ||||
|                 new Combine([t.cannotBeMoved.Clone(), | ||||
|                     new VariableUiElement(moveDisallowedReason).SetClass("subtle") | ||||
|                 ]).SetClass("flex flex-col") | ||||
|             ]).SetClass("flex"), | ||||
|             moveDisallowedReason.map(r => r === undefined) | ||||
|         ) | ||||
|     } | ||||
| } | ||||
|  | @ -965,6 +965,22 @@ | |||
|       "https://commons.wikimedia.org/wiki/File:Move_icon.svg" | ||||
|     ] | ||||
|   }, | ||||
|   { | ||||
|     "path": "move_confirm.svg", | ||||
|     "license": "CC0", | ||||
|     "authors": [ | ||||
|       "Pieter Vander Vennet" | ||||
|     ], | ||||
|     "sources": [] | ||||
|   }, | ||||
|   { | ||||
|     "path": "move_not_allowed.svg", | ||||
|     "license": "CC0", | ||||
|     "authors": [ | ||||
|       "Pieter Vander Vennet" | ||||
|     ], | ||||
|     "sources": [] | ||||
|   }, | ||||
|   { | ||||
|     "path": "no_checkmark.svg", | ||||
|     "license": "CC0; trivial", | ||||
|  |  | |||
							
								
								
									
										281
									
								
								assets/svg/move_confirm.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										281
									
								
								assets/svg/move_confirm.svg
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,281 @@ | |||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="20" | ||||
|    height="20" | ||||
|    viewBox="0 0 20 20" | ||||
|    version="1.1" | ||||
|    id="svg6" | ||||
|    sodipodi:docname="move_confirm.svg" | ||||
|    inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"> | ||||
|   <metadata | ||||
|      id="metadata12"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <defs | ||||
|      id="defs10"> | ||||
|     <filter | ||||
|        style="color-interpolation-filters:sRGB" | ||||
|        filterUnits="userSpaceOnUse" | ||||
|        height="17.436001" | ||||
|        width="25.4126" | ||||
|        y="52.703999" | ||||
|        x="58.84" | ||||
|        id="filter0_d"> | ||||
|       <feFlood | ||||
|          id="feFlood52" | ||||
|          result="BackgroundImageFix" | ||||
|          flood-opacity="0" /> | ||||
|       <feColorMatrix | ||||
|          id="feColorMatrix54" | ||||
|          values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" | ||||
|          type="matrix" | ||||
|          in="SourceAlpha" /> | ||||
|       <feOffset | ||||
|          id="feOffset56" | ||||
|          dy="4" /> | ||||
|       <feGaussianBlur | ||||
|          id="feGaussianBlur58" | ||||
|          stdDeviation="2" /> | ||||
|       <feColorMatrix | ||||
|          id="feColorMatrix60" | ||||
|          values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" | ||||
|          type="matrix" /> | ||||
|       <feBlend | ||||
|          id="feBlend62" | ||||
|          result="effect1_dropShadow" | ||||
|          in2="BackgroundImageFix" | ||||
|          mode="normal" /> | ||||
|       <feBlend | ||||
|          id="feBlend64" | ||||
|          result="shape" | ||||
|          in2="effect1_dropShadow" | ||||
|          in="SourceGraphic" | ||||
|          mode="normal" /> | ||||
|     </filter> | ||||
|     <filter | ||||
|        style="color-interpolation-filters:sRGB" | ||||
|        filterUnits="userSpaceOnUse" | ||||
|        height="38" | ||||
|        width="38.000099" | ||||
|        y="15" | ||||
|        x="14" | ||||
|        id="filter1_d"> | ||||
|       <feFlood | ||||
|          id="feFlood67" | ||||
|          result="BackgroundImageFix" | ||||
|          flood-opacity="0" /> | ||||
|       <feColorMatrix | ||||
|          id="feColorMatrix69" | ||||
|          values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" | ||||
|          type="matrix" | ||||
|          in="SourceAlpha" /> | ||||
|       <feOffset | ||||
|          id="feOffset71" | ||||
|          dy="4" /> | ||||
|       <feGaussianBlur | ||||
|          id="feGaussianBlur73" | ||||
|          stdDeviation="2" /> | ||||
|       <feColorMatrix | ||||
|          id="feColorMatrix75" | ||||
|          values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" | ||||
|          type="matrix" /> | ||||
|       <feBlend | ||||
|          id="feBlend77" | ||||
|          result="effect1_dropShadow" | ||||
|          in2="BackgroundImageFix" | ||||
|          mode="normal" /> | ||||
|       <feBlend | ||||
|          id="feBlend79" | ||||
|          result="shape" | ||||
|          in2="effect1_dropShadow" | ||||
|          in="SourceGraphic" | ||||
|          mode="normal" /> | ||||
|     </filter> | ||||
|     <filter | ||||
|        style="color-interpolation-filters:sRGB" | ||||
|        filterUnits="userSpaceOnUse" | ||||
|        height="53" | ||||
|        width="53" | ||||
|        y="7" | ||||
|        x="39.5" | ||||
|        id="filter2_d"> | ||||
|       <feFlood | ||||
|          id="feFlood82" | ||||
|          result="BackgroundImageFix" | ||||
|          flood-opacity="0" /> | ||||
|       <feColorMatrix | ||||
|          id="feColorMatrix84" | ||||
|          values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" | ||||
|          type="matrix" | ||||
|          in="SourceAlpha" /> | ||||
|       <feOffset | ||||
|          id="feOffset86" | ||||
|          dy="4" /> | ||||
|       <feGaussianBlur | ||||
|          id="feGaussianBlur88" | ||||
|          stdDeviation="2" /> | ||||
|       <feColorMatrix | ||||
|          id="feColorMatrix90" | ||||
|          values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" | ||||
|          type="matrix" /> | ||||
|       <feBlend | ||||
|          id="feBlend92" | ||||
|          result="effect1_dropShadow" | ||||
|          in2="BackgroundImageFix" | ||||
|          mode="normal" /> | ||||
|       <feBlend | ||||
|          id="feBlend94" | ||||
|          result="shape" | ||||
|          in2="effect1_dropShadow" | ||||
|          in="SourceGraphic" | ||||
|          mode="normal" /> | ||||
|     </filter> | ||||
|     <filter | ||||
|        style="color-interpolation-filters:sRGB" | ||||
|        filterUnits="userSpaceOnUse" | ||||
|        height="38.142899" | ||||
|        width="54.766701" | ||||
|        y="54" | ||||
|        x="11" | ||||
|        id="filter3_d"> | ||||
|       <feFlood | ||||
|          id="feFlood97" | ||||
|          result="BackgroundImageFix" | ||||
|          flood-opacity="0" /> | ||||
|       <feColorMatrix | ||||
|          id="feColorMatrix99" | ||||
|          values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" | ||||
|          type="matrix" | ||||
|          in="SourceAlpha" /> | ||||
|       <feOffset | ||||
|          id="feOffset101" | ||||
|          dy="4" /> | ||||
|       <feGaussianBlur | ||||
|          id="feGaussianBlur103" | ||||
|          stdDeviation="2" /> | ||||
|       <feColorMatrix | ||||
|          id="feColorMatrix105" | ||||
|          values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" | ||||
|          type="matrix" /> | ||||
|       <feBlend | ||||
|          id="feBlend107" | ||||
|          result="effect1_dropShadow" | ||||
|          in2="BackgroundImageFix" | ||||
|          mode="normal" /> | ||||
|       <feBlend | ||||
|          id="feBlend109" | ||||
|          result="shape" | ||||
|          in2="effect1_dropShadow" | ||||
|          in="SourceGraphic" | ||||
|          mode="normal" /> | ||||
|     </filter> | ||||
|     <filter | ||||
|        style="color-interpolation-filters:sRGB" | ||||
|        filterUnits="userSpaceOnUse" | ||||
|        height="29" | ||||
|        width="28" | ||||
|        y="64" | ||||
|        x="41" | ||||
|        id="filter4_d"> | ||||
|       <feFlood | ||||
|          id="feFlood112" | ||||
|          result="BackgroundImageFix" | ||||
|          flood-opacity="0" /> | ||||
|       <feColorMatrix | ||||
|          id="feColorMatrix114" | ||||
|          values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" | ||||
|          type="matrix" | ||||
|          in="SourceAlpha" /> | ||||
|       <feOffset | ||||
|          id="feOffset116" | ||||
|          dy="4" /> | ||||
|       <feGaussianBlur | ||||
|          id="feGaussianBlur118" | ||||
|          stdDeviation="2" /> | ||||
|       <feColorMatrix | ||||
|          id="feColorMatrix120" | ||||
|          values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" | ||||
|          type="matrix" /> | ||||
|       <feBlend | ||||
|          id="feBlend122" | ||||
|          result="effect1_dropShadow" | ||||
|          in2="BackgroundImageFix" | ||||
|          mode="normal" /> | ||||
|       <feBlend | ||||
|          id="feBlend124" | ||||
|          result="shape" | ||||
|          in2="effect1_dropShadow" | ||||
|          in="SourceGraphic" | ||||
|          mode="normal" /> | ||||
|     </filter> | ||||
|     <clipPath | ||||
|        id="clip0"> | ||||
|       <rect | ||||
|          style="fill:#ffffff" | ||||
|          y="0" | ||||
|          x="0" | ||||
|          id="rect127" | ||||
|          transform="rotate(-45,57.35965,-37.759145)" | ||||
|          height="31.819799" | ||||
|          width="31.819799" /> | ||||
|     </clipPath> | ||||
|   </defs> | ||||
|   <sodipodi:namedview | ||||
|      pagecolor="#ffffff" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1" | ||||
|      objecttolerance="10" | ||||
|      gridtolerance="10" | ||||
|      guidetolerance="10" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:window-width="960" | ||||
|      inkscape:window-height="1003" | ||||
|      id="namedview8" | ||||
|      showgrid="false" | ||||
|      inkscape:zoom="11.8" | ||||
|      inkscape:cx="14.211286" | ||||
|      inkscape:cy="-5.2054641" | ||||
|      inkscape:window-x="960" | ||||
|      inkscape:window-y="0" | ||||
|      inkscape:window-maximized="0" | ||||
|      inkscape:current-layer="svg6" /> | ||||
|   <title | ||||
|      id="title2"> | ||||
|     move | ||||
|   </title> | ||||
|   <path | ||||
|      d="M19 10l-4-3v2h-4V5h2l-3-4-3 4h2v4H5V7l-4 3 4 3v-2h4v4H7l3 4 3-4h-2v-4h4v2l4-3z" | ||||
|      id="path4" /> | ||||
|   <g | ||||
|      id="g942" | ||||
|      transform="matrix(0.42132349,0,0,0.42132349,8.3654416,8.6801476)"> | ||||
|     <circle | ||||
|        style="fill:#37d649;fill-opacity:1;stroke:none;stroke-width:0.20323335;stroke-opacity:1" | ||||
|        id="circle4" | ||||
|        r="9.9584341" | ||||
|        cy="15.401706" | ||||
|        cx="16.186441" /> | ||||
|     <path | ||||
|        inkscape:transform-center-y="40.988227" | ||||
|        inkscape:transform-center-x="14.392136" | ||||
|        id="path924" | ||||
|        d="m 11,15 4.5,5 6,-8" | ||||
|        inkscape:connector-curvature="0" | ||||
|        style="fill:none;stroke:#ffffff;stroke-width:2.5;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 7.5 KiB | 
							
								
								
									
										285
									
								
								assets/svg/move_not_allowed.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										285
									
								
								assets/svg/move_not_allowed.svg
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,285 @@ | |||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="20" | ||||
|    height="20" | ||||
|    viewBox="0 0 20 20" | ||||
|    version="1.1" | ||||
|    id="svg6" | ||||
|    sodipodi:docname="move_not_allowed.svg" | ||||
|    inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"> | ||||
|   <metadata | ||||
|      id="metadata12"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <defs | ||||
|      id="defs10"> | ||||
|     <filter | ||||
|        style="color-interpolation-filters:sRGB" | ||||
|        filterUnits="userSpaceOnUse" | ||||
|        height="17.436001" | ||||
|        width="25.4126" | ||||
|        y="52.703999" | ||||
|        x="58.84" | ||||
|        id="filter0_d"> | ||||
|       <feFlood | ||||
|          id="feFlood52" | ||||
|          result="BackgroundImageFix" | ||||
|          flood-opacity="0" /> | ||||
|       <feColorMatrix | ||||
|          id="feColorMatrix54" | ||||
|          values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" | ||||
|          type="matrix" | ||||
|          in="SourceAlpha" /> | ||||
|       <feOffset | ||||
|          id="feOffset56" | ||||
|          dy="4" /> | ||||
|       <feGaussianBlur | ||||
|          id="feGaussianBlur58" | ||||
|          stdDeviation="2" /> | ||||
|       <feColorMatrix | ||||
|          id="feColorMatrix60" | ||||
|          values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" | ||||
|          type="matrix" /> | ||||
|       <feBlend | ||||
|          id="feBlend62" | ||||
|          result="effect1_dropShadow" | ||||
|          in2="BackgroundImageFix" | ||||
|          mode="normal" /> | ||||
|       <feBlend | ||||
|          id="feBlend64" | ||||
|          result="shape" | ||||
|          in2="effect1_dropShadow" | ||||
|          in="SourceGraphic" | ||||
|          mode="normal" /> | ||||
|     </filter> | ||||
|     <filter | ||||
|        style="color-interpolation-filters:sRGB" | ||||
|        filterUnits="userSpaceOnUse" | ||||
|        height="38" | ||||
|        width="38.000099" | ||||
|        y="15" | ||||
|        x="14" | ||||
|        id="filter1_d"> | ||||
|       <feFlood | ||||
|          id="feFlood67" | ||||
|          result="BackgroundImageFix" | ||||
|          flood-opacity="0" /> | ||||
|       <feColorMatrix | ||||
|          id="feColorMatrix69" | ||||
|          values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" | ||||
|          type="matrix" | ||||
|          in="SourceAlpha" /> | ||||
|       <feOffset | ||||
|          id="feOffset71" | ||||
|          dy="4" /> | ||||
|       <feGaussianBlur | ||||
|          id="feGaussianBlur73" | ||||
|          stdDeviation="2" /> | ||||
|       <feColorMatrix | ||||
|          id="feColorMatrix75" | ||||
|          values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" | ||||
|          type="matrix" /> | ||||
|       <feBlend | ||||
|          id="feBlend77" | ||||
|          result="effect1_dropShadow" | ||||
|          in2="BackgroundImageFix" | ||||
|          mode="normal" /> | ||||
|       <feBlend | ||||
|          id="feBlend79" | ||||
|          result="shape" | ||||
|          in2="effect1_dropShadow" | ||||
|          in="SourceGraphic" | ||||
|          mode="normal" /> | ||||
|     </filter> | ||||
|     <filter | ||||
|        style="color-interpolation-filters:sRGB" | ||||
|        filterUnits="userSpaceOnUse" | ||||
|        height="53" | ||||
|        width="53" | ||||
|        y="7" | ||||
|        x="39.5" | ||||
|        id="filter2_d"> | ||||
|       <feFlood | ||||
|          id="feFlood82" | ||||
|          result="BackgroundImageFix" | ||||
|          flood-opacity="0" /> | ||||
|       <feColorMatrix | ||||
|          id="feColorMatrix84" | ||||
|          values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" | ||||
|          type="matrix" | ||||
|          in="SourceAlpha" /> | ||||
|       <feOffset | ||||
|          id="feOffset86" | ||||
|          dy="4" /> | ||||
|       <feGaussianBlur | ||||
|          id="feGaussianBlur88" | ||||
|          stdDeviation="2" /> | ||||
|       <feColorMatrix | ||||
|          id="feColorMatrix90" | ||||
|          values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" | ||||
|          type="matrix" /> | ||||
|       <feBlend | ||||
|          id="feBlend92" | ||||
|          result="effect1_dropShadow" | ||||
|          in2="BackgroundImageFix" | ||||
|          mode="normal" /> | ||||
|       <feBlend | ||||
|          id="feBlend94" | ||||
|          result="shape" | ||||
|          in2="effect1_dropShadow" | ||||
|          in="SourceGraphic" | ||||
|          mode="normal" /> | ||||
|     </filter> | ||||
|     <filter | ||||
|        style="color-interpolation-filters:sRGB" | ||||
|        filterUnits="userSpaceOnUse" | ||||
|        height="38.142899" | ||||
|        width="54.766701" | ||||
|        y="54" | ||||
|        x="11" | ||||
|        id="filter3_d"> | ||||
|       <feFlood | ||||
|          id="feFlood97" | ||||
|          result="BackgroundImageFix" | ||||
|          flood-opacity="0" /> | ||||
|       <feColorMatrix | ||||
|          id="feColorMatrix99" | ||||
|          values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" | ||||
|          type="matrix" | ||||
|          in="SourceAlpha" /> | ||||
|       <feOffset | ||||
|          id="feOffset101" | ||||
|          dy="4" /> | ||||
|       <feGaussianBlur | ||||
|          id="feGaussianBlur103" | ||||
|          stdDeviation="2" /> | ||||
|       <feColorMatrix | ||||
|          id="feColorMatrix105" | ||||
|          values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" | ||||
|          type="matrix" /> | ||||
|       <feBlend | ||||
|          id="feBlend107" | ||||
|          result="effect1_dropShadow" | ||||
|          in2="BackgroundImageFix" | ||||
|          mode="normal" /> | ||||
|       <feBlend | ||||
|          id="feBlend109" | ||||
|          result="shape" | ||||
|          in2="effect1_dropShadow" | ||||
|          in="SourceGraphic" | ||||
|          mode="normal" /> | ||||
|     </filter> | ||||
|     <filter | ||||
|        style="color-interpolation-filters:sRGB" | ||||
|        filterUnits="userSpaceOnUse" | ||||
|        height="29" | ||||
|        width="28" | ||||
|        y="64" | ||||
|        x="41" | ||||
|        id="filter4_d"> | ||||
|       <feFlood | ||||
|          id="feFlood112" | ||||
|          result="BackgroundImageFix" | ||||
|          flood-opacity="0" /> | ||||
|       <feColorMatrix | ||||
|          id="feColorMatrix114" | ||||
|          values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" | ||||
|          type="matrix" | ||||
|          in="SourceAlpha" /> | ||||
|       <feOffset | ||||
|          id="feOffset116" | ||||
|          dy="4" /> | ||||
|       <feGaussianBlur | ||||
|          id="feGaussianBlur118" | ||||
|          stdDeviation="2" /> | ||||
|       <feColorMatrix | ||||
|          id="feColorMatrix120" | ||||
|          values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" | ||||
|          type="matrix" /> | ||||
|       <feBlend | ||||
|          id="feBlend122" | ||||
|          result="effect1_dropShadow" | ||||
|          in2="BackgroundImageFix" | ||||
|          mode="normal" /> | ||||
|       <feBlend | ||||
|          id="feBlend124" | ||||
|          result="shape" | ||||
|          in2="effect1_dropShadow" | ||||
|          in="SourceGraphic" | ||||
|          mode="normal" /> | ||||
|     </filter> | ||||
|     <clipPath | ||||
|        id="clip0"> | ||||
|       <rect | ||||
|          style="fill:#ffffff" | ||||
|          y="0" | ||||
|          x="0" | ||||
|          id="rect127" | ||||
|          transform="rotate(-45,57.35965,-37.759145)" | ||||
|          height="31.819799" | ||||
|          width="31.819799" /> | ||||
|     </clipPath> | ||||
|   </defs> | ||||
|   <sodipodi:namedview | ||||
|      pagecolor="#ffffff" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1" | ||||
|      objecttolerance="10" | ||||
|      gridtolerance="10" | ||||
|      guidetolerance="10" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1003" | ||||
|      id="namedview8" | ||||
|      showgrid="false" | ||||
|      inkscape:zoom="11.8" | ||||
|      inkscape:cx="-2.6072629" | ||||
|      inkscape:cy="5.7824568" | ||||
|      inkscape:window-x="0" | ||||
|      inkscape:window-y="0" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:current-layer="svg6" /> | ||||
|   <title | ||||
|      id="title2"> | ||||
|     move | ||||
|   </title> | ||||
|   <path | ||||
|      d="M19 10l-4-3v2h-4V5h2l-3-4-3 4h2v4H5V7l-4 3 4 3v-2h4v4H7l3 4 3-4h-2v-4h4v2l4-3z" | ||||
|      id="path4" /> | ||||
|   <circle | ||||
|      cx="14.76144" | ||||
|      cy="14.745519" | ||||
|      id="circle4" | ||||
|      style="fill:#e72c44;fill-opacity:1;stroke:none;stroke-width:0.09427451;stroke-opacity:1" | ||||
|      r="4.619451" /> | ||||
|   <g | ||||
|      transform="matrix(0.20049776,0,0,0.20049776,12.17322,-42.226005)" | ||||
|      id="layer1" | ||||
|      inkscape:label="Layer 1"> | ||||
|     <path | ||||
|        inkscape:connector-curvature="0" | ||||
|        id="path815" | ||||
|        d="M 22.551907,293.60329 2.927466,273.97885 v 0" | ||||
|        style="fill:none;stroke:#ffffff;stroke-width:6.0128417;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | ||||
|     <path | ||||
|        inkscape:connector-curvature="0" | ||||
|        id="path815-3" | ||||
|        d="M 22.581499,273.88422 2.9570535,293.50867 v 0" | ||||
|        style="fill:none;stroke:#fcffff;stroke-width:6.0128417;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 7.8 KiB | 
|  | @ -820,6 +820,10 @@ video { | |||
|   margin: 0.75rem; | ||||
| } | ||||
| 
 | ||||
| .m-6 { | ||||
|   margin: 1.5rem; | ||||
| } | ||||
| 
 | ||||
| .m-4 { | ||||
|   margin: 1rem; | ||||
| } | ||||
|  | @ -892,6 +896,10 @@ video { | |||
|   margin-left: 0.5rem; | ||||
| } | ||||
| 
 | ||||
| .mb-4 { | ||||
|   margin-bottom: 1rem; | ||||
| } | ||||
| 
 | ||||
| .mt-4 { | ||||
|   margin-top: 1rem; | ||||
| } | ||||
|  | @ -912,10 +920,6 @@ video { | |||
|   margin-bottom: 0.25rem; | ||||
| } | ||||
| 
 | ||||
| .mb-4 { | ||||
|   margin-bottom: 1rem; | ||||
| } | ||||
| 
 | ||||
| .box-border { | ||||
|   box-sizing: border-box; | ||||
| } | ||||
|  | @ -2365,6 +2369,10 @@ li::marker { | |||
|     padding: 0.5rem; | ||||
|   } | ||||
| 
 | ||||
|   .md\:p-4 { | ||||
|     padding: 1rem; | ||||
|   } | ||||
| 
 | ||||
|   .md\:pt-4 { | ||||
|     padding-top: 1rem; | ||||
|   } | ||||
|  |  | |||
|  | @ -250,11 +250,20 @@ | |||
|     "move": { | ||||
|         "loginToMove": "You must be logged in to move a point", | ||||
|         "inviteToMove": "Move this point", | ||||
|         "inviteToMoveAgain": "Move this point again", | ||||
|         "moveTitle": "Move this point", | ||||
|         "whyMove": "Why do you want to move this point?", | ||||
|         "confirmMove": "Move here", | ||||
|         "pointIsMoved": "The point has been moved", | ||||
|         "zoomInFurther": "Zoom in further to confirm this move", | ||||
|         "selectReason": "Why do you move this object?", | ||||
|         "reasonRelocation": "The object has been relocated to a totally different location", | ||||
|         "reasonInaccurate": "The location of this object is inaccurate and should be moved a few meter", | ||||
|         "onlyPoints": "Only points can be moved", | ||||
|         "isWay": "This feature is a way", | ||||
|         "cannotBeMoved": "This feature cannot be moved.", | ||||
|         "isWay": "This feature is a way. Use another OpenStreetMap editor to move it.", | ||||
|         "isRelation": "This feature is a relation and can not be moved", | ||||
|         "partOfAWay": "This feature is part of another way. Use another editor to move it", | ||||
|         "partOfRelation": "This feature is part of a relation. Use another editor to move it", | ||||
|         "cancel": "Cancel move" | ||||
|     } | ||||
| } | ||||
							
								
								
									
										4
									
								
								test.ts
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								test.ts
									
										
									
									
									
								
							|  | @ -7,7 +7,9 @@ import MinimapImplementation from "./UI/Base/MinimapImplementation"; | |||
| State.state = new State(AllKnownLayouts.allKnownLayouts.get("bookcases")) | ||||
| const feature = { | ||||
|     "type": "Feature", | ||||
|     "properties": {}, | ||||
|     "properties": { | ||||
|         id: "node/14925464" | ||||
|     }, | ||||
|     "geometry": { | ||||
|         "type": "Point", | ||||
|         "coordinates": [ | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue