Adding a basic mechanism to choose overlays (not operational yet)
This commit is contained in:
parent
82e38308a4
commit
8ddbe1bdee
|
@ -5,22 +5,3 @@
|
||||||
margin-left: calc(100% - 70px) !important;
|
margin-left: calc(100% - 70px) !important;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
|
||||||
background-color: rgba(14, 116, 144, 0.7);
|
|
||||||
color: white;
|
|
||||||
clear: both;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title-text {
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.close {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.body {
|
|
||||||
padding: 20px;
|
|
||||||
background-color: rgba(255, 255, 255, 0.7);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import OSM from 'ol/source/OSM';
|
import OSM from 'ol/source/OSM';
|
||||||
import XYZ from 'ol/source/XYZ';
|
import XYZ from 'ol/source/XYZ';
|
||||||
import { Component, createSignal, For } from 'solid-js';
|
import { Component, createEffect, createSignal, For, Show } from 'solid-js';
|
||||||
import {
|
import {
|
||||||
I18nContext,
|
I18nContext,
|
||||||
createI18nContext,
|
createI18nContext,
|
||||||
|
@ -11,14 +11,19 @@ import style from './MapTileProvider.module.css';
|
||||||
import LayersIcon from '@suid/icons-material/Layers';
|
import LayersIcon from '@suid/icons-material/Layers';
|
||||||
import CloseIcon from '@suid/icons-material/Close';
|
import CloseIcon from '@suid/icons-material/Close';
|
||||||
import {
|
import {
|
||||||
Dialog,
|
|
||||||
DialogTitle,
|
|
||||||
FormControlLabel,
|
FormControlLabel,
|
||||||
IconButton,
|
IconButton,
|
||||||
Radio,
|
Radio,
|
||||||
RadioGroup,
|
RadioGroup,
|
||||||
} from '@suid/material';
|
} from '@suid/material';
|
||||||
import { useNavigate, useParams } from '@solidjs/router';
|
import { useNavigate, useParams } from '@solidjs/router';
|
||||||
|
import Dialog from '../dialog';
|
||||||
|
import Tree from '../tree';
|
||||||
|
import { createCachedSignal } from '../../workers/cached-signals';
|
||||||
|
import dispatch from '../../workers/dispatcher-main';
|
||||||
|
import getUri from '../../lib/ids';
|
||||||
|
|
||||||
|
const id = getUri('overlays', undefined);
|
||||||
|
|
||||||
interface TileProvider {
|
interface TileProvider {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -93,6 +98,91 @@ export const mapTileProviders: TileProviders = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type FeatureSubTypes = Array<string> | '*';
|
||||||
|
type FeatureTypes = Record<string, FeatureSubTypes>;
|
||||||
|
type Overlay = {
|
||||||
|
selected: boolean;
|
||||||
|
highlighted: FeatureTypes;
|
||||||
|
hidden: FeatureTypes;
|
||||||
|
};
|
||||||
|
type Overlays = Record<string, Overlay>;
|
||||||
|
|
||||||
|
const defaultOverlays: Overlays = {
|
||||||
|
none: { selected: true, highlighted: { none: [] }, hidden: {} },
|
||||||
|
hiking: {
|
||||||
|
selected: false,
|
||||||
|
highlighted: {
|
||||||
|
none: [],
|
||||||
|
},
|
||||||
|
hidden: { none: [] },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
type OverlayDefinition = Record<string, FeatureTypes>;
|
||||||
|
type OverlayDefinitions = Record<string, OverlayDefinition>;
|
||||||
|
|
||||||
|
export const overlayDefinitions: OverlayDefinitions = {
|
||||||
|
none: {},
|
||||||
|
hiking: {
|
||||||
|
none: {},
|
||||||
|
sleeping: {
|
||||||
|
tourism: '*',
|
||||||
|
},
|
||||||
|
drinking: {
|
||||||
|
amenity: ['bar', 'cafe', 'pub', 'drinking_water', 'water_point'],
|
||||||
|
},
|
||||||
|
eating: {
|
||||||
|
amenity: ['fast_food', 'pub', 'restaurant'],
|
||||||
|
shop: [
|
||||||
|
'bakery',
|
||||||
|
'butcher',
|
||||||
|
'cheese',
|
||||||
|
'chocolate',
|
||||||
|
'convenience',
|
||||||
|
'dairy',
|
||||||
|
'farm',
|
||||||
|
'greengrocer',
|
||||||
|
'health_food',
|
||||||
|
'pastry',
|
||||||
|
'seafood',
|
||||||
|
'department_store',
|
||||||
|
'supermarket',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
health: {
|
||||||
|
amenity: ['doctors', 'hospital', 'pharmacy'],
|
||||||
|
},
|
||||||
|
security: {
|
||||||
|
amenity: ['police', 'fire_station'],
|
||||||
|
},
|
||||||
|
dayToDay: {
|
||||||
|
amenity: ['waste_basket', 'waste_disposal'],
|
||||||
|
shop: ['laundry'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const getOverlays = createCachedSignal({
|
||||||
|
id,
|
||||||
|
method: 'getOverlays',
|
||||||
|
defaultOverlays,
|
||||||
|
}) as () => Overlays;
|
||||||
|
|
||||||
|
const currentOverlayKey = () =>
|
||||||
|
getOverlays()
|
||||||
|
? Object.keys(getOverlays()).filter((key) => getOverlays()[key].selected)[0]
|
||||||
|
: 'none';
|
||||||
|
|
||||||
|
const currentOverlay = () =>
|
||||||
|
getOverlays() ? getOverlays()[currentOverlayKey()] : {};
|
||||||
|
|
||||||
|
const currentOverlayDefinition = () => overlayDefinitions[currentOverlayKey()];
|
||||||
|
|
||||||
|
const currentOverlayHighlightedKey = () =>
|
||||||
|
currentOverlay() && currentOverlay().highlighted
|
||||||
|
? Object.keys(currentOverlay().highlighted)[0]
|
||||||
|
: 'none';
|
||||||
|
|
||||||
const MapTilesProvider: Component<{}> = (props) => {
|
const MapTilesProvider: Component<{}> = (props) => {
|
||||||
const [open, setOpen] = createSignal(false);
|
const [open, setOpen] = createSignal(false);
|
||||||
|
|
||||||
|
@ -116,6 +206,50 @@ const MapTilesProvider: Component<{}> = (props) => {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
createEffect(() => {
|
||||||
|
console.log({
|
||||||
|
caller: 'MapTilesProvider',
|
||||||
|
overlays: getOverlays(),
|
||||||
|
currentOverlayKey: currentOverlayKey(),
|
||||||
|
currentOverlay: currentOverlay(),
|
||||||
|
currentOverlayDefinition: currentOverlayDefinition(),
|
||||||
|
currentOverlayHighlightedKey: currentOverlayHighlightedKey(),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleOverlayChange = (ev: any) => {
|
||||||
|
const value = ev.target.value;
|
||||||
|
console.log({
|
||||||
|
caller: 'MapTilesProvider / handleOverlayChange',
|
||||||
|
ev,
|
||||||
|
value,
|
||||||
|
});
|
||||||
|
const newOverlays = getOverlays();
|
||||||
|
Object.keys(newOverlays).forEach((key) => {
|
||||||
|
newOverlays[key].selected = key === value;
|
||||||
|
});
|
||||||
|
dispatch({
|
||||||
|
action: 'putOverlays',
|
||||||
|
params: { id, overlays: newOverlays },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOverlayHighlightChange = (ev: any) => {
|
||||||
|
const value = ev.target.value;
|
||||||
|
console.log({
|
||||||
|
caller: 'MapTilesProvider / handleOverlayHighlightChange',
|
||||||
|
ev,
|
||||||
|
value,
|
||||||
|
});
|
||||||
|
const newOverlays = getOverlays();
|
||||||
|
newOverlays[currentOverlayKey()].highlighted = {};
|
||||||
|
newOverlays[currentOverlayKey()].highlighted[value] = [];
|
||||||
|
dispatch({
|
||||||
|
action: 'putOverlays',
|
||||||
|
params: { id, overlays: newOverlays },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div class={style.control}>
|
<div class={style.control}>
|
||||||
|
@ -123,28 +257,66 @@ const MapTilesProvider: Component<{}> = (props) => {
|
||||||
<LayersIcon />
|
<LayersIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</div>
|
</div>
|
||||||
<Dialog onClose={handleClose} open={open()} class={style.dialog}>
|
<Dialog
|
||||||
<DialogTitle class={style.title}>
|
closeHandler={handleClose}
|
||||||
<div class={style['title-text']}>{t('chooseYourMap')}</div>
|
open={open()}
|
||||||
<IconButton onClick={handleClose} class={style.close}>
|
title={t('chooseYourMap')}
|
||||||
<CloseIcon />
|
>
|
||||||
</IconButton>
|
<Tree
|
||||||
</DialogTitle>
|
title={t('overlay')}
|
||||||
<RadioGroup
|
content={
|
||||||
defaultValue={params.provider}
|
<>
|
||||||
class={style.body}
|
<RadioGroup
|
||||||
onChange={handleChange}
|
defaultValue={currentOverlayKey()}
|
||||||
>
|
onChange={handleOverlayChange}
|
||||||
<For each={Object.keys(mapTileProviders)}>
|
>
|
||||||
{(p: string) => (
|
<For each={Object.keys(overlayDefinitions)}>
|
||||||
<FormControlLabel
|
{(p: string) => (
|
||||||
value={p}
|
<FormControlLabel value={p} control={<Radio />} label={p} />
|
||||||
control={<Radio />}
|
)}
|
||||||
label={mapTileProviders[p].name}
|
</For>
|
||||||
/>
|
</RadioGroup>
|
||||||
)}
|
<Show when={Object.keys(currentOverlayDefinition()).length > 0}>
|
||||||
</For>
|
{' '}
|
||||||
</RadioGroup>
|
<div>---</div>
|
||||||
|
<div>Highlight</div>
|
||||||
|
<RadioGroup
|
||||||
|
defaultValue={currentOverlayHighlightedKey()}
|
||||||
|
onChange={handleOverlayHighlightChange}
|
||||||
|
>
|
||||||
|
<For each={Object.keys(currentOverlayDefinition())}>
|
||||||
|
{(p: string) => (
|
||||||
|
<FormControlLabel
|
||||||
|
value={p}
|
||||||
|
control={<Radio />}
|
||||||
|
label={p}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</RadioGroup>
|
||||||
|
</Show>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
subTree={undefined}
|
||||||
|
></Tree>
|
||||||
|
|
||||||
|
<Tree
|
||||||
|
title={t('baseLayer')}
|
||||||
|
content={
|
||||||
|
<RadioGroup defaultValue={params.provider} onChange={handleChange}>
|
||||||
|
<For each={Object.keys(mapTileProviders)}>
|
||||||
|
{(p: string) => (
|
||||||
|
<FormControlLabel
|
||||||
|
value={p}
|
||||||
|
control={<Radio />}
|
||||||
|
label={mapTileProviders[p].name}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</RadioGroup>
|
||||||
|
}
|
||||||
|
subTree={undefined}
|
||||||
|
></Tree>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { getWpt } from '../db/wpt';
|
||||||
import { returnAgain } from '../workers/dispatcher-worker';
|
import { returnAgain } from '../workers/dispatcher-worker';
|
||||||
import { getAllGpxes, getGpx } from './gpx';
|
import { getAllGpxes, getGpx } from './gpx';
|
||||||
import { put } from './lib';
|
import { put } from './lib';
|
||||||
|
import { getOverlays } from './overlays';
|
||||||
import { getRte } from './rte';
|
import { getRte } from './rte';
|
||||||
import { getTrk } from './trk';
|
import { getTrk } from './trk';
|
||||||
import { getTrkseg } from './trkseg';
|
import { getTrkseg } from './trkseg';
|
||||||
|
@ -18,6 +19,7 @@ const methods = {
|
||||||
getTrkseg,
|
getTrkseg,
|
||||||
getWpt,
|
getWpt,
|
||||||
getRte,
|
getRte,
|
||||||
|
getOverlays,
|
||||||
};
|
};
|
||||||
|
|
||||||
const sendUpdate = async (params: any) => {
|
const sendUpdate = async (params: any) => {
|
||||||
|
@ -79,7 +81,9 @@ const changeHandler = async (change: any) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const parentParams = globalThis.watches.get(parentId);
|
const parentParams = globalThis.watches.get(parentId);
|
||||||
debouncedSendUpdates[parentParams.method](parentParams);
|
if (parentParams) {
|
||||||
|
debouncedSendUpdates[parentParams.method](parentParams);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default changeHandler;
|
export default changeHandler;
|
||||||
|
|
|
@ -136,6 +136,16 @@ export const initDb = async (params: any) => {
|
||||||
console.log({ caller: 'changes / complete', error });
|
console.log({ caller: 'changes / complete', error });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const localDbChanges = localDb
|
||||||
|
.changes({ since: 'now', live: true, include_docs: false })
|
||||||
|
.on('change', changeHandler)
|
||||||
|
.on('complete', (info: any) => {
|
||||||
|
console.log({ caller: 'localDb changes / complete', info });
|
||||||
|
})
|
||||||
|
.on('error', (error: any) => {
|
||||||
|
console.log({ caller: 'localDb changes / complete', error });
|
||||||
|
});
|
||||||
|
|
||||||
// console.log({ caller: 'initDb / back from db.changes', changes });
|
// console.log({ caller: 'initDb / back from db.changes', changes });
|
||||||
|
|
||||||
// changes.cancel();
|
// changes.cancel();
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { get, put } from './lib';
|
||||||
|
|
||||||
|
export const getOverlays = async (params: any) => {
|
||||||
|
const { id, defaultOverlays } = params;
|
||||||
|
try {
|
||||||
|
const overlays = await get(id, true);
|
||||||
|
return overlays.doc;
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error({ caller: 'getOverlays', error });
|
||||||
|
return defaultOverlays;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const putOverlays = async (params: any) => {
|
||||||
|
const { id, overlays } = params;
|
||||||
|
await put(id, 'overlays', (doc) => overlays, {}, true);
|
||||||
|
return overlays;
|
||||||
|
};
|
|
@ -2,6 +2,9 @@ const dict = {
|
||||||
close: 'close',
|
close: 'close',
|
||||||
|
|
||||||
chooseYourMap: 'Choose your map',
|
chooseYourMap: 'Choose your map',
|
||||||
|
baseLayer: 'Base layer',
|
||||||
|
overlay: 'Overlay',
|
||||||
|
hiking: 'Hiking',
|
||||||
|
|
||||||
nearby: 'Nearby',
|
nearby: 'Nearby',
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,9 @@ const dict = {
|
||||||
close: 'quitter',
|
close: 'quitter',
|
||||||
|
|
||||||
chooseYourMap: 'Choisissez votre carte',
|
chooseYourMap: 'Choisissez votre carte',
|
||||||
|
baseLayer: 'Fond de carte',
|
||||||
|
overlay: 'Sur couche',
|
||||||
|
hiking: 'Randonnée',
|
||||||
|
|
||||||
nearby: 'À proximité',
|
nearby: 'À proximité',
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ const coding = {
|
||||||
const routes = {
|
const routes = {
|
||||||
dbdef: route('dbdef', coding),
|
dbdef: route('dbdef', coding),
|
||||||
state: route('state', coding),
|
state: route('state', coding),
|
||||||
|
overlays: route('overlays', coding),
|
||||||
account: route('account/:account', coding),
|
account: route('account/:account', coding),
|
||||||
settings: route('settings', coding),
|
settings: route('settings', coding),
|
||||||
gpx: route('gpx/:gpx', coding),
|
gpx: route('gpx/:gpx', coding),
|
||||||
|
|
|
@ -12,6 +12,7 @@ import {
|
||||||
getAllGpxes,
|
getAllGpxes,
|
||||||
getAllGpxesWithSummary,
|
getAllGpxesWithSummary,
|
||||||
} from '../db/gpx';
|
} from '../db/gpx';
|
||||||
|
import { putOverlays } from '../db/overlays';
|
||||||
import { putRte } from '../db/rte';
|
import { putRte } from '../db/rte';
|
||||||
import { putRtept } from '../db/rtept';
|
import { putRtept } from '../db/rtept';
|
||||||
import { getSettings, putSettings } from '../db/settings';
|
import { getSettings, putSettings } from '../db/settings';
|
||||||
|
@ -59,6 +60,8 @@ onmessage = async function (e) {
|
||||||
getState,
|
getState,
|
||||||
setState,
|
setState,
|
||||||
|
|
||||||
|
putOverlays,
|
||||||
|
|
||||||
getAndWatch,
|
getAndWatch,
|
||||||
cancelWatch,
|
cancelWatch,
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue