forked from MapComplete/MapComplete
Refactoring: add current view button
This commit is contained in:
parent
dec4296204
commit
2149fc1a1d
3 changed files with 266 additions and 256 deletions
|
@ -1,27 +1,23 @@
|
||||||
import LayoutConfig from "./ThemeConfig/LayoutConfig"
|
import LayoutConfig from "./ThemeConfig/LayoutConfig"
|
||||||
import { SpecialVisualizationState } from "../UI/SpecialVisualization"
|
import {SpecialVisualizationState} from "../UI/SpecialVisualization"
|
||||||
import { Changes } from "../Logic/Osm/Changes"
|
import {Changes} from "../Logic/Osm/Changes"
|
||||||
import { ImmutableStore, Store, UIEventSource } from "../Logic/UIEventSource"
|
import {ImmutableStore, Store, UIEventSource} from "../Logic/UIEventSource"
|
||||||
import {
|
import {FeatureSource, IndexedFeatureSource, WritableFeatureSource,} from "../Logic/FeatureSource/FeatureSource"
|
||||||
FeatureSource,
|
import {OsmConnection} from "../Logic/Osm/OsmConnection"
|
||||||
IndexedFeatureSource,
|
import {ExportableMap, MapProperties} from "./MapProperties"
|
||||||
WritableFeatureSource,
|
|
||||||
} from "../Logic/FeatureSource/FeatureSource"
|
|
||||||
import { OsmConnection } from "../Logic/Osm/OsmConnection"
|
|
||||||
import { ExportableMap, MapProperties } from "./MapProperties"
|
|
||||||
import LayerState from "../Logic/State/LayerState"
|
import LayerState from "../Logic/State/LayerState"
|
||||||
import { Feature, Point } from "geojson"
|
import {Feature, Point, Polygon} from "geojson"
|
||||||
import FullNodeDatabaseSource from "../Logic/FeatureSource/TiledFeatureSource/FullNodeDatabaseSource"
|
import FullNodeDatabaseSource from "../Logic/FeatureSource/TiledFeatureSource/FullNodeDatabaseSource"
|
||||||
import { Map as MlMap } from "maplibre-gl"
|
import {Map as MlMap} from "maplibre-gl"
|
||||||
import InitialMapPositioning from "../Logic/Actors/InitialMapPositioning"
|
import InitialMapPositioning from "../Logic/Actors/InitialMapPositioning"
|
||||||
import { MapLibreAdaptor } from "../UI/Map/MapLibreAdaptor"
|
import {MapLibreAdaptor} from "../UI/Map/MapLibreAdaptor"
|
||||||
import { GeoLocationState } from "../Logic/State/GeoLocationState"
|
import {GeoLocationState} from "../Logic/State/GeoLocationState"
|
||||||
import FeatureSwitchState from "../Logic/State/FeatureSwitchState"
|
import FeatureSwitchState from "../Logic/State/FeatureSwitchState"
|
||||||
import { QueryParameters } from "../Logic/Web/QueryParameters"
|
import {QueryParameters} from "../Logic/Web/QueryParameters"
|
||||||
import UserRelatedState from "../Logic/State/UserRelatedState"
|
import UserRelatedState from "../Logic/State/UserRelatedState"
|
||||||
import LayerConfig from "./ThemeConfig/LayerConfig"
|
import LayerConfig from "./ThemeConfig/LayerConfig"
|
||||||
import GeoLocationHandler from "../Logic/Actors/GeoLocationHandler"
|
import GeoLocationHandler from "../Logic/Actors/GeoLocationHandler"
|
||||||
import { AvailableRasterLayers, RasterLayerPolygon, RasterLayerUtils } from "./RasterLayers"
|
import {AvailableRasterLayers, RasterLayerPolygon, RasterLayerUtils} from "./RasterLayers"
|
||||||
import LayoutSource from "../Logic/FeatureSource/Sources/LayoutSource"
|
import LayoutSource from "../Logic/FeatureSource/Sources/LayoutSource"
|
||||||
import StaticFeatureSource from "../Logic/FeatureSource/Sources/StaticFeatureSource"
|
import StaticFeatureSource from "../Logic/FeatureSource/Sources/StaticFeatureSource"
|
||||||
import FeaturePropertiesStore from "../Logic/FeatureSource/Actors/FeaturePropertiesStore"
|
import FeaturePropertiesStore from "../Logic/FeatureSource/Actors/FeaturePropertiesStore"
|
||||||
|
@ -32,20 +28,20 @@ import TitleHandler from "../Logic/Actors/TitleHandler"
|
||||||
import ChangeToElementsActor from "../Logic/Actors/ChangeToElementsActor"
|
import ChangeToElementsActor from "../Logic/Actors/ChangeToElementsActor"
|
||||||
import PendingChangesUploader from "../Logic/Actors/PendingChangesUploader"
|
import PendingChangesUploader from "../Logic/Actors/PendingChangesUploader"
|
||||||
import SelectedElementTagsUpdater from "../Logic/Actors/SelectedElementTagsUpdater"
|
import SelectedElementTagsUpdater from "../Logic/Actors/SelectedElementTagsUpdater"
|
||||||
import { BBox } from "../Logic/BBox"
|
import {BBox} from "../Logic/BBox"
|
||||||
import Constants from "./Constants"
|
import Constants from "./Constants"
|
||||||
import Hotkeys from "../UI/Base/Hotkeys"
|
import Hotkeys from "../UI/Base/Hotkeys"
|
||||||
import Translations from "../UI/i18n/Translations"
|
import Translations from "../UI/i18n/Translations"
|
||||||
import { GeoIndexedStoreForLayer } from "../Logic/FeatureSource/Actors/GeoIndexedStore"
|
import {GeoIndexedStoreForLayer} from "../Logic/FeatureSource/Actors/GeoIndexedStore"
|
||||||
import { LastClickFeatureSource } from "../Logic/FeatureSource/Sources/LastClickFeatureSource"
|
import {LastClickFeatureSource} from "../Logic/FeatureSource/Sources/LastClickFeatureSource"
|
||||||
import { MenuState } from "./MenuState"
|
import {MenuState} from "./MenuState"
|
||||||
import MetaTagging from "../Logic/MetaTagging"
|
import MetaTagging from "../Logic/MetaTagging"
|
||||||
import ChangeGeometryApplicator from "../Logic/FeatureSource/Sources/ChangeGeometryApplicator"
|
import ChangeGeometryApplicator from "../Logic/FeatureSource/Sources/ChangeGeometryApplicator"
|
||||||
import { NewGeometryFromChangesFeatureSource } from "../Logic/FeatureSource/Sources/NewGeometryFromChangesFeatureSource"
|
import {NewGeometryFromChangesFeatureSource} from "../Logic/FeatureSource/Sources/NewGeometryFromChangesFeatureSource"
|
||||||
import OsmObjectDownloader from "../Logic/Osm/OsmObjectDownloader"
|
import OsmObjectDownloader from "../Logic/Osm/OsmObjectDownloader"
|
||||||
import ShowOverlayRasterLayer from "../UI/Map/ShowOverlayRasterLayer"
|
import ShowOverlayRasterLayer from "../UI/Map/ShowOverlayRasterLayer"
|
||||||
import { Utils } from "../Utils"
|
import {Utils} from "../Utils"
|
||||||
import { EliCategory } from "./RasterLayerProperties"
|
import {EliCategory} from "./RasterLayerProperties"
|
||||||
import BackgroundLayerResetter from "../Logic/Actors/BackgroundLayerResetter"
|
import BackgroundLayerResetter from "../Logic/Actors/BackgroundLayerResetter"
|
||||||
import SaveFeatureSourceToLocalStorage from "../Logic/FeatureSource/Actors/SaveFeatureSourceToLocalStorage"
|
import SaveFeatureSourceToLocalStorage from "../Logic/FeatureSource/Actors/SaveFeatureSourceToLocalStorage"
|
||||||
import Hash from "../Logic/Web/Hash"
|
import Hash from "../Logic/Web/Hash"
|
||||||
|
@ -80,6 +76,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
||||||
|
|
||||||
readonly historicalUserLocations: WritableFeatureSource<Feature<Point>>
|
readonly historicalUserLocations: WritableFeatureSource<Feature<Point>>
|
||||||
readonly indexedFeatures: IndexedFeatureSource & LayoutSource
|
readonly indexedFeatures: IndexedFeatureSource & LayoutSource
|
||||||
|
readonly currentView: FeatureSource<Feature<Polygon>>
|
||||||
readonly featuresInView: FeatureSource
|
readonly featuresInView: FeatureSource
|
||||||
readonly newFeatures: WritableFeatureSource
|
readonly newFeatures: WritableFeatureSource
|
||||||
readonly layerState: LayerState
|
readonly layerState: LayerState
|
||||||
|
@ -169,6 +166,12 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
||||||
(id) => self.layerState.filteredLayers.get(id).isDisplayed
|
(id) => self.layerState.filteredLayers.get(id).isDisplayed
|
||||||
)
|
)
|
||||||
this.indexedFeatures = layoutSource
|
this.indexedFeatures = layoutSource
|
||||||
|
const empty = []
|
||||||
|
this.currentView = new StaticFeatureSource(
|
||||||
|
this.mapProperties.bounds.map((bbox) =>
|
||||||
|
bbox === undefined ? empty : <Feature[]>[bbox.asGeoJson({ id: "current_view" })]
|
||||||
|
)
|
||||||
|
)
|
||||||
this.featuresInView = new BBoxFeatureSource(layoutSource, this.mapProperties.bounds)
|
this.featuresInView = new BBoxFeatureSource(layoutSource, this.mapProperties.bounds)
|
||||||
this.dataIsLoading = layoutSource.isLoading
|
this.dataIsLoading = layoutSource.isLoading
|
||||||
|
|
||||||
|
@ -447,11 +450,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
||||||
bbox === undefined ? empty : <Feature[]>[bbox.asGeoJson({ id: "range" })]
|
bbox === undefined ? empty : <Feature[]>[bbox.asGeoJson({ id: "range" })]
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
current_view: new StaticFeatureSource(
|
current_view: this.currentView
|
||||||
this.mapProperties.bounds.map((bbox) =>
|
|
||||||
bbox === undefined ? empty : <Feature[]>[bbox.asGeoJson({ id: "current_view" })]
|
|
||||||
)
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
if (this.layout?.lockLocation) {
|
if (this.layout?.lockLocation) {
|
||||||
const bbox = new BBox(this.layout.lockLocation)
|
const bbox = new BBox(this.layout.lockLocation)
|
||||||
|
|
|
@ -1,100 +1,109 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { UIEventSource } from "../Logic/UIEventSource";
|
import {UIEventSource} from "../Logic/UIEventSource";
|
||||||
import { Map as MlMap } from "maplibre-gl";
|
import {Map as MlMap} from "maplibre-gl";
|
||||||
import MaplibreMap from "./Map/MaplibreMap.svelte";
|
import MaplibreMap from "./Map/MaplibreMap.svelte";
|
||||||
import FeatureSwitchState from "../Logic/State/FeatureSwitchState";
|
import FeatureSwitchState from "../Logic/State/FeatureSwitchState";
|
||||||
import MapControlButton from "./Base/MapControlButton.svelte";
|
import MapControlButton from "./Base/MapControlButton.svelte";
|
||||||
import ToSvelte from "./Base/ToSvelte.svelte";
|
import ToSvelte from "./Base/ToSvelte.svelte";
|
||||||
import If from "./Base/If.svelte";
|
import If from "./Base/If.svelte";
|
||||||
import { GeolocationControl } from "./BigComponents/GeolocationControl";
|
import {GeolocationControl} from "./BigComponents/GeolocationControl";
|
||||||
import type { Feature } from "geojson";
|
import type {Feature} from "geojson";
|
||||||
import SelectedElementView from "./BigComponents/SelectedElementView.svelte";
|
import SelectedElementView from "./BigComponents/SelectedElementView.svelte";
|
||||||
import LayerConfig from "../Models/ThemeConfig/LayerConfig";
|
import LayerConfig from "../Models/ThemeConfig/LayerConfig";
|
||||||
import Filterview from "./BigComponents/Filterview.svelte";
|
import Filterview from "./BigComponents/Filterview.svelte";
|
||||||
import RasterLayerPicker from "./Map/RasterLayerPicker.svelte";
|
import RasterLayerPicker from "./Map/RasterLayerPicker.svelte";
|
||||||
import ThemeViewState from "../Models/ThemeViewState";
|
import ThemeViewState from "../Models/ThemeViewState";
|
||||||
import type { MapProperties } from "../Models/MapProperties";
|
import type {MapProperties} from "../Models/MapProperties";
|
||||||
import Geosearch from "./BigComponents/Geosearch.svelte";
|
import Geosearch from "./BigComponents/Geosearch.svelte";
|
||||||
import Translations from "./i18n/Translations";
|
import Translations from "./i18n/Translations";
|
||||||
import { CogIcon, EyeIcon, MenuIcon } from "@rgossiaux/svelte-heroicons/solid";
|
import {CogIcon, EyeIcon, MenuIcon} from "@rgossiaux/svelte-heroicons/solid";
|
||||||
import Tr from "./Base/Tr.svelte";
|
import Tr from "./Base/Tr.svelte";
|
||||||
import CommunityIndexView from "./BigComponents/CommunityIndexView.svelte";
|
import CommunityIndexView from "./BigComponents/CommunityIndexView.svelte";
|
||||||
import FloatOver from "./Base/FloatOver.svelte";
|
import FloatOver from "./Base/FloatOver.svelte";
|
||||||
import PrivacyPolicy from "./BigComponents/PrivacyPolicy";
|
import PrivacyPolicy from "./BigComponents/PrivacyPolicy";
|
||||||
import Constants from "../Models/Constants";
|
import Constants from "../Models/Constants";
|
||||||
import TabbedGroup from "./Base/TabbedGroup.svelte";
|
import TabbedGroup from "./Base/TabbedGroup.svelte";
|
||||||
import UserRelatedState from "../Logic/State/UserRelatedState";
|
import UserRelatedState from "../Logic/State/UserRelatedState";
|
||||||
import LoginToggle from "./Base/LoginToggle.svelte";
|
import LoginToggle from "./Base/LoginToggle.svelte";
|
||||||
import LoginButton from "./Base/LoginButton.svelte";
|
import LoginButton from "./Base/LoginButton.svelte";
|
||||||
import CopyrightPanel from "./BigComponents/CopyrightPanel";
|
import CopyrightPanel from "./BigComponents/CopyrightPanel";
|
||||||
import { DownloadPanel } from "./BigComponents/DownloadPanel";
|
import {DownloadPanel} from "./BigComponents/DownloadPanel";
|
||||||
import ModalRight from "./Base/ModalRight.svelte";
|
import ModalRight from "./Base/ModalRight.svelte";
|
||||||
import { Utils } from "../Utils";
|
import {Utils} from "../Utils";
|
||||||
import Hotkeys from "./Base/Hotkeys";
|
import Hotkeys from "./Base/Hotkeys";
|
||||||
import { VariableUiElement } from "./Base/VariableUIElement";
|
import {VariableUiElement} from "./Base/VariableUIElement";
|
||||||
import SvelteUIElement from "./Base/SvelteUIElement";
|
import SvelteUIElement from "./Base/SvelteUIElement";
|
||||||
import OverlayToggle from "./BigComponents/OverlayToggle.svelte";
|
import OverlayToggle from "./BigComponents/OverlayToggle.svelte";
|
||||||
import LevelSelector from "./BigComponents/LevelSelector.svelte";
|
import LevelSelector from "./BigComponents/LevelSelector.svelte";
|
||||||
|
import Svg from "../Svg";
|
||||||
|
|
||||||
export let state: ThemeViewState;
|
export let state: ThemeViewState;
|
||||||
let layout = state.layout;
|
let layout = state.layout;
|
||||||
|
|
||||||
let maplibremap: UIEventSource<MlMap> = state.map;
|
let maplibremap: UIEventSource<MlMap> = state.map;
|
||||||
let selectedElement: UIEventSource<Feature> = state.selectedElement;
|
let selectedElement: UIEventSource<Feature> = state.selectedElement;
|
||||||
let selectedLayer: UIEventSource<LayerConfig> = state.selectedLayer;
|
let selectedLayer: UIEventSource<LayerConfig> = state.selectedLayer;
|
||||||
|
|
||||||
const selectedViewElement = selectedElement.map(selectedElement => {
|
const selectedViewElement = selectedElement.map(selectedElement => {
|
||||||
// Svelte doesn't properly reload some of the legacy UI-elements
|
// Svelte doesn't properly reload some of the legacy UI-elements
|
||||||
// As such, we _reconstruct_ the selectedElementView every time a new feature is selected
|
// As such, we _reconstruct_ the selectedElementView every time a new feature is selected
|
||||||
// This is a bit wasteful, but until everything is a svelte-component, this should do the trick
|
// This is a bit wasteful, but until everything is a svelte-component, this should do the trick
|
||||||
const layer = selectedLayer.data;
|
const layer = selectedLayer.data;
|
||||||
if (selectedElement === undefined || layer === undefined) {
|
if (selectedElement === undefined || layer === undefined) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tags = state.featureProperties.getStore(selectedElement.properties.id);
|
const tags = state.featureProperties.getStore(selectedElement.properties.id);
|
||||||
return new SvelteUIElement(SelectedElementView, { state, layer, selectedElement, tags });
|
return new SvelteUIElement(SelectedElementView, {state, layer, selectedElement, tags});
|
||||||
}, [selectedLayer]);
|
}, [selectedLayer]);
|
||||||
|
|
||||||
|
|
||||||
let mapproperties: MapProperties = state.mapProperties;
|
let mapproperties: MapProperties = state.mapProperties;
|
||||||
let featureSwitches: FeatureSwitchState = state.featureSwitches;
|
let featureSwitches: FeatureSwitchState = state.featureSwitches;
|
||||||
let availableLayers = state.availableLayers;
|
let availableLayers = state.availableLayers;
|
||||||
let userdetails = state.osmConnection.userDetails;
|
let userdetails = state.osmConnection.userDetails;
|
||||||
|
let currentViewLayer = layout.layers.find(l => l.id === "current_view")
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<div class="h-screen w-screen absolute top-0 left-0 overflow-hidden">
|
<div class="h-screen w-screen absolute top-0 left-0 overflow-hidden">
|
||||||
<MaplibreMap map={maplibremap}></MaplibreMap>
|
<MaplibreMap map={maplibremap}></MaplibreMap>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="absolute top-0 left-0 w-full ">
|
<div class="absolute top-0 left-0 w-full ">
|
||||||
<!-- Top components -->
|
<!-- Top components -->
|
||||||
<If condition={state.featureSwitches.featureSwitchSearch}>
|
<If condition={state.featureSwitches.featureSwitchSearch}>
|
||||||
<div class="max-[480px]:w-full float-right mt-1 px-1 sm:m-2">
|
<div class="max-[480px]:w-full float-right mt-1 px-1 sm:m-2">
|
||||||
<Geosearch bounds={state.mapProperties.bounds} perLayer={state.perLayer} {selectedElement}
|
<Geosearch bounds={state.mapProperties.bounds} perLayer={state.perLayer} {selectedElement}
|
||||||
{selectedLayer}></Geosearch>
|
{selectedLayer}></Geosearch>
|
||||||
</div>
|
</div>
|
||||||
</If>
|
</If>
|
||||||
<div class="float-left m-1 sm:mt-2">
|
<div class="float-left m-1 sm:mt-2">
|
||||||
<MapControlButton on:click={() => state.guistate.themeIsOpened.setData(true)}>
|
<MapControlButton on:click={() => state.guistate.themeIsOpened.setData(true)}>
|
||||||
<div class="flex m-0.5 mx-1 sm:mx-1 md:mx-2 items-center cursor-pointer max-[480px]:w-full">
|
<div class="flex m-0.5 mx-1 sm:mx-1 md:mx-2 items-center cursor-pointer max-[480px]:w-full">
|
||||||
<img class="w-6 h-6 md:w-8 md:h-8 block mr-0.5 sm:mr-1 md:mr-2" src={layout.icon}>
|
<img class="w-6 h-6 md:w-8 md:h-8 block mr-0.5 sm:mr-1 md:mr-2" src={layout.icon}>
|
||||||
<b class="mr-1">
|
<b class="mr-1">
|
||||||
<Tr t={layout.title}></Tr>
|
<Tr t={layout.title}></Tr>
|
||||||
</b>
|
</b>
|
||||||
</div>
|
</div>
|
||||||
</MapControlButton>
|
</MapControlButton>
|
||||||
<MapControlButton on:click={() =>state.guistate.menuIsOpened.setData(true)}>
|
<MapControlButton on:click={() =>state.guistate.menuIsOpened.setData(true)}>
|
||||||
<MenuIcon class="w-8 h-8 cursor-pointer"></MenuIcon>
|
<MenuIcon class="w-8 h-8 cursor-pointer"></MenuIcon>
|
||||||
</MapControlButton>
|
</MapControlButton>
|
||||||
<If condition={state.featureSwitchIsTesting}>
|
{#if currentViewLayer?.tagRenderings}
|
||||||
|
<MapControlButton
|
||||||
|
on:click={() => {selectedLayer.setData(currentViewLayer); selectedElement.setData(state.currentView.features?.data?.[0])}}>
|
||||||
|
<ToSvelte
|
||||||
|
construct={() =>(currentViewLayer.defaultIcon() ?? Svg.checkbox_empty_svg()).SetClass("w-8 h-8 cursor-pointer")}/>
|
||||||
|
</MapControlButton>
|
||||||
|
{/if}
|
||||||
|
<If condition={state.featureSwitchIsTesting}>
|
||||||
<span class="alert">
|
<span class="alert">
|
||||||
Testmode
|
Testmode
|
||||||
</span>
|
</span>
|
||||||
</If>
|
</If>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="absolute bottom-0 left-0 mb-4 ml-4">
|
<div class="absolute bottom-0 left-0 mb-4 ml-4">
|
||||||
|
@ -102,191 +111,192 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="absolute bottom-0 right-0 mb-4 mr-4 flex flex-col items-end">
|
<div class="absolute bottom-0 right-0 mb-4 mr-4 flex flex-col items-end">
|
||||||
<If condition={state.floors.map(f => f.length > 1)}>
|
<If condition={state.floors.map(f => f.length > 1)}>
|
||||||
<div class="mr-0.5">
|
<div class="mr-0.5">
|
||||||
<LevelSelector floors={state.floors} layerState={state.layerState} zoom={state.mapProperties.zoom}/>
|
<LevelSelector floors={state.floors} layerState={state.layerState} zoom={state.mapProperties.zoom}/>
|
||||||
</div>
|
</div>
|
||||||
</If>
|
</If>
|
||||||
<MapControlButton on:click={() => mapproperties.zoom.update(z => z+1)}>
|
<MapControlButton on:click={() => mapproperties.zoom.update(z => z+1)}>
|
||||||
<img src="./assets/svg/plus.svg" class="w-8 h-8"/>
|
<img class="w-8 h-8" src="./assets/svg/plus.svg"/>
|
||||||
</MapControlButton>
|
|
||||||
<MapControlButton on:click={() => mapproperties.zoom.update(z => z-1)}>
|
|
||||||
<img src="./assets/svg/min.svg" class="w-8 h-8"/>
|
|
||||||
</MapControlButton>
|
|
||||||
<If condition={featureSwitches.featureSwitchGeolocation}>
|
|
||||||
<MapControlButton>
|
|
||||||
<ToSvelte
|
|
||||||
construct={new GeolocationControl(state.geolocation, mapproperties).SetClass("block w-8 h-8")}></ToSvelte>
|
|
||||||
</MapControlButton>
|
</MapControlButton>
|
||||||
</If>
|
<MapControlButton on:click={() => mapproperties.zoom.update(z => z-1)}>
|
||||||
|
<img class="w-8 h-8" src="./assets/svg/min.svg"/>
|
||||||
|
</MapControlButton>
|
||||||
|
<If condition={featureSwitches.featureSwitchGeolocation}>
|
||||||
|
<MapControlButton>
|
||||||
|
<ToSvelte
|
||||||
|
construct={new GeolocationControl(state.geolocation, mapproperties).SetClass("block w-8 h-8")}></ToSvelte>
|
||||||
|
</MapControlButton>
|
||||||
|
</If>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<If condition={selectedViewElement.map(v => v !== undefined && selectedLayer.data !== undefined && !selectedLayer.data.popupInFloatover,[ selectedLayer] )}>
|
<If condition={selectedViewElement.map(v => v !== undefined && selectedLayer.data !== undefined && !selectedLayer.data.popupInFloatover,[ selectedLayer] )}>
|
||||||
<ModalRight on:close={() => {selectedElement.setData(undefined)}}>
|
<ModalRight on:close={() => {selectedElement.setData(undefined)}}>
|
||||||
<ToSvelte construct={new VariableUiElement(selectedViewElement)}></ToSvelte>
|
<ToSvelte construct={new VariableUiElement(selectedViewElement)}></ToSvelte>
|
||||||
</ModalRight>
|
</ModalRight>
|
||||||
</If>
|
</If>
|
||||||
|
|
||||||
<If condition={selectedViewElement.map(v => v !== undefined && selectedLayer.data !== undefined && selectedLayer.data.popupInFloatover,[ selectedLayer] )}>
|
<If condition={selectedViewElement.map(v => v !== undefined && selectedLayer.data !== undefined && selectedLayer.data.popupInFloatover,[ selectedLayer] )}>
|
||||||
<FloatOver on:close={() => {selectedElement.setData(undefined)}}>
|
<FloatOver on:close={() => {selectedElement.setData(undefined)}}>
|
||||||
<ToSvelte construct={new VariableUiElement(selectedViewElement)}></ToSvelte>
|
<ToSvelte construct={new VariableUiElement(selectedViewElement)}></ToSvelte>
|
||||||
</FloatOver>
|
</FloatOver>
|
||||||
</If>
|
</If>
|
||||||
|
|
||||||
<If condition={state.guistate.themeIsOpened}>
|
<If condition={state.guistate.themeIsOpened}>
|
||||||
<!-- Theme page -->
|
<!-- Theme page -->
|
||||||
<FloatOver on:close={() => state.guistate.themeIsOpened.setData(false)}>
|
<FloatOver on:close={() => state.guistate.themeIsOpened.setData(false)}>
|
||||||
<TabbedGroup tab={state.guistate.themeViewTabIndex}>
|
<TabbedGroup tab={state.guistate.themeViewTabIndex}>
|
||||||
<Tr slot="title0" t={layout.title} />
|
<Tr slot="title0" t={layout.title}/>
|
||||||
|
|
||||||
<div slot="content0">
|
<div slot="content0">
|
||||||
|
|
||||||
<Tr t={layout.description}></Tr>
|
<Tr t={layout.description}></Tr>
|
||||||
<Tr t={Translations.t.general.welcomeExplanation.general} />
|
<Tr t={Translations.t.general.welcomeExplanation.general}/>
|
||||||
{#if layout.layers.some((l) => l.presets?.length > 0)}
|
{#if layout.layers.some((l) => l.presets?.length > 0)}
|
||||||
<If condition={state.featureSwitches.featureSwitchAddNew}>
|
<If condition={state.featureSwitches.featureSwitchAddNew}>
|
||||||
<Tr t={Translations.t.general.welcomeExplanation.addNew} />
|
<Tr t={Translations.t.general.welcomeExplanation.addNew}/>
|
||||||
</If>
|
</If>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<!--toTheMap,
|
<!--toTheMap,
|
||||||
loginStatus.SetClass("block mt-6 pt-2 md:border-t-2 border-dotted border-gray-400"),
|
loginStatus.SetClass("block mt-6 pt-2 md:border-t-2 border-dotted border-gray-400"),
|
||||||
-->
|
-->
|
||||||
<Tr t={layout.descriptionTail}></Tr>
|
<Tr t={layout.descriptionTail}></Tr>
|
||||||
<div class="m-x-8">
|
<div class="m-x-8">
|
||||||
<button class="subtle-background rounded w-full p-4"
|
<button class="subtle-background rounded w-full p-4"
|
||||||
on:click={() => state.guistate.themeIsOpened.setData(false)}>
|
on:click={() => state.guistate.themeIsOpened.setData(false)}>
|
||||||
<Tr t={Translations.t.general.openTheMap} />
|
<Tr t={Translations.t.general.openTheMap}/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex" slot="title1">
|
<div class="flex" slot="title1">
|
||||||
<If condition={state.featureSwitches.featureSwitchFilter}>
|
<If condition={state.featureSwitches.featureSwitchFilter}>
|
||||||
<img class="w-4 h-4" src="./assets/svg/filter.svg">
|
<img class="w-4 h-4" src="./assets/svg/filter.svg">
|
||||||
<Tr t={Translations.t.general.menu.filter} />
|
<Tr t={Translations.t.general.menu.filter}/>
|
||||||
</If>
|
</If>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col" slot="content1">
|
<div class="flex flex-col" slot="content1">
|
||||||
{#each layout.layers as layer}
|
{#each layout.layers as layer}
|
||||||
<Filterview zoomlevel={state.mapProperties.zoom} filteredLayer={state.layerState.filteredLayers.get(layer.id)}
|
<Filterview zoomlevel={state.mapProperties.zoom}
|
||||||
highlightedLayer={state.guistate.highlightedLayerInFilters}></Filterview>
|
filteredLayer={state.layerState.filteredLayers.get(layer.id)}
|
||||||
{/each}
|
highlightedLayer={state.guistate.highlightedLayerInFilters}></Filterview>
|
||||||
{#each layout.tileLayerSources as tilesource}
|
{/each}
|
||||||
<OverlayToggle
|
{#each layout.tileLayerSources as tilesource}
|
||||||
layerproperties={tilesource}
|
<OverlayToggle
|
||||||
state={state.overlayLayerStates.get(tilesource.id)}
|
layerproperties={tilesource}
|
||||||
highlightedLayer={state.guistate.highlightedLayerInFilters}
|
state={state.overlayLayerStates.get(tilesource.id)}
|
||||||
zoomlevel={state.mapProperties.zoom}
|
highlightedLayer={state.guistate.highlightedLayerInFilters}
|
||||||
/>
|
zoomlevel={state.mapProperties.zoom}
|
||||||
{/each}
|
/>
|
||||||
<If condition={state.featureSwitches.featureSwitchBackgroundSelection}>
|
{/each}
|
||||||
<RasterLayerPicker {availableLayers} value={mapproperties.rasterLayer}></RasterLayerPicker>
|
<If condition={state.featureSwitches.featureSwitchBackgroundSelection}>
|
||||||
</If>
|
<RasterLayerPicker {availableLayers} value={mapproperties.rasterLayer}></RasterLayerPicker>
|
||||||
</div>
|
</If>
|
||||||
<div class="flex" slot="title2">
|
</div>
|
||||||
<If condition={state.featureSwitches.featureSwitchEnableExport}>
|
<div class="flex" slot="title2">
|
||||||
<img class="w-4 h-4" src="./assets/svg/download.svg" />
|
<If condition={state.featureSwitches.featureSwitchEnableExport}>
|
||||||
<Tr t={Translations.t.general.download.title} />
|
<img class="w-4 h-4" src="./assets/svg/download.svg"/>
|
||||||
</If>
|
<Tr t={Translations.t.general.download.title}/>
|
||||||
</div>
|
</If>
|
||||||
<div slot="content2">
|
</div>
|
||||||
<ToSvelte construct={() => new DownloadPanel(state)} />
|
<div slot="content2">
|
||||||
</div>
|
<ToSvelte construct={() => new DownloadPanel(state)}/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div slot="title3">
|
<div slot="title3">
|
||||||
<Tr t={Translations.t.general.attribution.title} />
|
<Tr t={Translations.t.general.attribution.title}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ToSvelte construct={() => new CopyrightPanel(state)} slot="content3"></ToSvelte>
|
<ToSvelte construct={() => new CopyrightPanel(state)} slot="content3"></ToSvelte>
|
||||||
|
|
||||||
|
|
||||||
</TabbedGroup>
|
</TabbedGroup>
|
||||||
</FloatOver>
|
</FloatOver>
|
||||||
</If>
|
</If>
|
||||||
|
|
||||||
|
|
||||||
<If condition={state.guistate.menuIsOpened}>
|
<If condition={state.guistate.menuIsOpened}>
|
||||||
<!-- Menu page -->
|
<!-- Menu page -->
|
||||||
<FloatOver on:close={() => state.guistate.menuIsOpened.setData(false)}>
|
<FloatOver on:close={() => state.guistate.menuIsOpened.setData(false)}>
|
||||||
<TabbedGroup tab={state.guistate.menuViewTabIndex}>
|
<TabbedGroup tab={state.guistate.menuViewTabIndex}>
|
||||||
<div class="flex" slot="title0">
|
<div class="flex" slot="title0">
|
||||||
<Tr t={Translations.t.general.menu.aboutMapComplete} />
|
<Tr t={Translations.t.general.menu.aboutMapComplete}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col" slot="content0">
|
<div class="flex flex-col" slot="content0">
|
||||||
|
|
||||||
<Tr t={Translations.t.general.aboutMapComplete.intro} />
|
<Tr t={Translations.t.general.aboutMapComplete.intro}/>
|
||||||
|
|
||||||
<a class="flex" href={Utils.HomepageLink()}>
|
<a class="flex" href={Utils.HomepageLink()}>
|
||||||
<img class="w-6 h-6" src="./assets/svg/add.svg">
|
<img class="w-6 h-6" src="./assets/svg/add.svg">
|
||||||
<Tr t={Translations.t.general.backToIndex} />
|
<Tr t={Translations.t.general.backToIndex}/>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a class="flex" href="https://github.com/pietervdvn/MapComplete/issues" target="_blank">
|
<a class="flex" href="https://github.com/pietervdvn/MapComplete/issues" target="_blank">
|
||||||
<img class="w-6 h-6" src="./assets/svg/bug.svg">
|
<img class="w-6 h-6" src="./assets/svg/bug.svg">
|
||||||
<Tr t={Translations.t.general.attribution.openIssueTracker} />
|
<Tr t={Translations.t.general.attribution.openIssueTracker}/>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
||||||
<a class="flex" href="https://en.osm.town/@MapComplete" target="_blank">
|
<a class="flex" href="https://en.osm.town/@MapComplete" target="_blank">
|
||||||
<img class="w-6 h-6" src="./assets/svg/mastodon.svg">
|
<img class="w-6 h-6" src="./assets/svg/mastodon.svg">
|
||||||
<Tr t={Translations.t.general.attribution.followOnMastodon} />
|
<Tr t={Translations.t.general.attribution.followOnMastodon}/>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a class="flex" href="https://liberapay.com/pietervdvn/" target="_blank">
|
<a class="flex" href="https://liberapay.com/pietervdvn/" target="_blank">
|
||||||
<img class="w-6 h-6" src="./assets/svg/liberapay.svg">
|
<img class="w-6 h-6" src="./assets/svg/liberapay.svg">
|
||||||
<Tr t={Translations.t.general.attribution.donate} />
|
<Tr t={Translations.t.general.attribution.donate}/>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a class="flex" href={Utils.OsmChaLinkFor(7)} target="_blank">
|
<a class="flex" href={Utils.OsmChaLinkFor(7)} target="_blank">
|
||||||
<img class="w-6 h-6" src="./assets/svg/statistics.svg">
|
<img class="w-6 h-6" src="./assets/svg/statistics.svg">
|
||||||
<Tr t={Translations.t.general.attribution.openOsmcha.Subs({theme: "MapComplete"})} />
|
<Tr t={Translations.t.general.attribution.openOsmcha.Subs({theme: "MapComplete"})}/>
|
||||||
</a>
|
</a>
|
||||||
{Constants.vNumber}
|
{Constants.vNumber}
|
||||||
<ToSvelte construct={Hotkeys.generateDocumentationDynamic}></ToSvelte>
|
<ToSvelte construct={Hotkeys.generateDocumentationDynamic}></ToSvelte>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<If condition={state.osmConnection.isLoggedIn} slot="title1">
|
<If condition={state.osmConnection.isLoggedIn} slot="title1">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<CogIcon class="w-6 h-6" />
|
<CogIcon class="w-6 h-6"/>
|
||||||
<Tr t={UserRelatedState.usersettingsConfig.title.GetRenderValue({})} />
|
<Tr t={UserRelatedState.usersettingsConfig.title.GetRenderValue({})}/>
|
||||||
</div>
|
</div>
|
||||||
</If>
|
</If>
|
||||||
|
|
||||||
<div slot="content1">
|
<div slot="content1">
|
||||||
<!-- All shown components are set by 'usersettings.json', which happily uses some special visualisations created specifically for it -->
|
<!-- All shown components are set by 'usersettings.json', which happily uses some special visualisations created specifically for it -->
|
||||||
<LoginToggle {state}>
|
<LoginToggle {state}>
|
||||||
<div slot="not-logged-in">
|
<div slot="not-logged-in">
|
||||||
<Tr class="alert" t={Translations.t.userinfo.notLoggedIn} />
|
<Tr class="alert" t={Translations.t.userinfo.notLoggedIn}/>
|
||||||
<LoginButton osmConnection={state.osmConnection}></LoginButton>
|
<LoginButton osmConnection={state.osmConnection}></LoginButton>
|
||||||
</div>
|
</div>
|
||||||
<SelectedElementView
|
<SelectedElementView
|
||||||
highlightedRendering={state.guistate.highlightedUserSetting}
|
highlightedRendering={state.guistate.highlightedUserSetting}
|
||||||
layer={UserRelatedState.usersettingsConfig} selectedElement={({
|
layer={UserRelatedState.usersettingsConfig} selectedElement={({
|
||||||
type:"Feature",properties: {}, geometry: {type:"Point", coordinates: [0,0]}
|
type:"Feature",properties: {}, geometry: {type:"Point", coordinates: [0,0]}
|
||||||
})}
|
})}
|
||||||
{state}
|
{state}
|
||||||
tags={state.userRelatedState.preferencesAsTags}
|
tags={state.userRelatedState.preferencesAsTags}
|
||||||
/>
|
/>
|
||||||
</LoginToggle>
|
</LoginToggle>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex" slot="title2">
|
<div class="flex" slot="title2">
|
||||||
<img class="w-6" src="./assets/svg/community.svg">
|
<img class="w-6" src="./assets/svg/community.svg">
|
||||||
Get in touch with others
|
Get in touch with others
|
||||||
</div>
|
</div>
|
||||||
<CommunityIndexView location={state.mapProperties.location} slot="content2"></CommunityIndexView>
|
<CommunityIndexView location={state.mapProperties.location} slot="content2"></CommunityIndexView>
|
||||||
|
|
||||||
<div class="flex" slot="title3">
|
<div class="flex" slot="title3">
|
||||||
<EyeIcon class="w-6" />
|
<EyeIcon class="w-6"/>
|
||||||
<Tr t={Translations.t.privacy.title}></Tr>
|
<Tr t={Translations.t.privacy.title}></Tr>
|
||||||
</div>
|
</div>
|
||||||
<ToSvelte construct={() => new PrivacyPolicy()} slot="content3"></ToSvelte>
|
<ToSvelte construct={() => new PrivacyPolicy()} slot="content3"></ToSvelte>
|
||||||
</TabbedGroup>
|
</TabbedGroup>
|
||||||
</FloatOver>
|
</FloatOver>
|
||||||
</If>
|
</If>
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
{
|
{
|
||||||
"id": "current_view",
|
"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.\n\nThe icon on the button is the default icon of the layer, but can be customized by detecting 'button=yes'.",
|
"description": "A meta-layer which contains one single feature, namely the bounding box 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": "special",
|
"source": "special",
|
||||||
"shownByDefault": false,
|
"shownByDefault": false,
|
||||||
"title": "Current View",
|
"title": "Current View",
|
||||||
"tagRenderings": [],
|
"tagRenderings": [],
|
||||||
|
"popupInFloatover": true,
|
||||||
"mapRendering": [
|
"mapRendering": [
|
||||||
{
|
{
|
||||||
"color": "#cccc0088"
|
"color": "#cccc0088"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue