forked from MapComplete/MapComplete
		
	Add move option, enable move and delete option on most layers
This commit is contained in:
		
							parent
							
								
									0a3eb966c1
								
							
						
					
					
						commit
						7e2b73ac5d
					
				
					 33 changed files with 454 additions and 104 deletions
				
			
		|  | @ -18,7 +18,6 @@ export default class ChangeLocationAction extends OsmChangeAction { | |||
|         this._id = Number(id.substring("node/".length)) | ||||
|         this._newLonLat = newLonLat; | ||||
|         this._meta = meta; | ||||
|         throw "TODO" | ||||
|     } | ||||
| 
 | ||||
|     protected async CreateChangeDescriptions(changes: Changes): Promise<ChangeDescription[]> { | ||||
|  |  | |||
|  | @ -59,14 +59,13 @@ export abstract class OsmObject { | |||
|      | ||||
|     static async DownloadPropertiesOf(id: string): Promise<any> { | ||||
|         const splitted = id.split("/"); | ||||
|         const type = splitted[0]; | ||||
|         const idN = Number(splitted[1]); | ||||
|         if (idN < 0) { | ||||
|             return undefined; | ||||
|         } | ||||
| 
 | ||||
|         const url = `${OsmObject.backendURL}api/0.6/${id}`; | ||||
|         const rawData = await Utils.downloadJson(url) | ||||
|         const rawData = await Utils.downloadJsonCached(url, 1000) | ||||
|         return rawData.elements[0].tags | ||||
|     } | ||||
| 
 | ||||
|  | @ -80,7 +79,7 @@ export abstract class OsmObject { | |||
| 
 | ||||
|         const full = (id.startsWith("way")) ? "/full" : ""; | ||||
|         const url = `${OsmObject.backendURL}api/0.6/${id}${full}`; | ||||
|         const rawData = await Utils.downloadJson(url) | ||||
|         const rawData = await Utils.downloadJsonCached(url, 1000) | ||||
|         // A full query might contain more then just the requested object (e.g. nodes that are part of a way, where we only want the way)
 | ||||
|         const parsed = OsmObject.ParseObjects(rawData.elements); | ||||
|         // Lets fetch the object we need
 | ||||
|  | @ -105,7 +104,7 @@ export abstract class OsmObject { | |||
|      * Beware: their geometry will be incomplete! | ||||
|      */ | ||||
|     public static DownloadReferencingWays(id: string): Promise<OsmWay[]> { | ||||
|         return Utils.downloadJson(`${OsmObject.backendURL}api/0.6/${id}/ways`).then( | ||||
|         return Utils.downloadJsonCached(`${OsmObject.backendURL}api/0.6/${id}/ways`, 60 * 1000).then( | ||||
|             data => { | ||||
|                 return data.elements.map(wayInfo => { | ||||
|                     const way = new OsmWay(wayInfo.id) | ||||
|  | @ -121,7 +120,7 @@ export abstract class OsmObject { | |||
|      * Beware: their geometry will be incomplete! | ||||
|      */ | ||||
|     public static async DownloadReferencingRelations(id: string): Promise<OsmRelation[]> { | ||||
|         const data = await Utils.downloadJson(`${OsmObject.backendURL}api/0.6/${id}/relations`) | ||||
|         const data = await Utils.downloadJsonCached(`${OsmObject.backendURL}api/0.6/${id}/relations`, 60 * 1000) | ||||
|         return data.elements.map(wayInfo => { | ||||
|             const rel = new OsmRelation(wayInfo.id) | ||||
|             rel.LoadData(wayInfo) | ||||
|  | @ -139,7 +138,7 @@ export abstract class OsmObject { | |||
|         const idN = Number(splitted[1]); | ||||
|         const src = new UIEventSource<OsmObject[]>([]); | ||||
|         OsmObject.historyCache.set(id, src); | ||||
|         Utils.downloadJson(`${OsmObject.backendURL}api/0.6/${type}/${idN}/history`).then(data => { | ||||
|         Utils.downloadJsonCached(`${OsmObject.backendURL}api/0.6/${type}/${idN}/history`, 10 * 60 * 1000).then(data => { | ||||
|             const elements: any[] = data.elements; | ||||
|             const osmObjects: OsmObject[] = [] | ||||
|             for (const element of elements) { | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ import {TagRenderingConfigJson} from "./TagRenderingConfigJson"; | |||
| import FilterConfigJson from "./FilterConfigJson"; | ||||
| import {DeleteConfigJson} from "./DeleteConfigJson"; | ||||
| import UnitConfigJson from "./UnitConfigJson"; | ||||
| import MoveConfigJson from "./MoveConfigJson"; | ||||
| 
 | ||||
| /** | ||||
|  * Configuration for a single layer | ||||
|  | @ -314,6 +315,18 @@ export interface LayerConfigJson { | |||
|      */ | ||||
|     deletion?: boolean | DeleteConfigJson | ||||
| 
 | ||||
|     /** | ||||
|      * Indicates if a point can be moved and configures the modalities. | ||||
|      *  | ||||
|      * A feature can be moved by MapComplete if: | ||||
|      *  | ||||
|      * - It is a point | ||||
|      * - The point is _not_ part of a way or a a relation. | ||||
|      *  | ||||
|      * Off by default. Can be enabled by setting this flag or by configuring. | ||||
|      */ | ||||
|     allowMove?: boolean | MoveConfigJson  | ||||
| 
 | ||||
|     /** | ||||
|      * IF set, a 'split this road' button is shown | ||||
|      */ | ||||
|  |  | |||
							
								
								
									
										12
									
								
								Models/ThemeConfig/Json/MoveConfigJson.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								Models/ThemeConfig/Json/MoveConfigJson.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,12 @@ | |||
| export default interface MoveConfigJson { | ||||
|     /** | ||||
|      * One default reason to move a point is to improve accuracy. | ||||
|      * Set to false to disable this reason | ||||
|      */ | ||||
|     enableImproveAccuracy?: true | boolean | ||||
|     /** | ||||
|      * One default reason to move a point is because it has relocated | ||||
|      * Set to false to disable this reason | ||||
|      */ | ||||
|     enableRelocation?: true | boolean | ||||
| } | ||||
|  | @ -19,6 +19,7 @@ import {Unit} from "../Unit"; | |||
| import DeleteConfig from "./DeleteConfig"; | ||||
| import Svg from "../../Svg"; | ||||
| import Img from "../../UI/Base/Img"; | ||||
| import MoveConfig from "./MoveConfig"; | ||||
| 
 | ||||
| export default class LayerConfig { | ||||
|     static WAYHANDLING_DEFAULT = 0; | ||||
|  | @ -49,6 +50,7 @@ export default class LayerConfig { | |||
|     wayHandling: number; | ||||
|     public readonly units: Unit[]; | ||||
|     public readonly deletion: DeleteConfig | null; | ||||
|     public readonly allowMove: MoveConfig | null | ||||
|     public readonly allowSplit: boolean | ||||
| 
 | ||||
|     presets: PresetConfig[]; | ||||
|  | @ -67,7 +69,7 @@ export default class LayerConfig { | |||
|         this.id = json.id; | ||||
|         this.allowSplit = json.allowSplit ?? false; | ||||
|         this.name = Translations.T(json.name, context + ".name"); | ||||
|         this.units =   (json.units ?? []).map(((unitJson, i) => Unit.fromJson(unitJson, `${context}.unit[${i}]`))) | ||||
|         this.units = (json.units ?? []).map(((unitJson, i) => Unit.fromJson(unitJson, `${context}.unit[${i}]`))) | ||||
| 
 | ||||
|         if (json.description !== undefined) { | ||||
|             if (Object.keys(json.description).length === 0) { | ||||
|  | @ -138,11 +140,11 @@ export default class LayerConfig { | |||
|                 const key = kv.substring(0, index); | ||||
|                 const code = kv.substring(index + 1); | ||||
| 
 | ||||
|                 try{ | ||||
|                 try { | ||||
| 
 | ||||
|                 new Function("feat", "return " + code + ";"); | ||||
|                 }catch(e){ | ||||
|                  throw `Invalid function definition: code ${code} is invalid:${e} (at ${context})`    | ||||
|                     new Function("feat", "return " + code + ";"); | ||||
|                 } catch (e) { | ||||
|                     throw `Invalid function definition: code ${code} is invalid:${e} (at ${context})` | ||||
|                 } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -155,8 +157,8 @@ export default class LayerConfig { | |||
|         this.minzoom = json.minzoom ?? 0; | ||||
|         this.minzoomVisible = json.minzoomVisible ?? this.minzoom; | ||||
|         this.wayHandling = json.wayHandling ?? 0; | ||||
|         if(json.presets !== undefined && json.presets?.map === undefined){ | ||||
|             throw "Presets should be a list of items (at "+context+")" | ||||
|         if (json.presets !== undefined && json.presets?.map === undefined) { | ||||
|             throw "Presets should be a list of items (at " + context + ")" | ||||
|         } | ||||
|         this.presets = (json.presets ?? []).map((pr, i) => { | ||||
| 
 | ||||
|  | @ -292,20 +294,20 @@ export default class LayerConfig { | |||
| 
 | ||||
|         this.tagRenderings = trs(json.tagRenderings, false); | ||||
| 
 | ||||
|        const missingIds = json.tagRenderings?.filter(tr => typeof tr !== "string" && tr["builtin"] === undefined && tr["id"] === undefined) ?? []; | ||||
|         const missingIds = json.tagRenderings?.filter(tr => typeof tr !== "string" && tr["builtin"] === undefined && tr["id"] === undefined) ?? []; | ||||
| 
 | ||||
|        if(missingIds.length > 0 && official){ | ||||
|            console.error("Some tagRenderings of", this.id, "are missing an id:", missingIds) | ||||
|            throw "Missing ids in tagrenderings" | ||||
|        } | ||||
|         if (missingIds.length > 0 && official) { | ||||
|             console.error("Some tagRenderings of", this.id, "are missing an id:", missingIds) | ||||
|             throw "Missing ids in tagrenderings" | ||||
|         } | ||||
| 
 | ||||
|         this.filters = (json.filter ?? []).map((option, i) => { | ||||
|             return new FilterConfig(option, `${context}.filter-[${i}]`) | ||||
|         }); | ||||
| 
 | ||||
|        if(json["filters"] !== undefined){ | ||||
|            throw "Error in "+context+": use 'filter' instead of 'filters'" | ||||
|        } | ||||
|         if (json["filters"] !== undefined) { | ||||
|             throw "Error in " + context + ": use 'filter' instead of 'filters'" | ||||
|         } | ||||
| 
 | ||||
|         const titleIcons = []; | ||||
|         const defaultIcons = [ | ||||
|  | @ -369,6 +371,16 @@ export default class LayerConfig { | |||
|             this.deletion = new DeleteConfig(json.deletion, `${context}.deletion`); | ||||
|         } | ||||
| 
 | ||||
|         this.allowMove = null | ||||
|         if (json.allowMove === false) { | ||||
|             this.allowMove = null; | ||||
|         } else if (json.allowMove === true) { | ||||
|             this.allowMove = new MoveConfig({}, context + ".allowMove") | ||||
|         } else if (json.allowMove !== undefined && json.allowMove !== false) { | ||||
|             this.allowMove = new MoveConfig(json.allowMove, context + ".allowMove") | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         if (json["showIf"] !== undefined) { | ||||
|             throw ( | ||||
|                 "Invalid key on layerconfig " + | ||||
|  |  | |||
							
								
								
									
										17
									
								
								Models/ThemeConfig/MoveConfig.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								Models/ThemeConfig/MoveConfig.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | |||
| import MoveConfigJson from "./Json/MoveConfigJson"; | ||||
| 
 | ||||
| export default class MoveConfig { | ||||
| 
 | ||||
|     public readonly enableImproveAccuracy: boolean | ||||
|     public readonly enableRelocation: boolean | ||||
| 
 | ||||
|     constructor(json: MoveConfigJson, context: string) { | ||||
|         this.enableImproveAccuracy = json.enableImproveAccuracy ?? true | ||||
|         this.enableRelocation = json.enableRelocation ?? true | ||||
|         if (!(this.enableRelocation || this.enableImproveAccuracy)) { | ||||
|             throw "At least one default move reason should be allowed (at " + context + ")" | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|  | @ -15,6 +15,7 @@ import {BBox} from "../../Logic/BBox"; | |||
| import {FixedUiElement} from "../Base/FixedUiElement"; | ||||
| import ShowDataLayer from "../ShowDataLayer/ShowDataLayer"; | ||||
| import BaseUIElement from "../BaseUIElement"; | ||||
| import Toggle from "./Toggle"; | ||||
| 
 | ||||
| export default class LocationInput extends InputElement<Loc> implements MinimapObj { | ||||
| 
 | ||||
|  | @ -161,6 +162,11 @@ export default class LocationInput extends InputElement<Loc> implements MinimapO | |||
|     protected InnerConstructElement(): HTMLElement { | ||||
|         try { | ||||
|             const self = this; | ||||
|             const hasMoved = new UIEventSource(false) | ||||
|             this.GetValue().addCallbackAndRunD(_ => { | ||||
|                 hasMoved.setData(true) | ||||
|                 return true; | ||||
|             }) | ||||
|             this.clickLocation.addCallbackAndRunD(location => this._centerLocation.setData(location)) | ||||
|              if (this._snapTo !== undefined) { | ||||
|                  | ||||
|  | @ -213,8 +219,8 @@ export default class LocationInput extends InputElement<Loc> implements MinimapO | |||
|                     ]).SetClass("block w-0 h-0 z-10 relative") | ||||
|                     .SetStyle("background: rgba(255, 128, 128, 0.21); left: 50%; top: 50%; opacity: 0.5"), | ||||
|                  | ||||
|                 new Combine([ | ||||
|                     animatedHand]) | ||||
|                 new Toggle(undefined, | ||||
|                     animatedHand, hasMoved) | ||||
|                     .SetClass("block w-0 h-0 z-10 relative") | ||||
|                     .SetStyle("left: calc(50% + 3rem); top: calc(50% + 2rem); opacity: 0.7"), | ||||
| 
 | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; | |||
| import {Translation} from "../i18n/Translation"; | ||||
| import {Utils} from "../../Utils"; | ||||
| import {SubstitutedTranslation} from "../SubstitutedTranslation"; | ||||
| import MoveWizard from "./MoveWizard"; | ||||
| 
 | ||||
| export default class FeatureInfoBox extends ScrollableFullScreen { | ||||
| 
 | ||||
|  | @ -72,6 +73,19 @@ export default class FeatureInfoBox extends ScrollableFullScreen { | |||
|             editElements.push(questionBox); | ||||
|         } | ||||
| 
 | ||||
|         if(layerConfig.allowMove) { | ||||
|             editElements.push( | ||||
|                 new VariableUiElement(tags.map(tags => tags.id).map(id => { | ||||
|                         const feature = State.state.allElements.ContainingFeatures.get(id) | ||||
|                         return new MoveWizard( | ||||
|                             feature, | ||||
|                             State.state, | ||||
|                             layerConfig.allowMove | ||||
|                         ); | ||||
|                     }) | ||||
|                 ) | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         if (layerConfig.deletion) { | ||||
|             editElements.push( | ||||
|  |  | |||
|  | @ -15,13 +15,17 @@ 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"; | ||||
| import MoveConfig from "../../Models/ThemeConfig/MoveConfig"; | ||||
| import AvailableBaseLayers from "../../Logic/Actors/AvailableBaseLayers"; | ||||
| import {ElementStorage} from "../../Logic/ElementStorage"; | ||||
| 
 | ||||
| interface MoveReason { | ||||
|     text: Translation | string, | ||||
|     invitingText: Translation | string, | ||||
|     icon: string | BaseUIElement, | ||||
|     changesetCommentValue: string, | ||||
|     lockBounds: true | boolean, | ||||
|     background: undefined | "map" | "photo", | ||||
|     background: undefined | "map" | "photo" | string | string[], | ||||
|     startZoom: number, | ||||
|     minZoom: number | ||||
| } | ||||
|  | @ -36,13 +40,9 @@ export default class MoveWizard extends Toggle { | |||
|             osmConnection: OsmConnection, | ||||
|             featureSwitchUserbadge: UIEventSource<boolean>, | ||||
|             changes: Changes, | ||||
|             layoutToUse: LayoutConfig | ||||
|         }, options?: { | ||||
|             reasons?: MoveReason[] | ||||
|             disableDefaultReasons?: false | boolean | ||||
| 
 | ||||
|         }) { | ||||
|         options = options ?? {} | ||||
|             layoutToUse: LayoutConfig, | ||||
|             allElements: ElementStorage | ||||
|         }, options : MoveConfig) { | ||||
| 
 | ||||
|         const t = Translations.t.move | ||||
|         const loginButton = new Toggle( | ||||
|  | @ -51,14 +51,53 @@ export default class MoveWizard extends Toggle { | |||
|             state.featureSwitchUserbadge | ||||
|         ) | ||||
| 
 | ||||
|         const reasons: MoveReason[] = [] | ||||
|         if (options.enableRelocation) { | ||||
|             reasons.push({ | ||||
|                 text: t.reasons.reasonRelocation.Clone(), | ||||
|                 invitingText: t.inviteToMove.reasonRelocation.Clone(), | ||||
|                 icon: Svg.relocation_svg(), | ||||
|                 changesetCommentValue: "relocated", | ||||
|                 lockBounds: false, | ||||
|                 background: undefined, | ||||
|                 startZoom: 12, | ||||
|                 minZoom: 6 | ||||
|             }) | ||||
|         } | ||||
|         if(options.enableImproveAccuracy){ | ||||
|             reasons.push({ | ||||
|                 text: t.reasons.reasonInaccurate.Clone(), | ||||
|                 invitingText: t.inviteToMove.reasonInaccurate, | ||||
|                 icon: Svg.crosshair_svg(), | ||||
|                 changesetCommentValue: "improve_accuracy", | ||||
|                 lockBounds: true, | ||||
|                 background: "photo", | ||||
|                 startZoom: 17, | ||||
|                 minZoom: 16 | ||||
|             }) | ||||
|         } | ||||
| 
 | ||||
|         const currentStep = new UIEventSource<"start" | "reason" | "pick_location" | "moved">("start") | ||||
|         const moveReason = new UIEventSource<MoveReason>(undefined) | ||||
|         const moveButton = new SubtleButton( | ||||
|             Svg.move_ui(), | ||||
|             t.inviteToMove.Clone() | ||||
|         ).onClick(() => { | ||||
|             currentStep.setData("reason") | ||||
|         }) | ||||
|         let moveButton : BaseUIElement; | ||||
|         if(reasons.length === 1){ | ||||
|             const reason = reasons[0] | ||||
|             moveReason.setData(reason) | ||||
|             moveButton = new SubtleButton( | ||||
|                 reason.icon, | ||||
|                 Translations.WT(reason.invitingText).Clone() | ||||
|             ).onClick(() => { | ||||
|                 currentStep.setData("pick_location") | ||||
|             }) | ||||
|         }else{ | ||||
|             moveButton = new SubtleButton( | ||||
|                 Svg.move_ui(), | ||||
|                 t.inviteToMove.generic.Clone() | ||||
|             ).onClick(() => { | ||||
|                 currentStep.setData("reason") | ||||
|             }) | ||||
|         } | ||||
|          | ||||
| 
 | ||||
|         const moveAgainButton = new SubtleButton( | ||||
|             Svg.move_ui(), | ||||
|  | @ -68,39 +107,7 @@ export default class MoveWizard extends Toggle { | |||
|         }) | ||||
| 
 | ||||
| 
 | ||||
|         const reasons: MoveReason[] = [] | ||||
|         if (!options.disableDefaultReasons) { | ||||
|             reasons.push({ | ||||
|                 text: t.reasonRelocation.Clone(), | ||||
|                 icon: Svg.relocation_svg(), | ||||
|                 changesetCommentValue: "relocated", | ||||
|                 lockBounds: false, | ||||
|                 background: undefined, | ||||
|                 startZoom: 12, | ||||
|                 minZoom: 6 | ||||
|             }) | ||||
|          | ||||
|             reasons.push({ | ||||
|                 text: t.reasonInaccurate.Clone(), | ||||
|                 icon: Svg.crosshair_svg(), | ||||
|                 changesetCommentValue: "improve_accuracy", | ||||
|                 lockBounds: true, | ||||
|                 background: "photo", | ||||
|                 startZoom: 17, | ||||
|                 minZoom: 16 | ||||
|             }) | ||||
|         } | ||||
|         for (const reason of options.reasons ?? []) { | ||||
|             reasons.push({ | ||||
|                 text: reason.text, | ||||
|                 icon: reason.icon, | ||||
|                 changesetCommentValue: reason.changesetCommentValue, | ||||
|                 lockBounds: reason.lockBounds ?? true, | ||||
|                 background: reason.background, | ||||
|                 startZoom: reason.startZoom ?? 15, | ||||
|                 minZoom: reason.minZoom | ||||
|             }) | ||||
|         } | ||||
|          | ||||
|         const selectReason = new Combine(reasons.map(r => new SubtleButton(r.icon, r.text).onClick(() => { | ||||
|             moveReason.setData(r) | ||||
|  | @ -124,7 +131,8 @@ export default class MoveWizard extends Toggle { | |||
| 
 | ||||
|             const locationInput = new LocationInput({ | ||||
|                 minZoom: reason.minZoom, | ||||
|                 centerLocation: loc | ||||
|                 centerLocation: loc, | ||||
|                 mapBackground: AvailableBaseLayers.SelectBestLayerAccordingTo(loc,  new UIEventSource(reason.background)) | ||||
|             }) | ||||
| 
 | ||||
|             if (reason.lockBounds) { | ||||
|  | @ -135,10 +143,14 @@ export default class MoveWizard extends Toggle { | |||
| 
 | ||||
|             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], { | ||||
|                 const loc = locationInput.GetValue().data | ||||
|                 state.changes.applyAction(new ChangeLocationAction(featureToMove.properties.id, [loc.lon, loc.lat], { | ||||
|                     reason: Translations.WT(reason.text).textFor("en"), | ||||
|                     theme: state.layoutToUse.icon | ||||
|                     theme: state.layoutToUse.id | ||||
|                 })) | ||||
|                 featureToMove.properties._lat = loc.lat | ||||
|                 featureToMove.properties._lon = loc.lon | ||||
|                 state.allElements.getEventSourceById(id).ping() | ||||
|                 currentStep.setData("moved") | ||||
|             }) | ||||
|             const zoomInFurhter = t.zoomInFurther.Clone().SetClass("alert block m-6") | ||||
|  |  | |||
							
								
								
									
										13
									
								
								Utils.ts
									
										
									
									
									
								
							
							
						
						
									
										13
									
								
								Utils.ts
									
										
									
									
									
								
							|  | @ -320,6 +320,19 @@ export class Utils { | |||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     private static _download_cache = new Map<string, {promise: Promise<any>, timestamp: number}>() | ||||
|     public static async downloadJsonCached(url: string, maxCacheTimeMs: number, headers?: any): Promise<any> { | ||||
|         const cached = Utils._download_cache.get(url) | ||||
|         if(cached !== undefined){ | ||||
|             if((new Date().getTime() - cached.timestamp) <= maxCacheTimeMs){ | ||||
|                 return cached.promise | ||||
|             } | ||||
|         } | ||||
|         const promise = Utils.downloadJson(url, headers) | ||||
|         Utils._download_cache.set(url, {promise, timestamp: new Date().getTime()}) | ||||
|         return await promise | ||||
|     } | ||||
| 
 | ||||
|     public static async downloadJson(url: string, headers?: any): Promise<any> { | ||||
|         const injected = Utils.injectedDownloads[url] | ||||
|         if (injected !== undefined) { | ||||
|  |  | |||
|  | @ -600,5 +600,18 @@ | |||
|                 "preferredBackground": "photo" | ||||
|             } | ||||
|         } | ||||
|     ] | ||||
|     ], | ||||
|     "deletion": { | ||||
|         "softDeletionTags": { | ||||
|             "and": [ | ||||
|                 "disused:amenity=bench", | ||||
|                 "amenity=" | ||||
|             ] | ||||
|         }, | ||||
|         "neededChangesets": 1 | ||||
|     }, | ||||
|     "allowMove": { | ||||
|         "enableRelocation": false, | ||||
|         "enableImproveAccuraccy": true | ||||
|     } | ||||
| } | ||||
|  | @ -255,5 +255,18 @@ | |||
|             ], | ||||
|             "multiAnswer": true | ||||
|         } | ||||
|     ] | ||||
|     ], | ||||
|     "deletion": { | ||||
|         "softDeletionTags": { | ||||
|             "and": [ | ||||
|                 "disused:amenity:={amenity}", | ||||
|                 "amenity=" | ||||
|             ] | ||||
|         }, | ||||
|         "neededChangesets": 1 | ||||
|     }, | ||||
|     "allowMove": { | ||||
|         "enableRelocation": false, | ||||
|         "enableImproveAccuraccy": true | ||||
|     } | ||||
| } | ||||
|  | @ -145,5 +145,18 @@ | |||
|             "roaming": false, | ||||
|             "id": "bike_cleaning-charge" | ||||
|         } | ||||
|     ] | ||||
|     ], | ||||
|     "deletion": { | ||||
|         "softDeletionTags": { | ||||
|             "and": [ | ||||
|                 "disused:amenity:={amenity}", | ||||
|                 "amenity=" | ||||
|             ] | ||||
|         }, | ||||
|         "neededChangesets": 1 | ||||
|     }, | ||||
|     "allowMove": { | ||||
|         "enableRelocation": false, | ||||
|         "enableImproveAccuraccy": true | ||||
|     } | ||||
| } | ||||
|  | @ -508,5 +508,18 @@ | |||
|             }, | ||||
|             "id": "Cargo bike capacity?" | ||||
|         } | ||||
|     ] | ||||
|     ], | ||||
|     "deletion": { | ||||
|         "softDeletionTags": { | ||||
|             "and": [ | ||||
|                 "disused:amenity:={amenity}", | ||||
|                 "amenity=" | ||||
|             ] | ||||
|         }, | ||||
|         "neededChangesets": 1 | ||||
|     }, | ||||
|     "allowMove": { | ||||
|         "enableRelocation": false, | ||||
|         "enableImproveAccuraccy": true | ||||
|     } | ||||
| } | ||||
|  | @ -731,5 +731,18 @@ | |||
|                 "service:bicycle:pump=no" | ||||
|             ] | ||||
|         } | ||||
|     ] | ||||
|     ], | ||||
|     "deletion": { | ||||
|         "softDeletionTags": { | ||||
|             "and": [ | ||||
|                 "disused:amenity:={amenity}", | ||||
|                 "amenity=" | ||||
|             ] | ||||
|         }, | ||||
|         "neededChangesets": 1 | ||||
|     }, | ||||
|     "allowMove": { | ||||
|         "enableRelocation": false, | ||||
|         "enableImproveAccuraccy": true | ||||
|     } | ||||
| } | ||||
|  | @ -100,5 +100,18 @@ | |||
|                 "amenity=binoculars" | ||||
|             ] | ||||
|         } | ||||
|     }, | ||||
|     "deletion": { | ||||
|         "softDeletionTags": { | ||||
|             "and": [ | ||||
|                 "disused:amenity:={amenity}", | ||||
|                 "amenity=" | ||||
|             ] | ||||
|         }, | ||||
|         "neededChangesets": 1 | ||||
|     }, | ||||
|     "allowMove": { | ||||
|         "enableRelocation": false, | ||||
|         "enableImproveAccuraccy": true | ||||
|     } | ||||
| } | ||||
|  | @ -296,5 +296,17 @@ | |||
|                 } | ||||
|             ] | ||||
|         } | ||||
|     ] | ||||
|     ], | ||||
|     "deletion": { | ||||
|         "softDeletionTags": { | ||||
|             "and": [ | ||||
|                 "disused:amenity:={amenity}", | ||||
|                 "amenity=" | ||||
|             ] | ||||
|         } | ||||
|     }, | ||||
|     "allowMove": { | ||||
|         "enableRelocation": false, | ||||
|         "enableImproveAccuraccy": true | ||||
|     } | ||||
| } | ||||
|  | @ -181,5 +181,11 @@ | |||
|                 } | ||||
|             ] | ||||
|         } | ||||
|     ] | ||||
|     ], | ||||
|     "deletion": { | ||||
|         "softDeletionTags": { | ||||
|             "and": ["amenity=","disused:amenity:={amenity}"] | ||||
|         } | ||||
|     }, | ||||
|     "allowMove": true | ||||
| } | ||||
|  | @ -3655,5 +3655,18 @@ | |||
|             ], | ||||
|             "eraseInvalidValues": true | ||||
|         } | ||||
|     ] | ||||
|     ], | ||||
|     "deletion": { | ||||
|         "softDeletionTags": { | ||||
|             "and": [ | ||||
|                 "disused:amenity:={amenity}", | ||||
|                 "amenity=" | ||||
|             ] | ||||
|         }, | ||||
|         "neededChangesets": 1 | ||||
|     }, | ||||
|     "allowMove": { | ||||
|         "enableRelocation": false, | ||||
|         "enableImproveAccuraccy": true | ||||
|     } | ||||
| } | ||||
|  | @ -539,5 +539,18 @@ | |||
|             }, | ||||
|             "id": "defibrillator-fixme" | ||||
|         } | ||||
|     ] | ||||
|     ], | ||||
|     "deletion": { | ||||
|         "softDeletionTags": { | ||||
|             "and": [ | ||||
|                 "disused:emergency:=defibrillator}", | ||||
|                 "emergency=" | ||||
|             ] | ||||
|         }, | ||||
|         "neededChangesets": 5 | ||||
|     }, | ||||
|     "allowMove": { | ||||
|         "enableRelocation": false, | ||||
|         "enableImproveAccuraccy": true | ||||
|     } | ||||
| } | ||||
|  | @ -166,5 +166,18 @@ | |||
|             }, | ||||
|             "condition": "_closest_other_drinking_water_id~*" | ||||
|         } | ||||
|     ] | ||||
|     ], | ||||
|     "deletion": { | ||||
|         "softDeletionTags": { | ||||
|             "and": [ | ||||
|                 "disused:amenity:={amenity}", | ||||
|                 "amenity=" | ||||
|             ] | ||||
|         }, | ||||
|         "neededChangesets": 1 | ||||
|     }, | ||||
|     "allowMove": { | ||||
|         "enableRelocation": false, | ||||
|         "enableImproveAccuraccy": true | ||||
|     } | ||||
| } | ||||
|  | @ -624,5 +624,11 @@ | |||
|                 } | ||||
|             ] | ||||
|         } | ||||
|     ] | ||||
|     ], | ||||
|     "deletion": { | ||||
|         "softDeletionTags": { | ||||
|             "and": ["amenity=","disused:amenity:={amenity}"] | ||||
|         } | ||||
|     }, | ||||
|     "allowMove": true | ||||
| } | ||||
|  | @ -187,5 +187,18 @@ | |||
|             }, | ||||
|             "id": "ghost_bike-start_date" | ||||
|         } | ||||
|     ] | ||||
|     ], | ||||
|     "deletion": { | ||||
|         "softDeletionTags": { | ||||
|             "and": [ | ||||
|                 "razed:memorial:=ghost_bike", | ||||
|                 "memorial=" | ||||
|             ] | ||||
|         }, | ||||
|         "neededChangesets": 50 | ||||
|     }, | ||||
|     "allowMove": { | ||||
|         "enableRelocation": false, | ||||
|         "enableImproveAccuraccy": true | ||||
|     } | ||||
| } | ||||
|  | @ -53,5 +53,20 @@ | |||
|                 "ru": "Информационный щит" | ||||
|             } | ||||
|         } | ||||
|     ] | ||||
|     ], | ||||
|     "deletion": { | ||||
|         "softDeletionTags": { | ||||
|             "and": [ | ||||
|                 "disused:tourism:=information", | ||||
|                 "tourism=" , | ||||
|                 "razed:information=board", | ||||
|                 "information=" | ||||
|             ] | ||||
|         }, | ||||
|         "neededChangesets": 1 | ||||
|     }, | ||||
|     "allowMove": { | ||||
|         "enableRelocation": false, | ||||
|         "enableImproveAccuraccy": true | ||||
|     } | ||||
| } | ||||
|  | @ -227,5 +227,18 @@ | |||
|             } | ||||
|         } | ||||
|     ], | ||||
|     "wayHandling": 2 | ||||
|     "wayHandling": 2, | ||||
|     "deletion": { | ||||
|         "softDeletionTags": { | ||||
|             "and": [ | ||||
|                 "razed:tourism:=information", | ||||
|                 "tourism=" | ||||
|             ] | ||||
|         }, | ||||
|         "neededChangesets": 1 | ||||
|     }, | ||||
|     "allowMove": { | ||||
|         "enableRelocation": false, | ||||
|         "enableImproveAccuraccy": true | ||||
|     } | ||||
| } | ||||
|  | @ -180,5 +180,9 @@ | |||
|             ], | ||||
|             "eraseInvalidValues": true | ||||
|         } | ||||
|     ] | ||||
|     ], | ||||
|     "allowMove": { | ||||
|         "enableRelocation": false, | ||||
|         "enableImproveAccuraccy": true | ||||
|     } | ||||
| } | ||||
|  | @ -81,5 +81,18 @@ | |||
|                 "nl": "Voeg hier een parking voor auto's toe" | ||||
|             } | ||||
|         } | ||||
|     ] | ||||
|     ], | ||||
|     "deletion": { | ||||
|         "softDeletionTags": { | ||||
|             "and": [ | ||||
|                 "disused:amenity:={amenity}", | ||||
|                 "amenity=" | ||||
|             ] | ||||
|         }, | ||||
|         "neededChangesets": 1 | ||||
|     }, | ||||
|     "allowMove": { | ||||
|         "enableRelocation": false, | ||||
|         "enableImproveAccuraccy": true | ||||
|     } | ||||
| } | ||||
|  | @ -101,5 +101,18 @@ | |||
|             } | ||||
|         } | ||||
|     ], | ||||
|     "wayHandling": 1 | ||||
|     "wayHandling": 1, | ||||
|     "deletion": { | ||||
|         "softDeletionTags": { | ||||
|             "and": [ | ||||
|                 "disused:amenity:={amenity}", | ||||
|                 "amenity=" | ||||
|             ] | ||||
|         }, | ||||
|         "neededChangesets": 1 | ||||
|     }, | ||||
|     "allowMove": { | ||||
|         "enableRelocation": false, | ||||
|         "enableImproveAccuraccy": true | ||||
|     } | ||||
| } | ||||
|  | @ -498,5 +498,18 @@ | |||
|                 } | ||||
|             ] | ||||
|         } | ||||
|     ] | ||||
|     ], | ||||
|     "deletion": { | ||||
|         "softDeletionTags": { | ||||
|             "and": [ | ||||
|                 "disused:amenity:={amenity}", | ||||
|                 "amenity=" | ||||
|             ] | ||||
|         }, | ||||
|         "neededChangesets": 1 | ||||
|     }, | ||||
|     "allowMove": { | ||||
|         "enableRelocation": false, | ||||
|         "enableImproveAccuraccy": true | ||||
|     } | ||||
| } | ||||
|  | @ -115,5 +115,18 @@ | |||
|                 "preferredBackground": "photo" | ||||
|             } | ||||
|         } | ||||
|     ] | ||||
|     ], | ||||
|     "deletion": { | ||||
|         "softDeletionTags": { | ||||
|             "and": [ | ||||
|                 "disused:amenity:={amenity}", | ||||
|                 "amenity=" | ||||
|             ] | ||||
|         }, | ||||
|         "neededChangesets": 1 | ||||
|     }, | ||||
|     "allowMove": { | ||||
|         "enableRelocation": false, | ||||
|         "enableImproveAccuraccy": true | ||||
|     } | ||||
| } | ||||
|  | @ -256,7 +256,6 @@ | |||
|     }, | ||||
|     "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?", | ||||
|  | @ -264,8 +263,15 @@ | |||
|         "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", | ||||
|         "reasons": { | ||||
|             "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" | ||||
|         }, | ||||
|         "inviteToMove": { | ||||
|             "generic": "Move this point", | ||||
|             "reasonInaccurate": "Improve the accuracy of this point", | ||||
|             "reasonRelocation": "Move this object to a another place because it has relocated" | ||||
|         }, | ||||
|         "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", | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ | |||
|   "homepage": "https://mapcomplete.osm.be", | ||||
|   "main": "index.js", | ||||
|   "scripts": { | ||||
|     "increase-memory": "export NODE_OPTIONS=--max_old_space_size=6182", | ||||
|     "increase-memory": "export NODE_OPTIONS=--max_old_space_size=8364", | ||||
|     "start": "npm run start:prepare && npm-run-all --parallel start:parallel:*", | ||||
|     "strt": "npm run start:prepare && npm run start:parallel:parcel", | ||||
|     "start:prepare": "ts-node scripts/generateLayerOverview.ts --no-fail && npm run increase-memory", | ||||
|  |  | |||
							
								
								
									
										11
									
								
								test.ts
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								test.ts
									
										
									
									
									
								
							|  | @ -2,6 +2,9 @@ import MoveWizard from "./UI/Popup/MoveWizard"; | |||
| import State from "./State"; | ||||
| import {AllKnownLayouts} from "./Customizations/AllKnownLayouts"; | ||||
| import MinimapImplementation from "./UI/Base/MinimapImplementation"; | ||||
| import MoveConfig from "./Models/ThemeConfig/MoveConfig"; | ||||
| import {FixedUiElement} from "./UI/Base/FixedUiElement"; | ||||
| import Combine from "./UI/Base/Combine"; | ||||
| 
 | ||||
| 
 | ||||
| State.state = new State(AllKnownLayouts.allKnownLayouts.get("bookcases")) | ||||
|  | @ -18,8 +21,14 @@ const feature = { | |||
|         ] | ||||
|     } | ||||
| } | ||||
| /* | ||||
| MinimapImplementation.initialize() | ||||
| new MoveWizard( | ||||
|     feature, | ||||
|     State.state).AttachTo("maindiv") | ||||
|     State.state, | ||||
|     new MoveConfig({ | ||||
|         enableRelocation: false, | ||||
|         enableImproveAccuracy: true | ||||
|     }, "test")).AttachTo("maindiv") | ||||
| 
 | ||||
| */ | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue