diff --git a/website/src/lib/assets/layers.ts b/website/src/lib/assets/layers.ts index 5d08c404..7d971d48 100644 --- a/website/src/lib/assets/layers.ts +++ b/website/src/lib/assets/layers.ts @@ -371,89 +371,199 @@ export const opacities: { [key: string]: number; } = { swisstopoSlope: 0.4, }; -export type LayerTreeType = string[] | { [key: string]: LayerTreeType; }; +export type LayerTreeType = { [key: string]: LayerTreeType | boolean; }; export type CollapsedInfoTreeType = { self: T; children: { [key: string]: CollapsedInfoTreeType; }; }; -export type CheckedInfoTreeType = { [key: string]: boolean | CheckedInfoTreeType }; +// Hierarchy containing all basemaps export const basemapTree: LayerTreeType = { basemaps: { - world: ['mapboxOutdoors', 'mapboxSatellite', 'openStreetMap', 'openTopoMap', 'openHikingMap', 'cyclOSM'], + world: { + mapboxOutdoors: true, + mapboxSatellite: true, + openStreetMap: true, + openTopoMap: true, + openHikingMap: true, + cyclOSM: true + }, countries: { - bulgaria: ['bgMountains'], - finland: ['finlandTopo'], - france: ['ignPlanV2', 'ignFrScan25', 'ignSatellite'], - new_zealand: ['linz', 'linzTopo'], - norway: ['norwayTopo'], - spain: ['ignEs'], - sweden: ['swedenTopo'], - switzerland: ['swisstopo'], - united_kingdom: ['ordnanceSurvey'], - united_states: ['usgs'], + bulgaria: { + bgMountains: true, + }, + finland: { + finlandTopo: true, + }, + france: { + ignPlanV2: true, + ignFrScan25: true, + ignSatellite: true + }, + new_zealand: { + linz: true, + linzTopo: true, + }, + norway: { + norwayTopo: true, + }, + spain: { + ignEs: true, + }, + sweden: { + swedenTopo: true, + }, + switzerland: { + swisstopo: true, + }, + united_kingdom: { + ordnanceSurvey: true, + }, + united_states: { + usgs: true, + } }, }, } +// Hierarchy containing all overlays export const overlayTree: LayerTreeType = { overlays: { world: { - cyclOSM: ['cyclOSMlite'], - waymarked_trails: ['waymarkedTrailsHiking', 'waymarkedTrailsCycling', 'waymarkedTrailsMTB', 'waymarkedTrailsSkating', 'waymarkedTrailsHorseRiding', 'waymarkedTrailsWinter'] + cyclOSM: { + cyclOSMlite: true, + }, + waymarked_trails: { + waymarkedTrailsHiking: true, + waymarkedTrailsCycling: true, + waymarkedTrailsMTB: true, + waymarkedTrailsSkating: true, + waymarkedTrailsHorseRiding: true, + waymarkedTrailsWinter: true, + } }, countries: { - france: ['ignFrCadastre', 'ignSlope'], - switzerland: ['swisstopoSlope', 'swisstopoCycling', 'swisstopoMountainBike'], + france: { + ignFrCadastre: true, + ignSlope: true, + }, + switzerland: { + swisstopoSlope: true, + swisstopoCycling: true, + swisstopoMountainBike: true, + } }, }, } -export const layerKeys: { [key: string]: string[]; } = { - mapboxOutdoors: ['basemaps', 'world'], - mapboxSatellite: ['basemaps', 'world'], - openStreetMap: ['basemaps', 'world'], - openTopoMap: ['basemaps', 'world'], - openHikingMap: ['basemaps', 'world'], - cyclOSM: ['basemaps', 'world'], - cyclOSMlite: ['overlays', 'world', 'cyclOSM'], - waymarkedTrailsHiking: ['overlays', 'world', 'waymarked_trails'], - waymarkedTrailsCycling: ['overlays', 'world', 'waymarked_trails'], - waymarkedTrailsMTB: ['overlays', 'world', 'waymarked_trails'], - waymarkedTrailsSkating: ['overlays', 'world', 'waymarked_trails'], - waymarkedTrailsHorseRiding: ['overlays', 'world', 'waymarked_trails'], - waymarkedTrailsWinter: ['overlays', 'world', 'waymarked_trails'], - bgMountains: ['basemaps', 'countries', 'bulgaria'], - finlandTopo: ['basemaps', 'countries', 'finland'], - ignPlanV2: ['basemaps', 'countries', 'france'], - ignFrScan25: ['basemaps', 'countries', 'france'], - ignSatellite: ['basemaps', 'countries', 'france'], - ignFrCadastre: ['overlays', 'countries', 'france'], - ignSlope: ['overlays', 'countries', 'france'], - linz: ['basemaps', 'countries', 'new_zealand'], - linzTopo: ['basemaps', 'countries', 'new_zealand'], - norwayTopo: ['basemaps', 'countries', 'norway'], - swisstopo: ['basemaps', 'countries', 'switzerland'], - swisstopoSlope: ['overlays', 'countries', 'switzerland'], - swisstopoCycling: ['overlays', 'countries', 'switzerland'], - swisstopoMountainBike: ['overlays', 'countries', 'switzerland'], - swedenTopo: ['basemaps', 'countries', 'sweden'], - ordnanceSurvey: ['basemaps', 'countries', 'united_kingdom'], - usgs: ['basemaps', 'countries', 'united_states'], -}; - +// Default basemap used export const defaultBasemap = 'mapboxOutdoors'; +// Default overlays used (none) +export const defaultOverlays = { + overlays: { + world: { + cyclOSM: { + cyclOSMlite: false, + }, + waymarked_trails: { + waymarkedTrailsHiking: false, + waymarkedTrailsCycling: false, + waymarkedTrailsMTB: false, + waymarkedTrailsSkating: false, + waymarkedTrailsHorseRiding: false, + waymarkedTrailsWinter: false, + } + }, + countries: { + france: { + ignFrCadastre: false, + ignSlope: false, + }, + switzerland: { + swisstopoSlope: false, + swisstopoCycling: false, + swisstopoMountainBike: false, + } + }, + }, +}; + +// Default basemaps shown in the layer menu export const defaultBasemapTree: LayerTreeType = { basemaps: { - world: ['mapboxOutdoors', 'mapboxSatellite', 'openStreetMap', 'openTopoMap', 'openHikingMap', 'cyclOSM'] + world: { + mapboxOutdoors: true, + mapboxSatellite: true, + openStreetMap: true, + openTopoMap: true, + openHikingMap: true, + cyclOSM: true + }, + countries: { + bulgaria: { + bgMountains: false, + }, + finland: { + finlandTopo: false, + }, + france: { + ignPlanV2: false, + ignFrScan25: false, + ignSatellite: false + }, + new_zealand: { + linz: false, + linzTopo: false, + }, + norway: { + norwayTopo: false, + }, + spain: { + ignEs: false, + }, + sweden: { + swedenTopo: false, + }, + switzerland: { + swisstopo: false, + }, + united_kingdom: { + ordnanceSurvey: false, + }, + united_states: { + usgs: false, + } + }, } }; + +// Default overlays shown in the layer menu export const defaultOverlayTree: LayerTreeType = { overlays: { world: { - cyclOSM: ['cyclOSMlite'], - waymarked_trails: ['waymarkedTrailsHiking', 'waymarkedTrailsCycling', 'waymarkedTrailsMTB'] - } + cyclOSM: { + cyclOSMlite: true, + }, + waymarked_trails: { + waymarkedTrailsHiking: true, + waymarkedTrailsCycling: true, + waymarkedTrailsMTB: true, + waymarkedTrailsSkating: false, + waymarkedTrailsHorseRiding: false, + waymarkedTrailsWinter: false, + } + }, + countries: { + france: { + ignFrCadastre: false, + ignSlope: false, + }, + switzerland: { + swisstopoSlope: false, + swisstopoCycling: false, + swisstopoMountainBike: false, + } + }, } } \ No newline at end of file diff --git a/website/src/lib/components/Menu.svelte b/website/src/lib/components/Menu.svelte index 95e6ac2f..541ec7d1 100644 --- a/website/src/lib/components/Menu.svelte +++ b/website/src/lib/components/Menu.svelte @@ -19,6 +19,8 @@ import { resetMode, setMode } from 'mode-watcher'; import { _ } from 'svelte-i18n'; + import { anySelectedLayer } from './layer-control/utils'; + import { defaultOverlays } from '$lib/assets/layers'; let showDistanceMarkers = false; let showDirectionMarkers = false; @@ -229,10 +231,10 @@ [$currentBasemap, $previousBasemap] = [$previousBasemap, $currentBasemap]; e.preventDefault(); } else if (e.key === 'F2') { - if ($currentOverlays.length > 0) { - [$currentOverlays, $previousOverlays] = [[], $currentOverlays]; + if (anySelectedLayer($currentOverlays)) { + [$currentOverlays, $previousOverlays] = [defaultOverlays, $currentOverlays]; } else { - [$currentOverlays, $previousOverlays] = [$previousOverlays, []]; + [$currentOverlays, $previousOverlays] = [$previousOverlays, defaultOverlays]; } e.preventDefault(); } diff --git a/website/src/lib/components/layer-control/LayerControl.svelte b/website/src/lib/components/layer-control/LayerControl.svelte index 883ac73d..54a19bdb 100644 --- a/website/src/lib/components/layer-control/LayerControl.svelte +++ b/website/src/lib/components/layer-control/LayerControl.svelte @@ -12,6 +12,7 @@ import { settings } from '$lib/db'; import { map } from '$lib/stores'; import { get, writable } from 'svelte/store'; + import { getLayers } from './utils'; const { currentBasemap, @@ -30,21 +31,21 @@ $: if ($map) { // Add or remove overlay layers depending on the current overlays - // Object.keys(overlays).forEach((id) => { - // if ($currentOverlays.includes(id)) { - // if (!addOverlayLayer.hasOwnProperty(id)) { - // addOverlayLayer[id] = addOverlayLayerForId(id); - // } - // if (!$map.getLayer(id)) { - // addOverlayLayer[id](); - // $map.on('style.load', addOverlayLayer[id]); - // } - // } else if ($map.getLayer(id)) { - // $map.removeLayer(id); - // $map.off('style.load', addOverlayLayer[id]); - // } - // }); - console.log($currentOverlays); + let overlayLayers = getLayers($currentOverlays); + Object.keys(overlayLayers).forEach((id) => { + if (overlayLayers[id]) { + if (!addOverlayLayer.hasOwnProperty(id)) { + addOverlayLayer[id] = addOverlayLayerForId(id); + } + if (!$map.getLayer(id)) { + addOverlayLayer[id](); + $map.on('style.load', addOverlayLayer[id]); + } + } else if ($map.getLayer(id)) { + $map.removeLayer(id); + $map.off('style.load', addOverlayLayer[id]); + } + }); } let selectedBasemap = writable(get(currentBasemap)); @@ -60,18 +61,6 @@ selectedBasemap.set(value); }); - let selectedOverlays = writable(get(currentOverlays)); - selectedOverlays.subscribe((value) => { - // Updates coming from checkboxes - if (value != get(currentOverlays)) { - currentOverlays.set(value); - } - }); - currentOverlays.subscribe((value) => { - // Updates coming from the database, or from the user toggling overlays - selectedOverlays.set(value); - }); - let addOverlayLayer: { [key: string]: () => void } = {}; function addOverlayLayerForId(id: string) { return () => { @@ -124,7 +113,7 @@ layerTree={$selectedOverlayTree} name="overlays" multiple={true} - bind:checked={$selectedOverlays} + bind:checked={$currentOverlays} /> diff --git a/website/src/lib/components/layer-control/LayerControlSettings.svelte b/website/src/lib/components/layer-control/LayerControlSettings.svelte index 77557cf6..c254a940 100644 --- a/website/src/lib/components/layer-control/LayerControlSettings.svelte +++ b/website/src/lib/components/layer-control/LayerControlSettings.svelte @@ -9,21 +9,12 @@ import { Settings } from 'lucide-svelte'; - import { basemapTree, overlayTree, type CollapsedInfoTreeType } from '$lib/assets/layers'; + import { basemapTree, overlayTree } from '$lib/assets/layers'; import { settings } from '$lib/db'; import { _ } from 'svelte-i18n'; const { selectedBasemapTree, selectedOverlayTree } = settings; - - let checkedBasemaps: CollapsedInfoTreeType<{ [key: string]: boolean }> = { - self: {}, - children: {} - }; - let checkedOverlays: CollapsedInfoTreeType<{ [key: string]: boolean }> = { - self: {}, - children: {} - }; @@ -48,10 +39,7 @@ layerTree={basemapTree} name="basemapSettings" multiple={true} - onValueChange={(id, checked) => { - console.log('basemap', id, checked); - }} - bind:checked={checkedBasemaps} + bind:checked={$selectedBasemapTree} /> @@ -60,10 +48,7 @@ layerTree={overlayTree} name="overlaySettings" multiple={true} - onValueChange={(id, checked) => { - console.log('overlay', id, checked); - }} - bind:checked={checkedOverlays} + bind:checked={$selectedOverlayTree} /> diff --git a/website/src/lib/components/layer-control/LayerTree.svelte b/website/src/lib/components/layer-control/LayerTree.svelte index 9c38d87f..fe00f020 100644 --- a/website/src/lib/components/layer-control/LayerTree.svelte +++ b/website/src/lib/components/layer-control/LayerTree.svelte @@ -1,10 +1,6 @@
diff --git a/website/src/lib/components/layer-control/LayerTreeNode.svelte b/website/src/lib/components/layer-control/LayerTreeNode.svelte index f180ba4c..ec80089e 100644 --- a/website/src/lib/components/layer-control/LayerTreeNode.svelte +++ b/website/src/lib/components/layer-control/LayerTreeNode.svelte @@ -6,11 +6,8 @@ import { ChevronDown, ChevronUp } from 'lucide-svelte'; - import { - type CheckedInfoTreeType, - type CollapsedInfoTreeType, - type LayerTreeType - } from '$lib/assets/layers'; + import { type CollapsedInfoTreeType, type LayerTreeType } from '$lib/assets/layers'; + import { anySelectedLayer } from './utils'; import { _ } from 'svelte-i18n'; @@ -31,48 +28,40 @@ }); } - export let checked: CheckedInfoTreeType; - if (Array.isArray(node)) { - if (multiple) { - node.forEach((id) => { - if (!checked.hasOwnProperty(id)) { - checked[id] = false; - } - }); - } - } else { - Object.keys(node).forEach((id) => { - if (!checked.hasOwnProperty(id)) { + export let checked: LayerTreeType; + Object.keys(node).forEach((id) => { + if (!checked.hasOwnProperty(id)) { + if (typeof node[id] == 'boolean') { + checked[id] = false; + } else { checked[id] = {}; } - }); - } + } + }); -{#if Array.isArray(node)} -
- {#each node as id} -
- {#if multiple} - - {:else} - - {/if} - -
- {/each} -
-{:else} -
- {#each Object.keys(node) as id} +
+ {#each Object.keys(node) as id} + {#if typeof node[id] == 'boolean'} + {#if node[id]} +
+ {#if multiple} + + {:else} + + {/if} + +
+ {/if} + {:else if anySelectedLayer(node[id])}
-{/if} + {/if} + {/each} +