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