import { WxGetColorStyles } from '@metoceanapi/wxtiles-common/utils/wxtools'; import L from 'leaflet'; export function flyTo(map: L.Map, zoom: number, lng: number, lat: number, bearing: number, pitch: number) { map.flyTo([lat, lng], zoom); } export function setURL( map: L.Map, time: string, datasetName: string, variable: string, // biome-ignore lint/suspicious/noExplicitAny: Suppressing for specific use case style: any, ) { let newStyle = style; const { base } = WxGetColorStyles(); for (const i in style) style[i] === base[i] && delete style[i]; // remove default values if (style.gl) { for (const i in style.gl) style.gl[i] === base.gl?.[i] && delete style.gl[i]; // remove default values from gl if (Object.keys(style.gl).length === 0) { const { gl, ...rest } = style; // Destructure to exclude gl newStyle = rest; // Assign the new object back to style } } const center = map.getCenter().wrap(); const href = `##${datasetName}/${variable}/${time}/${map.getZoom().toFixed(2)}/${center.lng.toFixed(2)}/${center.lat.toFixed(2)}/0/0${newStyle ? `/${JSON.stringify(newStyle)}` : ''}`; history.replaceState(null, '', href); // location.href = `#${datasetName}/${variables.join(',')}/${time}/${map.getZoom().toFixed(2)}/${center.lng.toFixed(2)}/${center.lat.toFixed(2)}`; } export async function initFrameWork() { const map = L.map('map', { center: [-40.75, 174.5], zoom: 7, zoomControl: false, }); L.control.zoom({ position: 'bottomright' }).addTo(map); // class WxDebugLayer extends L.GridLayer { // createTile(coords: { x: number; y: number; z: number }) { // const tile = document.createElement('div'); // tile.innerHTML = [coords.x, coords.y, coords.z].join(', '); // tile.style.outline = '1px solid red'; // return tile; // } // } // map.addLayer(new WxDebugLayer().setZIndex(1000)); return map; } export function addControl( map: L.Map, // biome-ignore lint/suspicious/noExplicitAny: Suppressing for specific use case control: { extender: () => any }, position: string, ) { const newPosition = position.replace('-', ''); map.addControl( // biome-ignore lint/suspicious/noExplicitAny: Suppressing for specific use case new (L.Control.extend(control.extender()))({ position: newPosition as any }), ); } export function position(e: L.LeafletMouseEvent): L.LatLng { return e.latlng.wrap(); // (mapbox) } export function removeLayer(map: L.Map, layerId: string, layer?: L.Layer) { // biome-ignore lint/suspicious/noExplicitAny: Suppressing for specific use case map.eachLayer((l: any) => { if (l.options.id === layerId) { map.removeLayer(l); } }); } export async function addLayer(map: L.Map, idL: string, layer: L.Layer) { map.addLayer(layer); await new Promise((done) => layer.once('load', done)); // highly recommended to await for the first load } async function fetchImage(url, callback, errback, headers, abort) { const controller = new AbortController(); const signal = controller.signal; if (abort) { abort.subscribe(() => { controller.abort(); }); } await fetch(url, { method: 'GET', headers: headers, mode: 'cors', signal: signal, }) .then((resp) => { if (resp.ok) { return resp.blob(); } throw new Error(`Unexpected response: ${resp.status} (${resp.type})`); }) .then((blob) => callback(blob)) .catch((error) => errback(error)); } L.TileLayerWithHeaders = L.TileLayer.extend({ initialize: function (url, options, headers, abort) { L.TileLayer.prototype.initialize.call(this, url, options); this.headers = headers; this.abort = abort; }, createTile(coords, done) { const url = this.getTileUrl(coords); const img = document.createElement('img'); img.setAttribute('role', 'presentation'); fetchImage( url, (resp) => { if (resp.size > 0) { const reader = new FileReader(); reader.onload = () => { img.src = reader.result; }; reader.readAsDataURL(resp); done(null, img); } }, (error) => console.log(error), this.headers, this.abort, ); return img; }, }); L.tileLayerWithHeaders = function (url, options, headers, abort) { return new L.TileLayerWithHeaders(url, options, headers, abort); }; export function addRaster( map: L.Map, idS: string, idL: string, URL: string, maxZoom: number, // biome-ignore lint/suspicious/noExplicitAny: Suppressing for specific use case bounds?: any, headers?: any, ) { const options = { id: idS, maxNativeZoom: maxZoom, zIndex: idL === 'baseL' ? 1 : 0, }; const layer = headers ? L.tileLayerWithHeaders(URL, options, headers) : L.tileLayer(URL, options); map.addLayer(layer); }