forked from MapComplete/MapComplete
		
	Ressurect marker to 'add a new item', but only on long press
This commit is contained in:
		
							parent
							
								
									9deae9e659
								
							
						
					
					
						commit
						800a4ae849
					
				
					 12 changed files with 111 additions and 49 deletions
				
			
		|  | @ -56,6 +56,7 @@ | ||||||
|   }, |   }, | ||||||
|   "popupInFloatover": true, |   "popupInFloatover": true, | ||||||
|   "titleIcons": [], |   "titleIcons": [], | ||||||
|  |   "isShown": "mouse_button=right", | ||||||
|   "pointRendering": [ |   "pointRendering": [ | ||||||
|     { |     { | ||||||
|       "marker": [ |       "marker": [ | ||||||
|  | @ -168,6 +169,11 @@ | ||||||
|       "render": { |       "render": { | ||||||
|         "*": "{open_note()}" |         "*": "{open_note()}" | ||||||
|       } |       } | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "id": "debug", | ||||||
|  |       "metacondition": "__featureSwitchIsDebugging=true", | ||||||
|  |       "render": "{all_tags()}" | ||||||
|     } |     } | ||||||
|   ], |   ], | ||||||
|   "filter": [ |   "filter": [ | ||||||
|  |  | ||||||
|  | @ -540,7 +540,7 @@ | ||||||
|         }, |         }, | ||||||
|         { |         { | ||||||
|           "if": "mapcomplete-more_privacy=no", |           "if": "mapcomplete-more_privacy=no", | ||||||
|           "icon": "./assets/svg/eye.svg", |           "icon": "cross_bottom_right:red;./assets/svg/eye.svg", | ||||||
|           "then": { |           "then": { | ||||||
|             "en": "When making changes to OpenStreetMap, roughly indicate how far away you were from the changed objects. This helps other contributors to understand how you made the change", |             "en": "When making changes to OpenStreetMap, roughly indicate how far away you were from the changed objects. This helps other contributors to understand how you made the change", | ||||||
|             "de": "Wenn du Änderungen an OpenStreetMap vornimmst, gib grob an, wie weit du von den geänderten Objekten entfernt warst. Das hilft anderen Mitwirkenden zu verstehen, wie du die Änderung vorgenommen hast.", |             "de": "Wenn du Änderungen an OpenStreetMap vornimmst, gib grob an, wie weit du von den geänderten Objekten entfernt warst. Das hilft anderen Mitwirkenden zu verstehen, wie du die Änderung vorgenommen hast.", | ||||||
|  | @ -619,7 +619,7 @@ | ||||||
|       "mappings": [ |       "mappings": [ | ||||||
|         { |         { | ||||||
|           "if": "mapcomplete-translation-mode=false", |           "if": "mapcomplete-translation-mode=false", | ||||||
|           "icon": "./assets/layers/usersettings/translate_disabled.svg", |           "icon": "cross_bottom_right:red;./assets/svg/translate.svg", | ||||||
|           "then": { |           "then": { | ||||||
|             "en": "Don't show a button to quickly change translations", |             "en": "Don't show a button to quickly change translations", | ||||||
|             "de": "Keine Schaltfläche zum schnellen Wechseln von Übersetzungen anzeigen", |             "de": "Keine Schaltfläche zum schnellen Wechseln von Übersetzungen anzeigen", | ||||||
|  | @ -856,6 +856,7 @@ | ||||||
|         }, |         }, | ||||||
|         { |         { | ||||||
|           "if": "mapcomplete-show_debug=no", |           "if": "mapcomplete-show_debug=no", | ||||||
|  |           "icon": "cross_bottom_right:red;./assets/svg/bug.svg", | ||||||
|           "then": { |           "then": { | ||||||
|             "en": "Don't show debug info", |             "en": "Don't show debug info", | ||||||
|             "de": "Keine Debug-Informationen anzeigen", |             "de": "Keine Debug-Informationen anzeigen", | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| { | { | ||||||
|   "name": "mapcomplete", |   "name": "mapcomplete", | ||||||
|   "version": "0.43.3", |   "version": "0.44.0", | ||||||
|   "repository": "https://github.com/pietervdvn/MapComplete", |   "repository": "https://github.com/pietervdvn/MapComplete", | ||||||
|   "description": "A small website to edit OSM easily", |   "description": "A small website to edit OSM easily", | ||||||
|   "bugs": "https://github.com/pietervdvn/MapComplete/issues", |   "bugs": "https://github.com/pietervdvn/MapComplete/issues", | ||||||
|  |  | ||||||
|  | @ -1,24 +1,24 @@ | ||||||
| import LayoutConfig from "../../../Models/ThemeConfig/LayoutConfig" | import LayoutConfig from "../../../Models/ThemeConfig/LayoutConfig" | ||||||
| import { WritableFeatureSource } from "../FeatureSource" | import { ImmutableStore, Store } from "../../UIEventSource" | ||||||
| import { ImmutableStore, Store, UIEventSource } from "../../UIEventSource" |  | ||||||
| import { Feature, Point } from "geojson" | import { Feature, Point } from "geojson" | ||||||
| import { TagUtils } from "../../Tags/TagUtils" | import { TagUtils } from "../../Tags/TagUtils" | ||||||
| import BaseUIElement from "../../../UI/BaseUIElement" | import BaseUIElement from "../../../UI/BaseUIElement" | ||||||
| import { Utils } from "../../../Utils" | import { Utils } from "../../../Utils" | ||||||
| import { OsmTags } from "../../../Models/OsmFeature" | import { OsmTags } from "../../../Models/OsmFeature" | ||||||
|  | import { FeatureSource } from "../FeatureSource" | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Highly specialized feature source. |  * Highly specialized feature source. | ||||||
|  * Based on a lon/lat UIEVentSource, will generate the corresponding feature with the correct properties |  * Based on a lon/lat UIEVentSource, will generate the corresponding feature with the correct properties | ||||||
|  */ |  */ | ||||||
| export class LastClickFeatureSource { | export class LastClickFeatureSource implements FeatureSource{ | ||||||
|     public readonly renderings: string[] |     public readonly renderings: string[] | ||||||
|     private i: number = 0 |     private i: number = 0 | ||||||
|     private readonly hasPresets: boolean |     private readonly hasPresets: boolean | ||||||
|     private readonly hasNoteLayer: boolean |     private readonly hasNoteLayer: boolean | ||||||
|     public static readonly newPointElementId = "new_point_dialog" |     public static readonly newPointElementId = "new_point_dialog" | ||||||
| 
 |     public readonly features: Store<Feature[]> | ||||||
|     constructor(layout: LayoutConfig) { |     constructor(layout: LayoutConfig, clickSource: Store<{lon:number,lat:number,mode:"left"|"right"|"middle"}> ) { | ||||||
|         this.hasNoteLayer = layout.hasNoteLayer() |         this.hasNoteLayer = layout.hasNoteLayer() | ||||||
|         this.hasPresets = layout.hasPresets() |         this.hasPresets = layout.hasPresets() | ||||||
|         const allPresets: BaseUIElement[] = [] |         const allPresets: BaseUIElement[] = [] | ||||||
|  | @ -33,7 +33,7 @@ export class LastClickFeatureSource { | ||||||
|                 } |                 } | ||||||
|                 const { html } = rendering.RenderIcon(tags, { |                 const { html } = rendering.RenderIcon(tags, { | ||||||
|                     noSize: true, |                     noSize: true, | ||||||
|                     includeBadges: false, |                     includeBadges: false | ||||||
|                 }) |                 }) | ||||||
|                 allPresets.push(html) |                 allPresets.push(html) | ||||||
|             } |             } | ||||||
|  | @ -43,16 +43,21 @@ export class LastClickFeatureSource { | ||||||
|                 Utils.runningFromConsole ? "" : uiElem.ConstructElement().innerHTML |                 Utils.runningFromConsole ? "" : uiElem.ConstructElement().innerHTML | ||||||
|             ) |             ) | ||||||
|         ) |         ) | ||||||
|  | 
 | ||||||
|  |         this.features = clickSource.mapD(({lon, lat,mode}) => | ||||||
|  |             [this.createFeature(lon, lat, mode)]) | ||||||
|  | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public createFeature(lon: number, lat: number): Feature<Point, OsmTags> { |     public createFeature(lon: number, lat: number, mode?: "left" | "right" | "middle"): Feature<Point, OsmTags> { | ||||||
|         const properties: OsmTags = { |         const properties: OsmTags = { | ||||||
|             id: LastClickFeatureSource.newPointElementId, |             id: LastClickFeatureSource.newPointElementId + "_" + this.i, | ||||||
|             has_note_layer: this.hasNoteLayer ? "yes" : "no", |             has_note_layer: this.hasNoteLayer ? "yes" : "no", | ||||||
|             has_presets: this.hasPresets ? "yes" : "no", |             has_presets: this.hasPresets ? "yes" : "no", | ||||||
|             renderings: this.renderings.join(""), |             renderings: this.renderings.join(""), | ||||||
|             number_of_presets: "" + this.renderings.length, |             number_of_presets: "" + this.renderings.length, | ||||||
|             first_preset: this.renderings[0], |             first_preset: this.renderings[0], | ||||||
|  |             mouse_button: mode ?? "none" | ||||||
|         } |         } | ||||||
|         this.i++ |         this.i++ | ||||||
| 
 | 
 | ||||||
|  | @ -61,8 +66,8 @@ export class LastClickFeatureSource { | ||||||
|             properties, |             properties, | ||||||
|             geometry: { |             geometry: { | ||||||
|                 type: "Point", |                 type: "Point", | ||||||
|                 coordinates: [lon, lat], |                 coordinates: [lon, lat] | ||||||
|             }, |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -236,8 +236,9 @@ export default class LinkedDataLoader { | ||||||
|     static async fetchJsonLd( |     static async fetchJsonLd( | ||||||
|         url: string, |         url: string, | ||||||
|         options?: JsonLdLoaderOptions, |         options?: JsonLdLoaderOptions, | ||||||
|         mode: "fetch-lod" | "fetch-raw" | "proxy" |         mode?: "fetch-lod" | "fetch-raw" | "proxy" | ||||||
|     ): Promise<object> { |     ): Promise<object> { | ||||||
|  |         mode ??= "fetch-lod" | ||||||
|         if (mode === "proxy") { |         if (mode === "proxy") { | ||||||
|             url = Constants.linkedDataProxy.replace("{url}", encodeURIComponent(url)) |             url = Constants.linkedDataProxy.replace("{url}", encodeURIComponent(url)) | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -205,6 +205,7 @@ export default class PointRenderingConfig extends WithContextLoader { | ||||||
|                       marker: this.marker, |                       marker: this.marker, | ||||||
|                       rotation: this.rotation, |                       rotation: this.rotation, | ||||||
|                       tags, |                       tags, | ||||||
|  |                         emojiHeight: iconH | ||||||
|                   }).SetClass("w-full h-full") |                   }).SetClass("w-full h-full") | ||||||
|                 : undefined |                 : undefined | ||||||
|         let badges = undefined |         let badges = undefined | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ import { Store, UIEventSource } from "../Logic/UIEventSource" | ||||||
| import { | import { | ||||||
|     FeatureSource, |     FeatureSource, | ||||||
|     IndexedFeatureSource, |     IndexedFeatureSource, | ||||||
|     WritableFeatureSource, |     WritableFeatureSource | ||||||
| } from "../Logic/FeatureSource/FeatureSource" | } from "../Logic/FeatureSource/FeatureSource" | ||||||
| import { OsmConnection } from "../Logic/Osm/OsmConnection" | import { OsmConnection } from "../Logic/Osm/OsmConnection" | ||||||
| import { ExportableMap, MapProperties } from "./MapProperties" | import { ExportableMap, MapProperties } from "./MapProperties" | ||||||
|  | @ -51,7 +51,7 @@ import SaveFeatureSourceToLocalStorage from "../Logic/FeatureSource/Actors/SaveF | ||||||
| import BBoxFeatureSource from "../Logic/FeatureSource/Sources/TouchesBboxFeatureSource" | import BBoxFeatureSource from "../Logic/FeatureSource/Sources/TouchesBboxFeatureSource" | ||||||
| import ThemeViewStateHashActor from "../Logic/Web/ThemeViewStateHashActor" | import ThemeViewStateHashActor from "../Logic/Web/ThemeViewStateHashActor" | ||||||
| import NoElementsInViewDetector, { | import NoElementsInViewDetector, { | ||||||
|     FeatureViewState, |     FeatureViewState | ||||||
| } from "../Logic/Actors/NoElementsInViewDetector" | } from "../Logic/Actors/NoElementsInViewDetector" | ||||||
| import FilteredLayer from "./FilteredLayer" | import FilteredLayer from "./FilteredLayer" | ||||||
| import { PreferredRasterLayerSelector } from "../Logic/Actors/PreferredRasterLayerSelector" | import { PreferredRasterLayerSelector } from "../Logic/Actors/PreferredRasterLayerSelector" | ||||||
|  | @ -64,12 +64,15 @@ import { GeolocationControlState } from "../UI/BigComponents/GeolocationControl" | ||||||
| import Zoomcontrol from "../UI/Zoomcontrol" | import Zoomcontrol from "../UI/Zoomcontrol" | ||||||
| import { | import { | ||||||
|     SummaryTileSource, |     SummaryTileSource, | ||||||
|     SummaryTileSourceRewriter, |     SummaryTileSourceRewriter | ||||||
| } from "../Logic/FeatureSource/TiledFeatureSource/SummaryTileSource" | } from "../Logic/FeatureSource/TiledFeatureSource/SummaryTileSource" | ||||||
| import summaryLayer from "../assets/generated/layers/summary.json" | import summaryLayer from "../assets/generated/layers/summary.json" | ||||||
|  | import last_click_layerconfig from "../assets/generated/layers/last_click.json" | ||||||
|  | 
 | ||||||
| import { LayerConfigJson } from "./ThemeConfig/Json/LayerConfigJson" | import { LayerConfigJson } from "./ThemeConfig/Json/LayerConfigJson" | ||||||
| import Locale from "../UI/i18n/Locale" | import Locale from "../UI/i18n/Locale" | ||||||
| import Hash from "../Logic/Web/Hash" | import Hash from "../Logic/Web/Hash" | ||||||
|  | import { GeoOperations } from "../Logic/GeoOperations" | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * |  * | ||||||
|  | @ -173,7 +176,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | ||||||
|                 "oauth_token", |                 "oauth_token", | ||||||
|                 undefined, |                 undefined, | ||||||
|                 "Used to complete the login" |                 "Used to complete the login" | ||||||
|             ), |             ) | ||||||
|         }) |         }) | ||||||
|         this.userRelatedState = new UserRelatedState( |         this.userRelatedState = new UserRelatedState( | ||||||
|             this.osmConnection, |             this.osmConnection, | ||||||
|  | @ -248,8 +251,8 @@ export default class ThemeViewState implements SpecialVisualizationState { | ||||||
|                         bbox.asGeoJson({ |                         bbox.asGeoJson({ | ||||||
|                             zoom: this.mapProperties.zoom.data, |                             zoom: this.mapProperties.zoom.data, | ||||||
|                             ...this.mapProperties.location.data, |                             ...this.mapProperties.location.data, | ||||||
|                             id: "current_view_" + currentViewIndex, |                             id: "current_view_" + currentViewIndex | ||||||
|                         }), |                         }) | ||||||
|                     ] |                     ] | ||||||
|                 }) |                 }) | ||||||
|             ) |             ) | ||||||
|  | @ -266,7 +269,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | ||||||
|                     featurePropertiesStore: this.featureProperties, |                     featurePropertiesStore: this.featureProperties, | ||||||
|                     osmConnection: this.osmConnection, |                     osmConnection: this.osmConnection, | ||||||
|                     historicalUserLocations: this.geolocation.historicalUserLocations, |                     historicalUserLocations: this.geolocation.historicalUserLocations, | ||||||
|                     featureSwitches: this.featureSwitches, |                     featureSwitches: this.featureSwitches | ||||||
|                 }, |                 }, | ||||||
|                 layout?.isLeftRightSensitive() ?? false |                 layout?.isLeftRightSensitive() ?? false | ||||||
|             ) |             ) | ||||||
|  | @ -293,7 +296,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | ||||||
|                             "leftover features, such as", |                             "leftover features, such as", | ||||||
|                             features[0].properties |                             features[0].properties | ||||||
|                         ) |                         ) | ||||||
|                     }, |                     } | ||||||
|                 } |                 } | ||||||
|             ) |             ) | ||||||
|             this.perLayer = perLayer.perLayer |             this.perLayer = perLayer.perLayer | ||||||
|  | @ -331,7 +334,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | ||||||
|             return sorted |             return sorted | ||||||
|         }) |         }) | ||||||
| 
 | 
 | ||||||
|         this.lastClickObject = new LastClickFeatureSource(this.layout) |         this.lastClickObject = new LastClickFeatureSource(this.layout, this.mapProperties.lastClickLocation) | ||||||
| 
 | 
 | ||||||
|         this.osmObjectDownloader = new OsmObjectDownloader( |         this.osmObjectDownloader = new OsmObjectDownloader( | ||||||
|             this.osmConnection.Backend(), |             this.osmConnection.Backend(), | ||||||
|  | @ -345,7 +348,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | ||||||
|             { |             { | ||||||
|                 currentZoom: this.mapProperties.zoom, |                 currentZoom: this.mapProperties.zoom, | ||||||
|                 layerState: this.layerState, |                 layerState: this.layerState, | ||||||
|                 bounds: this.visualFeedbackViewportBounds, |                 bounds: this.visualFeedbackViewportBounds | ||||||
|             } |             } | ||||||
|         ) |         ) | ||||||
|         this.hasDataInView = new NoElementsInViewDetector(this).hasFeatureInView |         this.hasDataInView = new NoElementsInViewDetector(this).hasFeatureInView | ||||||
|  | @ -403,6 +406,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | ||||||
|         }) |         }) | ||||||
|         return toLocalStorage |         return toLocalStorage | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|     public showNormalDataOn(map: Store<MlMap>): ReadonlyMap<string, FilteringFeatureSource> { |     public showNormalDataOn(map: Store<MlMap>): ReadonlyMap<string, FilteringFeatureSource> { | ||||||
|         const filteringFeatureSource = new Map<string, FilteringFeatureSource>() |         const filteringFeatureSource = new Map<string, FilteringFeatureSource>() | ||||||
|         this.perLayer.forEach((fs, layerName) => { |         this.perLayer.forEach((fs, layerName) => { | ||||||
|  | @ -436,7 +440,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | ||||||
|                 doShowLayer, |                 doShowLayer, | ||||||
|                 metaTags: this.userRelatedState.preferencesAsTags, |                 metaTags: this.userRelatedState.preferencesAsTags, | ||||||
|                 selectedElement: this.selectedElement, |                 selectedElement: this.selectedElement, | ||||||
|                 fetchStore: (id) => this.featureProperties.getStore(id), |                 fetchStore: (id) => this.featureProperties.getStore(id) | ||||||
|             }) |             }) | ||||||
|         }) |         }) | ||||||
|         return filteringFeatureSource |         return filteringFeatureSource | ||||||
|  | @ -460,7 +464,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | ||||||
|             doShowLayer: flayerGps.isDisplayed, |             doShowLayer: flayerGps.isDisplayed, | ||||||
|             layer: flayerGps.layerDef, |             layer: flayerGps.layerDef, | ||||||
|             metaTags: this.userRelatedState.preferencesAsTags, |             metaTags: this.userRelatedState.preferencesAsTags, | ||||||
|             selectedElement: this.selectedElement, |             selectedElement: this.selectedElement | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -552,7 +556,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | ||||||
|         Hotkeys.RegisterHotkey( |         Hotkeys.RegisterHotkey( | ||||||
|             { |             { | ||||||
|                 nomod: " ", |                 nomod: " ", | ||||||
|                 onUp: true, |                 onUp: true | ||||||
|             }, |             }, | ||||||
|             docs.selectItem, |             docs.selectItem, | ||||||
|             () => { |             () => { | ||||||
|  | @ -582,7 +586,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | ||||||
|             Hotkeys.RegisterHotkey( |             Hotkeys.RegisterHotkey( | ||||||
|                 { |                 { | ||||||
|                     nomod: "" + i, |                     nomod: "" + i, | ||||||
|                     onUp: true, |                     onUp: true | ||||||
|                 }, |                 }, | ||||||
|                 doc, |                 doc, | ||||||
|                 () => this.selectClosestAtCenter(i - 1) |                 () => this.selectClosestAtCenter(i - 1) | ||||||
|  | @ -595,7 +599,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | ||||||
|             } |             } | ||||||
|             Hotkeys.RegisterHotkey( |             Hotkeys.RegisterHotkey( | ||||||
|                 { |                 { | ||||||
|                     nomod: "b", |                     nomod: "b" | ||||||
|                 }, |                 }, | ||||||
|                 docs.openLayersPanel, |                 docs.openLayersPanel, | ||||||
|                 () => { |                 () => { | ||||||
|  | @ -606,7 +610,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | ||||||
|             ) |             ) | ||||||
|             Hotkeys.RegisterHotkey( |             Hotkeys.RegisterHotkey( | ||||||
|                 { |                 { | ||||||
|                     nomod: "s", |                     nomod: "s" | ||||||
|                 }, |                 }, | ||||||
|                 Translations.t.hotkeyDocumentation.openFilterPanel, |                 Translations.t.hotkeyDocumentation.openFilterPanel, | ||||||
|                 () => { |                 () => { | ||||||
|  | @ -664,7 +668,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | ||||||
| 
 | 
 | ||||||
|         Hotkeys.RegisterHotkey( |         Hotkeys.RegisterHotkey( | ||||||
|             { |             { | ||||||
|                 shift: "T", |                 shift: "T" | ||||||
|             }, |             }, | ||||||
|             Translations.t.hotkeyDocumentation.translationMode, |             Translations.t.hotkeyDocumentation.translationMode, | ||||||
|             () => { |             () => { | ||||||
|  | @ -696,7 +700,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | ||||||
|             this.mapProperties.zoom.map((z) => Math.max(Math.floor(z), 0)), |             this.mapProperties.zoom.map((z) => Math.max(Math.floor(z), 0)), | ||||||
|             this.mapProperties, |             this.mapProperties, | ||||||
|             { |             { | ||||||
|                 isActive: this.mapProperties.zoom.map((z) => z <= maxzoom), |                 isActive: this.mapProperties.zoom.map((z) => z <= maxzoom) | ||||||
|             } |             } | ||||||
|         ) |         ) | ||||||
|         return new SummaryTileSourceRewriter(summaryTileSource, this.layerState.filteredLayers) |         return new SummaryTileSourceRewriter(summaryTileSource, this.layerState.filteredLayers) | ||||||
|  | @ -712,7 +716,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | ||||||
|          * A listing which maps the layerId onto the featureSource |          * A listing which maps the layerId onto the featureSource | ||||||
|          */ |          */ | ||||||
|         const specialLayers: Record< |         const specialLayers: Record< | ||||||
|             Exclude<AddedByDefaultTypes, "last_click"> | "current_view", |             AddedByDefaultTypes | "current_view", | ||||||
|             FeatureSource |             FeatureSource | ||||||
|         > = { |         > = { | ||||||
|             home_location: this.userRelatedState.homeLocation, |             home_location: this.userRelatedState.homeLocation, | ||||||
|  | @ -730,6 +734,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | ||||||
|             current_view: this.currentView, |             current_view: this.currentView, | ||||||
|             favourite: this.favourites, |             favourite: this.favourites, | ||||||
|             summary: this.featureSummary, |             summary: this.featureSummary, | ||||||
|  |             last_click: this.lastClickObject | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         this.closestFeatures.registerSource(specialLayers.favourite, "favourite") |         this.closestFeatures.registerSource(specialLayers.favourite, "favourite") | ||||||
|  | @ -774,7 +779,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | ||||||
|             if (features === undefined) { |             if (features === undefined) { | ||||||
|                 return |                 return | ||||||
|             } |             } | ||||||
|             if (id === "summary") { |             if (id === "summary" || id === "last_click") { | ||||||
|                 return |                 return | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  | @ -784,7 +789,7 @@ export default class ThemeViewState implements SpecialVisualizationState { | ||||||
|                 doShowLayer: flayer.isDisplayed, |                 doShowLayer: flayer.isDisplayed, | ||||||
|                 layer: flayer.layerDef, |                 layer: flayer.layerDef, | ||||||
|                 metaTags: this.userRelatedState.preferencesAsTags, |                 metaTags: this.userRelatedState.preferencesAsTags, | ||||||
|                 selectedElement: this.selectedElement, |                 selectedElement: this.selectedElement | ||||||
|             }) |             }) | ||||||
|         }) |         }) | ||||||
| 
 | 
 | ||||||
|  | @ -792,7 +797,33 @@ export default class ThemeViewState implements SpecialVisualizationState { | ||||||
|             features: specialLayers.summary, |             features: specialLayers.summary, | ||||||
|             layer: new LayerConfig(<LayerConfigJson>summaryLayer, "summaryLayer"), |             layer: new LayerConfig(<LayerConfigJson>summaryLayer, "summaryLayer"), | ||||||
|             // doShowLayer: this.mapProperties.zoom.map((z) => z < maxzoom),
 |             // doShowLayer: this.mapProperties.zoom.map((z) => z < maxzoom),
 | ||||||
|             selectedElement: this.selectedElement, |             selectedElement: this.selectedElement | ||||||
|  |         }) | ||||||
|  | 
 | ||||||
|  |         const lastClickLayerConfig = new LayerConfig(<LayerConfigJson>last_click_layerconfig, "last_click") | ||||||
|  |         const lastClickFiltered = | ||||||
|  |             lastClickLayerConfig.isShown === undefined ? specialLayers.last_click : | ||||||
|  |             specialLayers.last_click.features.mapD(fs => | ||||||
|  |             fs.filter( | ||||||
|  |                 f => { | ||||||
|  |                    const matches = lastClickLayerConfig.isShown.matchesProperties(f.properties) | ||||||
|  |                     console.log("LastClick ",f,"matches",matches) | ||||||
|  |                     return matches | ||||||
|  |                 })) | ||||||
|  |         new ShowDataLayer(this.map, { | ||||||
|  |             features: new StaticFeatureSource(lastClickFiltered), | ||||||
|  |             layer: lastClickLayerConfig, | ||||||
|  |             onClick: feature => { | ||||||
|  |                 console.log("Last click was clicked", feature) | ||||||
|  |                 if (this.mapProperties.zoom.data >= Constants.minZoomLevelToAddNewPoint) { | ||||||
|  |                     this.selectedElement.setData(feature) | ||||||
|  |                     return | ||||||
|  |                 } | ||||||
|  |                 this.map.data.flyTo({ | ||||||
|  |                     zoom: Constants.minZoomLevelToAddNewPoint, | ||||||
|  |                     center: GeoOperations.centerpointCoordinates(feature) | ||||||
|  |                 }) | ||||||
|  |             } | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -15,7 +15,7 @@ | ||||||
|   /** |   /** | ||||||
|    * Only used in case of emoji |    * Only used in case of emoji | ||||||
|    */ |    */ | ||||||
|   export let emojiHeight: number |   export let emojiHeight: number = undefined | ||||||
|   let _rotation: Store<string> = rotation |   let _rotation: Store<string> = rotation | ||||||
|     ? tags.map((tags) => rotation.GetRenderValue(tags).Subs(tags).txt) |     ? tags.map((tags) => rotation.GetRenderValue(tags).Subs(tags).txt) | ||||||
|     : new ImmutableStore("0deg") |     : new ImmutableStore("0deg") | ||||||
|  |  | ||||||
|  | @ -1,7 +1,5 @@ | ||||||
| import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource" | import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource" | ||||||
| import { Map as MLMap } from "maplibre-gl" | import maplibregl, { Map as MLMap, Map as MlMap, SourceSpecification } from "maplibre-gl" | ||||||
| import { Map as MlMap, SourceSpecification } from "maplibre-gl" |  | ||||||
| import maplibregl from "maplibre-gl" |  | ||||||
| import { RasterLayerPolygon } from "../../Models/RasterLayers" | import { RasterLayerPolygon } from "../../Models/RasterLayers" | ||||||
| import { Utils } from "../../Utils" | import { Utils } from "../../Utils" | ||||||
| import { BBox } from "../../Logic/BBox" | import { BBox } from "../../Logic/BBox" | ||||||
|  | @ -13,7 +11,6 @@ import * as htmltoimage from "html-to-image" | ||||||
| import RasterLayerHandler from "./RasterLayerHandler" | import RasterLayerHandler from "./RasterLayerHandler" | ||||||
| import Constants from "../../Models/Constants" | import Constants from "../../Models/Constants" | ||||||
| import { Protocol } from "pmtiles" | import { Protocol } from "pmtiles" | ||||||
| import { bool } from "sharp" |  | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * The 'MapLibreAdaptor' bridges 'MapLibre' with the various properties of the `MapProperties` |  * The 'MapLibreAdaptor' bridges 'MapLibre' with the various properties of the `MapProperties` | ||||||
|  | @ -42,7 +39,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap { | ||||||
|     readonly allowMoving: UIEventSource<true | boolean | undefined> |     readonly allowMoving: UIEventSource<true | boolean | undefined> | ||||||
|     readonly allowRotating: UIEventSource<true | boolean | undefined> |     readonly allowRotating: UIEventSource<true | boolean | undefined> | ||||||
|     readonly allowZooming: UIEventSource<true | boolean | undefined> |     readonly allowZooming: UIEventSource<true | boolean | undefined> | ||||||
|     readonly lastClickLocation: Store<undefined | { lon: number; lat: number }> |     readonly lastClickLocation: Store<undefined | { lon: number; lat: number, mode : "left" | "right" | "middle" }> | ||||||
|     readonly minzoom: UIEventSource<number> |     readonly minzoom: UIEventSource<number> | ||||||
|     readonly maxzoom: UIEventSource<number> |     readonly maxzoom: UIEventSource<number> | ||||||
|     readonly rotation: UIEventSource<number> |     readonly rotation: UIEventSource<number> | ||||||
|  | @ -95,20 +92,24 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap { | ||||||
|         this.rasterLayer = |         this.rasterLayer = | ||||||
|             state?.rasterLayer ?? new UIEventSource<RasterLayerPolygon | undefined>(undefined) |             state?.rasterLayer ?? new UIEventSource<RasterLayerPolygon | undefined>(undefined) | ||||||
| 
 | 
 | ||||||
|         const lastClickLocation = new UIEventSource<{ lon: number; lat: number }>(undefined) |         const lastClickLocation = new UIEventSource<{lat:number,lon:number,mode: "left" | "right" | "middle"}>(undefined) | ||||||
|         this.lastClickLocation = lastClickLocation |         this.lastClickLocation = lastClickLocation | ||||||
|         const self = this |         const self = this | ||||||
| 
 | 
 | ||||||
|         new RasterLayerHandler(this._maplibreMap, this.rasterLayer) |         new RasterLayerHandler(this._maplibreMap, this.rasterLayer) | ||||||
| 
 | 
 | ||||||
|         function handleClick(e) { |         const clickmodes = ["left" , "middle", "right"] as const | ||||||
|  |         function handleClick(e: maplibregl.MapMouseEvent, mode?: "left" | "right" | "middle") { | ||||||
|             if (e.originalEvent["consumed"]) { |             if (e.originalEvent["consumed"]) { | ||||||
|                 // Workaround, 'ShowPointLayer' sets this flag
 |                 // Workaround, 'ShowPointLayer' sets this flag
 | ||||||
|                 return |                 return | ||||||
|             } |             } | ||||||
|             const lon = e.lngLat.lng |             const lon = e.lngLat.lng | ||||||
|             const lat = e.lngLat.lat |             const lat = e.lngLat.lat | ||||||
|             lastClickLocation.setData({ lon, lat }) |             const mouseEvent: MouseEvent = e.originalEvent | ||||||
|  |             mode = mode ?? clickmodes[mouseEvent.button] | ||||||
|  | 
 | ||||||
|  |             lastClickLocation.setData({ lon, lat, mode }) | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         maplibreMap.addCallbackAndRunD((map) => { |         maplibreMap.addCallbackAndRunD((map) => { | ||||||
|  | @ -142,10 +143,19 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap { | ||||||
|                 handleClick(e) |                 handleClick(e) | ||||||
|             }) |             }) | ||||||
|             map.on("contextmenu", (e) => { |             map.on("contextmenu", (e) => { | ||||||
|                 handleClick(e) |                 // This one only works on desktop
 | ||||||
|  |                 handleClick(e, "right") | ||||||
|  |             }) | ||||||
|  | 
 | ||||||
|  |             map._container.addEventListener("contextmenu", (e) => { | ||||||
|  |                  const lngLat =  map.unproject([e.x, e.y]) | ||||||
|  |                 lastClickLocation.setData({lon: lngLat.lng, lat: lngLat.lat, mode: "right"}) | ||||||
|             }) |             }) | ||||||
|             map.on("dblclick", (e) => { |             map.on("dblclick", (e) => { | ||||||
|                 handleClick(e) |                 handleClick(e, "left") | ||||||
|  |             }) | ||||||
|  |             map.on("touchend", (e) => { | ||||||
|  |                 const touchEvent = e.originalEvent | ||||||
|             }) |             }) | ||||||
|             map.on("rotateend", (_) => { |             map.on("rotateend", (_) => { | ||||||
|                 this.updateStores() |                 this.updateStores() | ||||||
|  | @ -665,4 +675,5 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap { | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -27,6 +27,7 @@ | ||||||
| 
 | 
 | ||||||
|   let _map: Map |   let _map: Map | ||||||
|   onMount(() => { |   onMount(() => { | ||||||
|  | 
 | ||||||
|     const { lon, lat } = mapProperties?.location?.data ?? { lon: 0, lat: 0 } |     const { lon, lat } = mapProperties?.location?.data ?? { lon: 0, lat: 0 } | ||||||
| 
 | 
 | ||||||
|     const rasterLayer: RasterLayerProperties = mapProperties?.rasterLayer?.data?.properties |     const rasterLayer: RasterLayerProperties = mapProperties?.rasterLayer?.data?.properties | ||||||
|  | @ -72,8 +73,13 @@ | ||||||
|   }) |   }) | ||||||
|   onDestroy(async () => { |   onDestroy(async () => { | ||||||
|     await Utils.waitFor(250) |     await Utils.waitFor(250) | ||||||
|  |     try{ | ||||||
|  | 
 | ||||||
|     if (_map) _map.remove() |     if (_map) _map.remove() | ||||||
|     map = null |     map = null | ||||||
|  |     }catch (e) { | ||||||
|  |       console.error("Could not destroy map") | ||||||
|  |     } | ||||||
|   }) |   }) | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -122,7 +122,7 @@ class SingleBackgroundHandler { | ||||||
|             console.warn( |             console.warn( | ||||||
|                 "Layer", |                 "Layer", | ||||||
|                 addLayerBeforeId, |                 addLayerBeforeId, | ||||||
|                 "not foundhttp://127.0.0.1:1234/theme.html?layout=cyclofix&z=14.8&lat=51.05282501324558&lon=3.720591622281745&layer-range=true" |                 "not found" | ||||||
|             ) |             ) | ||||||
|             addLayerBeforeId = undefined |             addLayerBeforeId = undefined | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -118,7 +118,7 @@ | ||||||
|       </div> |       </div> | ||||||
|     {/if} |     {/if} | ||||||
|   {:else} |   {:else} | ||||||
|     <div class="h-full w-full overflow-hidden"> |     <div class="h-full w-full overflow-auto"> | ||||||
|       <TagRenderingAnswer {config} {tags} {selectedElement} {state} {layer} /> |       <TagRenderingAnswer {config} {tags} {selectedElement} {state} {layer} /> | ||||||
|     </div> |     </div> | ||||||
|   {/if} |   {/if} | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue