import OSM from 'ol/source/OSM'; import XYZ from 'ol/source/XYZ'; import { Component, createEffect, createSignal, For, Show } from 'solid-js'; import { I18nContext, createI18nContext, useI18n, } from '@solid-primitives/i18n'; import style from './MapTileProvider.module.css'; import LayersIcon from '@suid/icons-material/Layers'; import CloseIcon from '@suid/icons-material/Close'; import { FormControlLabel, IconButton, Radio, RadioGroup, } from '@suid/material'; 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'; import { Feature } from 'ol'; import { overlayCategories, overlayDefinitions, } from '../overlays/overlay-definitions'; const id = getUri('overlays', undefined); 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: 16, 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', }), }, rasterIgnEs: { name: 'Cartografía Ráster de España del IGN', language: 'es', source: new XYZ({ minZoom: 0, maxZoom: 19, url: 'http://www.ign.es/wmts/mapa-raster?request=getTile&layer=MTN&TileMatrixSet=GoogleMapsCompatible&TileMatrix={z}&TileCol={x}&TileRow={y}&format=image/jpeg', }), }, pnoaMaEs: { name: 'Ortoimágenes de España', language: 'es', source: new XYZ({ minZoom: 0, maxZoom: 19, url: 'http://www.ign.es/wmts/pnoa-ma?request=getTile&layer=MTN&TileMatrixSet=GoogleMapsCompatible&TileMatrix={z}&TileCol={x}&TileRow={y}&format=image/jpeg', }), }, }; type FeatureSubTypes = Array | '*'; type FeatureTypes = Record; type Overlay = { selected: boolean; highlighted: FeatureTypes; hidden: FeatureTypes; }; type Overlays = Record; const defaultOverlays: Overlays = { none: { selected: true, highlighted: { none: [] }, hidden: {} }, hiking: { selected: false, highlighted: { none: [], }, hidden: { none: [] }, }, }; // type OverlayDefinition = Record; // type OverlayDefinitions = Record; // export const overlayDefinitions: OverlayDefinitions = { // none: {}, // hiking: { // none: {}, // sleeping: { // tourism: [ // 'hotel', // 'alpine_hut', // 'apartment', // 'camp_site', // 'chalet', // 'guest_house', // 'hostel', // 'motel', // 'wilderness_hut', // ], // }, // drinking: { // amenity: ['bar', 'cafe', 'pub', 'drinking_water', 'water_point'], // natural: ['spring'], // }, // 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'], // }, // naturalSites: { // tourism: ['viewpoint'], // natural: '*', // }, // }, // }; 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 overlayCategoriesPlusNone = { none: [], ...overlayCategories }; export const currentCategory = () => currentOverlayKey() === 'none' ? [] : ['none', ...overlayCategoriesPlusNone[currentOverlayKey()]]; const currentOverlayHighlightedKey = () => currentOverlay() && currentOverlay().highlighted ? currentOverlay().highlighted : 'none'; export const currentOverlayHighlightedDefinition = () => currentCategory()[currentOverlayHighlightedKey()]; export const highlightedTags = () => { let result = {}; Object.keys(overlayDefinitions).forEach((tagName) => { let tagValues = []; const tag = overlayDefinitions[tagName]; Object.keys(tag).forEach((tagValue) => { const catDef = tag[tagValue]; Object.keys(catDef).forEach((catName) => { if (catName === currentOverlayKey()) { const catValue = catDef[catName]; if (catValue[currentOverlay()?.highlighted]) { tagValues = [...tagValues, tagValue]; } } }); }); if (tagValues.length > 0) { result[tagName] = tagValues; } }); // console.log({ // caller: 'MapTileProviders / highlightedTags', // result, // currentOverlayKey: currentOverlayKey(), // currentOverlay: currentOverlay(), // }); return result; }; // createEffect(() => { // highlightedTags = {}; // Object.keys(overlayDefinitions).forEach((tagName) => { // let tagValues = []; // const tag = overlayDefinitions[tagName]; // Object.keys(tag).forEach((tagValue) => { // const catDef = tag[tagValue]; // Object.keys(catDef).forEach((catName) => { // if (catName === currentOverlayKey()) { // const catValue = catDef[catName]; // if (catValue[currentOverlay()?.highlighted]) { // tagValues = [...tagValues, tagValue]; // } // } // }); // }); // if (tagValues.length > 0) { // highlightedTags[tagName] = tagValues; // } // }); // console.log({ // caller: 'MapTileProviders / createEffect', // highlightedTags, // currentOverlayKey: currentOverlayKey(), // currentOverlay: currentOverlay(), // }); // }); export const getHighlightedTagValue = (feature: Feature) => { let result = false; Object.keys(highlightedTags()).every((tagName) => { const value = feature.get(tagName); const highlightedValues = highlightedTags()[tagName]; // console.log({ // caller: 'MapTileProviders / highlightedTag / found', // feature, // feature_values: feature.values_, // highlightedTags, // tagName, // tag_value: value, // highlightedValues, // }); if (value !== undefined && highlightedValues.includes(value)) { result = value; return false; } return true; }); // console.log({ // caller: 'MapTileProviders / highlightedTag / result', // feature, // feature_values: feature.values_, // highlightedTags, // result, // }); return result; }; export const isHighlighted = (feature: Feature) => { return !!getHighlightedTagValue(feature); }; export const getTagValue = (feature: Feature) => { let result = false; Object.keys(overlayDefinitions).every((tagName) => { const value = feature.get(tagName); const tagValues = overlayDefinitions[tagName]; if (value !== undefined && Object.keys(tagValues).includes(value)) { // console.log({ // caller: 'MapTileProviders / tagValue / found', // feature, // feature_values: feature.values_, // highlightedTags, // tagName, // tag_value: value, // highlightedValues, // }); result = value; return false; } return true; }); // console.log({ // caller: 'MapTileProviders / isHighlighted / false', // feature, // feature_values: feature.values_, // highlightedTags, // }); return result; }; const MapTilesProvider: Component<{}> = (props) => { const [open, setOpen] = createSignal(false); const navigate = useNavigate(); const handleClickOpen = () => { setOpen(true); }; const handleClose = () => { setOpen(false); }; const params = useParams(); const [t] = useI18n(); const handleChange = (ev: any) => { navigate( `/map/${ev.target.value}/${params.lon}/${params.lat}/${params.zoom}/${params.rotation}` ); setOpen(false); }; createEffect(() => { console.log({ caller: 'MapTilesProvider', overlays: getOverlays(), currentOverlayKey: currentOverlayKey(), currentOverlay: currentOverlay(), currentOverlayDefinition: currentCategory(), 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 = value; dispatch({ action: 'putOverlays', params: { id, overlays: newOverlays }, }); }; return ( <>
{(p: string) => ( } label={p} /> )} 0}>
---
Highlight
{(p: string) => ( } label={p} /> )}
} subTree={undefined} >
{(p: string) => ( } label={mapTileProviders[p].name} /> )} } subTree={undefined} >
); }; export default MapTilesProvider;