dyomedea/src/components/map-tile-provider/MapTileProvider.tsx

129 lines
3.0 KiB
TypeScript

import OSM from 'ol/source/OSM';
import XYZ from 'ol/source/XYZ';
import { Component, createSignal, For } from 'solid-js';
import style from './MapTileProvider.module.css';
import LayersIcon from '@suid/icons-material/Layers';
import CloseIcon from '@suid/icons-material/Close';
import {
Dialog,
DialogTitle,
FormControlLabel,
IconButton,
Radio,
RadioGroup,
} from '@suid/material';
import { useNavigate, useParams } from '@solidjs/router';
interface TileProvider {
name: string;
language: string;
source: XYZ;
}
type TileProviders = {
[key: string]: TileProvider;
};
export const mapTileProviders: TileProviders = {
osm: {
name: 'Open Street Map',
language: 'int',
source: new OSM(),
},
osmfr: {
name: 'Open Street Map France',
language: 'fr',
source: new XYZ({
minZoom: 0,
maxZoom: 20,
url: 'https://{a-c}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png',
}),
},
otm: {
name: 'Open Topo Map',
language: 'int',
source: new XYZ({
minZoom: 0,
maxZoom: 20,
url: 'https://{a-c}.tile.opentopomap.org/{z}/{x}/{y}.png',
}),
},
cyclosm: {
name: 'CyclOSM',
language: 'int',
source: new XYZ({
minZoom: 0,
maxZoom: 19,
url: 'https://{a-c}.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png',
}),
},
//https://b.tile.openstreetmap.fr/openriverboatmap/20/535762/382966.png
openriverboatmap: {
name: 'Open River Boat Map',
language: 'int',
source: new XYZ({
minZoom: 0,
maxZoom: 19,
url: 'https://{a-c}.tile.openstreetmap.fr/openriverboatmap/{z}/{x}/{y}.png',
}),
},
};
const MapTilesProvider: Component<{}> = (props) => {
const [open, setOpen] = createSignal(false);
const navigate = useNavigate();
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
const params = useParams();
const handleChange = (ev: any) => {
navigate(
`/map/${ev.target.value}/${params.lon}/${params.lat}/${params.zoom}/${params.rotation}`
);
setOpen(false);
};
return (
<>
<div class={style.control}>
<IconButton onClick={handleClickOpen}>
<LayersIcon />
</IconButton>
</div>
<Dialog onClose={handleClose} open={open()} class={style.dialog}>
<DialogTitle class={style.title}>
<div class={style['title-text']}>Choose your map</div>
<IconButton onClick={handleClose} class={style.close}>
<CloseIcon />
</IconButton>
</DialogTitle>
<RadioGroup
defaultValue={params.provider}
class={style.body}
onChange={handleChange}
>
<For each={Object.keys(mapTileProviders)}>
{(p: string) => (
<FormControlLabel
value={p}
control={<Radio />}
label={mapTileProviders[p].name}
/>
)}
</For>
</RadioGroup>
</Dialog>
</>
);
};
export default MapTilesProvider;