forked from MapComplete/MapComplete
Add current view popup
This commit is contained in:
commit
c76b0a6340
9 changed files with 116 additions and 45 deletions
|
@ -152,6 +152,11 @@ export default class FeaturePipeline {
|
|||
handlePriviligedFeatureSource(state.homeLocation)
|
||||
continue
|
||||
}
|
||||
|
||||
if (id === "current_view") {
|
||||
handlePriviligedFeatureSource(state.currentView)
|
||||
continue
|
||||
}
|
||||
|
||||
const localTileSaver = new SaveTileToLocalStorageActor(filteredLayer)
|
||||
this.localStorageSavers.set(filteredLayer.layerDef.id, localTileSaver)
|
||||
|
|
|
@ -45,7 +45,10 @@ export default class MapState extends UserRelatedState {
|
|||
lon: number;
|
||||
}> = new UIEventSource<{ lat: number; lon: number }>(undefined);
|
||||
|
||||
public currentView: FeatureSourceForLayer
|
||||
/**
|
||||
* The bounds of the current map view
|
||||
*/
|
||||
public currentView: FeatureSourceForLayer & Tiled;
|
||||
/**
|
||||
* The location as delivered by the GPS
|
||||
*/
|
||||
|
@ -174,30 +177,43 @@ export default class MapState extends UserRelatedState {
|
|||
}
|
||||
|
||||
private initCurrentView(){
|
||||
let currentViewLayer: FilteredLayer = this.filteredLayers.data.filter(l => l.layerDef.id === "current_view")[0]
|
||||
|
||||
if(currentViewLayer === undefined){
|
||||
// This layer is not needed by the theme and thus unloaded
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
let i = 0
|
||||
const features : UIEventSource<{ feature: any, freshness: Date }[]>= this.currentBounds.map(bounds => {
|
||||
if(bounds === undefined){
|
||||
return []
|
||||
}
|
||||
i++
|
||||
const feature = {
|
||||
freshness: new Date(),
|
||||
feature: {
|
||||
type: "Polygon",
|
||||
type: "Feature",
|
||||
properties:{
|
||||
id:"current_view"
|
||||
id:"current_view-"+i,
|
||||
"current_view":"yes"
|
||||
},
|
||||
geometry:{
|
||||
type:"Polygon",
|
||||
coordinates:[
|
||||
coordinates:[[
|
||||
[bounds.maxLon, bounds.maxLat],
|
||||
[bounds.minLon, bounds.maxLat],
|
||||
[bounds.minLon, bounds.minLat],
|
||||
[bounds.maxLon, bounds.minLat],
|
||||
[bounds.maxLon, bounds.maxLat],
|
||||
]
|
||||
]]
|
||||
}
|
||||
}
|
||||
}
|
||||
return [feature]
|
||||
})
|
||||
let currentViewLayer: FilteredLayer = this.filteredLayers.data.filter(l => l.layerDef.id === "current_view")[0]
|
||||
|
||||
|
||||
this.currentView = new SimpleFeatureSource(currentViewLayer,0,features)
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import {Utils} from "../Utils";
|
|||
|
||||
export default class Constants {
|
||||
|
||||
public static vNumber = "0.13.0-alpha-5";
|
||||
public static vNumber = "0.13.0-alpha-6";
|
||||
public static ImgurApiKey = '7070e7167f0a25a'
|
||||
public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85"
|
||||
|
||||
|
|
|
@ -15,10 +15,17 @@ import FilteredLayer from "../../Models/FilteredLayer";
|
|||
import BaseLayer from "../../Models/BaseLayer";
|
||||
import {OsmConnection} from "../../Logic/Osm/OsmConnection";
|
||||
import BackgroundMapSwitch from "./BackgroundMapSwitch";
|
||||
import {FeatureSourceForLayer} from "../../Logic/FeatureSource/FeatureSource";
|
||||
import Lazy from "../Base/Lazy";
|
||||
import {VariableUiElement} from "../Base/VariableUIElement";
|
||||
import FeatureInfoBox from "../Popup/FeatureInfoBox";
|
||||
import {ElementStorage} from "../../Logic/ElementStorage";
|
||||
|
||||
export default class LeftControls extends Combine {
|
||||
|
||||
constructor(state: {
|
||||
allElements: ElementStorage;
|
||||
currentView: FeatureSourceForLayer;
|
||||
featureSwitchBackgroundSelection: UIEventSource<boolean>;
|
||||
layoutToUse: LayoutConfig,
|
||||
featurePipeline: FeaturePipeline,
|
||||
|
@ -33,12 +40,56 @@ export default class LeftControls extends Combine {
|
|||
osmConnection: OsmConnection
|
||||
},
|
||||
guiState: {
|
||||
currentViewControlIsOpened: UIEventSource<boolean>;
|
||||
downloadControlIsOpened: UIEventSource<boolean>,
|
||||
filterViewIsOpened: UIEventSource<boolean>,
|
||||
copyrightViewIsOpened: UIEventSource<boolean>
|
||||
}) {
|
||||
|
||||
|
||||
const currentViewFL = state.currentView?.layer
|
||||
const currentViewAction = new Toggle(
|
||||
new Lazy(() => {
|
||||
const feature : UIEventSource<any> = state.currentView.features.map(ffs => ffs[0]?.feature)
|
||||
const icon = new VariableUiElement(feature.map(feature => {
|
||||
const defaultIcon = Svg.checkbox_empty_svg()
|
||||
if (feature === undefined) {
|
||||
return defaultIcon;
|
||||
}
|
||||
const tags = {...feature.properties, button: "yes"}
|
||||
const elem = currentViewFL.layerDef.mapRendering[0]?.GenerateLeafletStyle(tags, false, {
|
||||
noSize: true
|
||||
})?.html
|
||||
if(elem === undefined){
|
||||
return defaultIcon
|
||||
}
|
||||
return elem
|
||||
}))
|
||||
|
||||
const featureBox = new VariableUiElement(feature.map(feature => {
|
||||
if(feature === undefined){return undefined}
|
||||
return new Lazy(() => {
|
||||
const tagsSource= state.allElements.getEventSourceById(feature.properties.id)
|
||||
return new FeatureInfoBox(tagsSource, currentViewFL.layerDef, "currentview", guiState.currentViewControlIsOpened)
|
||||
})
|
||||
}))
|
||||
|
||||
|
||||
return new Toggle(
|
||||
featureBox,
|
||||
new MapControlButton(icon),
|
||||
guiState.currentViewControlIsOpened
|
||||
)
|
||||
|
||||
}).SetClass("inline-block w-full").onClick(() => {
|
||||
guiState.currentViewControlIsOpened.setData(true)
|
||||
}),
|
||||
|
||||
|
||||
undefined,
|
||||
new UIEventSource<boolean>(currentViewFL !== undefined && currentViewFL?.layerDef?.tagRenderings !== null)
|
||||
)
|
||||
|
||||
const toggledDownload = new Toggle(
|
||||
new AllDownloads(
|
||||
guiState.downloadControlIsOpened
|
||||
|
@ -75,16 +126,18 @@ export default class LeftControls extends Combine {
|
|||
undefined,
|
||||
state.featureSwitchFilter
|
||||
);
|
||||
|
||||
|
||||
const mapSwitch = new Toggle(
|
||||
new BackgroundMapSwitch(state, state.backgroundLayer),
|
||||
undefined,
|
||||
state.featureSwitchBackgroundSelection
|
||||
)
|
||||
|
||||
super([filterButton,
|
||||
super([
|
||||
currentViewAction,
|
||||
filterButton,
|
||||
downloadButtonn,
|
||||
mapSwitch
|
||||
mapSwitch
|
||||
])
|
||||
|
||||
this.SetClass("flex flex-col")
|
||||
|
|
|
@ -9,6 +9,7 @@ export class DefaultGuiState {
|
|||
public readonly downloadControlIsOpened: UIEventSource<boolean>;
|
||||
public readonly filterViewIsOpened: UIEventSource<boolean>;
|
||||
public readonly copyrightViewIsOpened: UIEventSource<boolean>;
|
||||
public readonly currentViewControlIsOpened: UIEventSource<boolean>;
|
||||
public readonly welcomeMessageOpenedTab: UIEventSource<number>
|
||||
public readonly allFullScreenStates: UIEventSource<boolean>[] = []
|
||||
|
||||
|
@ -40,6 +41,11 @@ export class DefaultGuiState {
|
|||
"false",
|
||||
"Whether or not the copyright view is shown"
|
||||
)
|
||||
this.currentViewControlIsOpened = QueryParameters.GetBooleanQueryParameter(
|
||||
"currentview-toggle",
|
||||
"false",
|
||||
"Whether or not the current view box is shown"
|
||||
)
|
||||
if (Hash.hash.data === "download") {
|
||||
this.downloadControlIsOpened.setData(true)
|
||||
}
|
||||
|
@ -48,12 +54,14 @@ export class DefaultGuiState {
|
|||
}
|
||||
if (Hash.hash.data === "copyright") {
|
||||
this.copyrightViewIsOpened.setData(true)
|
||||
}if (Hash.hash.data === "currentview") {
|
||||
this.currentViewControlIsOpened.setData(true)
|
||||
}
|
||||
if (Hash.hash.data === "" || Hash.hash.data === undefined || Hash.hash.data === "welcome") {
|
||||
this.welcomeMessageIsOpened.setData(true)
|
||||
}
|
||||
|
||||
this.allFullScreenStates.push(this.downloadControlIsOpened, this.filterViewIsOpened, this.copyrightViewIsOpened, this.welcomeMessageIsOpened)
|
||||
this.allFullScreenStates.push(this.downloadControlIsOpened, this.filterViewIsOpened, this.copyrightViewIsOpened, this.welcomeMessageIsOpened, this.currentViewControlIsOpened)
|
||||
|
||||
for (let i = 0; i < this.allFullScreenStates.length; i++) {
|
||||
const fullScreenState = this.allFullScreenStates[i];
|
||||
|
|
|
@ -25,10 +25,13 @@ export default class FeatureInfoBox extends ScrollableFullScreen {
|
|||
public constructor(
|
||||
tags: UIEventSource<any>,
|
||||
layerConfig: LayerConfig,
|
||||
hashToShow?: string,
|
||||
isShown?: UIEventSource<boolean>
|
||||
) {
|
||||
super(() => FeatureInfoBox.GenerateTitleBar(tags, layerConfig),
|
||||
() => FeatureInfoBox.GenerateContent(tags, layerConfig),
|
||||
tags.data.id);
|
||||
hashToShow ?? tags.data.id,
|
||||
isShown);
|
||||
|
||||
if (layerConfig === undefined) {
|
||||
throw "Undefined layerconfig";
|
||||
|
|
|
@ -180,8 +180,7 @@
|
|||
"if": {
|
||||
"and": [
|
||||
"socket:schuko~*",
|
||||
"socket:schuko!=1",
|
||||
""
|
||||
"socket:schuko!=1"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
|
@ -202,8 +201,7 @@
|
|||
"if": {
|
||||
"and": [
|
||||
"socket:typee~*",
|
||||
"socket:typee!=1",
|
||||
""
|
||||
"socket:typee!=1"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
|
@ -250,8 +248,7 @@
|
|||
"if": {
|
||||
"and": [
|
||||
"socket:chademo~*",
|
||||
"socket:chademo!=1",
|
||||
""
|
||||
"socket:chademo!=1"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
|
@ -298,8 +295,7 @@
|
|||
"if": {
|
||||
"and": [
|
||||
"socket:type1_cable~*",
|
||||
"socket:type1_cable!=1",
|
||||
""
|
||||
"socket:type1_cable!=1"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
|
@ -346,8 +342,7 @@
|
|||
"if": {
|
||||
"and": [
|
||||
"socket:type1~*",
|
||||
"socket:type1!=1",
|
||||
""
|
||||
"socket:type1!=1"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
|
@ -394,8 +389,7 @@
|
|||
"if": {
|
||||
"and": [
|
||||
"socket:type1_combo~*",
|
||||
"socket:type1_combo!=1",
|
||||
""
|
||||
"socket:type1_combo!=1"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
|
@ -442,8 +436,7 @@
|
|||
"if": {
|
||||
"and": [
|
||||
"socket:tesla_supercharger~*",
|
||||
"socket:tesla_supercharger!=1",
|
||||
""
|
||||
"socket:tesla_supercharger!=1"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
|
@ -490,8 +483,7 @@
|
|||
"if": {
|
||||
"and": [
|
||||
"socket:type2~*",
|
||||
"socket:type2!=1",
|
||||
""
|
||||
"socket:type2!=1"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
|
@ -538,8 +530,7 @@
|
|||
"if": {
|
||||
"and": [
|
||||
"socket:type2_combo~*",
|
||||
"socket:type2_combo!=1",
|
||||
""
|
||||
"socket:type2_combo!=1"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
|
@ -586,8 +577,7 @@
|
|||
"if": {
|
||||
"and": [
|
||||
"socket:type2_cable~*",
|
||||
"socket:type2_cable!=1",
|
||||
""
|
||||
"socket:type2_cable!=1"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
|
@ -634,8 +624,7 @@
|
|||
"if": {
|
||||
"and": [
|
||||
"socket:tesla_supercharger_ccs~*",
|
||||
"socket:tesla_supercharger_ccs!=1",
|
||||
""
|
||||
"socket:tesla_supercharger_ccs!=1"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
|
@ -762,8 +751,7 @@
|
|||
"if": {
|
||||
"and": [
|
||||
"socket:USB-A~*",
|
||||
"socket:USB-A!=1",
|
||||
""
|
||||
"socket:USB-A!=1"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
|
@ -806,8 +794,7 @@
|
|||
"if": {
|
||||
"and": [
|
||||
"socket:bosch_3pin~*",
|
||||
"socket:bosch_3pin!=1",
|
||||
""
|
||||
"socket:bosch_3pin!=1"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
|
@ -850,8 +837,7 @@
|
|||
"if": {
|
||||
"and": [
|
||||
"socket:bosch_5pin~*",
|
||||
"socket:bosch_5pin!=1",
|
||||
""
|
||||
"socket:bosch_5pin!=1"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
|
|
|
@ -3,7 +3,6 @@ import {Utils} from "../../../Utils";
|
|||
import {TagRenderingConfigJson} from "../../../Models/ThemeConfig/Json/TagRenderingConfigJson";
|
||||
import ScriptUtils from "../../../scripts/ScriptUtils";
|
||||
import {LayerConfigJson} from "../../../Models/ThemeConfig/Json/LayerConfigJson";
|
||||
import {TagsFilter} from "../../../Logic/Tags/TagsFilter";
|
||||
|
||||
|
||||
function colonSplit(value: string): string[] {
|
||||
|
@ -122,7 +121,7 @@ function run(file, protojson) {
|
|||
// We add a second time for any amount to trigger a visualisation; but this is not an answer option
|
||||
const no_ask_json = {
|
||||
if: {
|
||||
and:Utils.NoNull( [`${e.key}~*`, `${e.key}!=1`, ...e.extraVisualisationCondition.split(";")])
|
||||
and:Utils.NoEmpty( [`${e.key}~*`, `${e.key}!=1`, ...e.extraVisualisationCondition.split(";")])
|
||||
},
|
||||
then: txt,
|
||||
hideInAnswer: true
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
{
|
||||
"id": "current_view",
|
||||
"description": "A meta-layer which contains one single feature, namely the BBOX of the current map view. This can be used to trigger special actions. If a popup is defined for this layer, this popup will be accessible via an extra button on screen",
|
||||
"description": "A meta-layer which contains one single feature, namely the BBOX of the current map view. This can be used to trigger special actions. If a popup is defined for this layer, this popup will be accessible via an extra button on screen.\n\nThe icon on the button is the default icon of the layer, but can be customized by detecting 'button=yes'.",
|
||||
"source": {
|
||||
"osmTags": "id=currentView"
|
||||
"osmTags": "current_view=yes"
|
||||
},
|
||||
"shownByDefault": false,
|
||||
"title": "Current View",
|
||||
"tagRenderings": [],
|
||||
"mapRendering": [
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue