onLayerToggle?: (layerId: string) => void; // OPFISH WMS layer hook - only pass selectedDate when user has explicitly moved slider // PFZ Zones layer - renders the new pfz_zones_2025-12-25.geojson with glowing effect // Unlock a premium layer after code validation map.setPaintProperty(layer.id, 'raster-brightness-min', filterValue - 0.2); map.setPaintProperty(layer.id, 'raster-brightness-max', filterValue + 0.2); map.addSource('emodnet-bed', { map.addLayer( // Add bathymetry layers (initialized hidden; toggled via setBathyVisibility) map.addSource('bathy-global', { map.addLayer( map.addSource('bathy-europe', { map.addLayer({ map.addSource('contours', { map.addLayer({ // ═══ CARTES layer stack (8 layers, all hidden by default) ═══ const firstSymbol = map.getStyle().layers?.find(l => l.type === 'symbol')?.id; map.addSource('satcatch-terrain', { map.addLayer({ map.addSource('cartes-depth-raster', { map.addLayer({ id: 'cartes-depth-raster-layer', type: 'raster', source: 'cartes-depth-raster', fetch('https://tiles.satcatch.com/med_isobaths_simple.geojson') .then(geojson => { map.addSource('cartes-isobaths', { type: 'geojson', data: geojson }); map.addLayer({ id: 'cartes-isobath-lines', type: 'line', source: 'cartes-isobaths', map.addLayer({ id: 'cartes-isobath-labels', type: 'symbol', source: 'cartes-isobaths', map.addLayer({ id: 'cartes-tombant-label', type: 'symbol', source: 'cartes-isobaths', fetch('https://tiles.satcatch.com/DZ_EEZ.geojson') .then(geojson => { map.addSource('cartes-eez', { type: 'geojson', data: geojson }); map.addLayer({ id: 'cartes-eez-line', type: 'line', source: 'cartes-eez', map.addLayer({ id: 'cartes-eez-label', type: 'symbol', source: 'cartes-eez', map.addSource('cartes-openseamap', { map.addLayer({ id: 'cartes-openseamap-layer', type: 'raster', source: 'cartes-openseamap', map.addSource('cartes-ports', { type: 'geojson', data: { type: 'FeatureCollection', features: portFeatures } }); map.addLayer({ id: 'cartes-ports-layer', type: 'symbol', source: 'cartes-ports', // ═══ S-57 feature layers (L9–L18, all hidden by default) ═══ map.addSource('cartes-soundings', { type: 'geojson', data: 'https://tiles.satcatch.com/med_soundings.geojson' }); map.addLayer({ id: 'cartes-soundings-layer', type: 'symbol', source: 'cartes-soundings', map.addSource('cartes-lighthouses', { type: 'geojson', data: 'https://tiles.satcatch.com/lighthouses.geojson' }); map.addLayer({ id: 'cartes-lighthouses-layer', type: 'circle', source: 'cartes-lighthouses', map.addLayer({ id: 'cartes-lighthouses-label', type: 'symbol', source: 'cartes-lighthouses', map.addSource('cartes-seamarks', { type: 'geojson', data: 'https://tiles.satcatch.com/seamarks.geojson' }); map.addLayer({ id: 'cartes-buoys-lateral', type: 'circle', source: 'cartes-seamarks', map.addLayer({ id: 'cartes-buoys-cardinal', type: 'circle', source: 'cartes-seamarks', map.addLayer({ id: 'cartes-buoys-safewater', type: 'circle', source: 'cartes-seamarks', map.addLayer({ id: 'cartes-wrecks', type: 'symbol', source: 'cartes-seamarks', map.addLayer({ id: 'cartes-rocks', type: 'circle', source: 'cartes-seamarks', map.addLayer({ id: 'cartes-anchorages', type: 'symbol', source: 'cartes-seamarks', map.addSource('cartes-landmarks', { type: 'geojson', data: ALGERIAN_LANDMARKS }); map.addLayer({ id: 'cartes-landmarks-layer', type: 'symbol', source: 'cartes-landmarks', map.addSource('cartes-lights', { type: 'geojson', data: 'https://tiles.satcatch.com/algeria_lights.geojson' }); map.addLayer({ id: 'cartes-lights-circle', type: 'circle', source: 'cartes-lights', map.addLayer({ id: 'cartes-lights-label', type: 'symbol', source: 'cartes-lights', map.addSource('cartes-dangers', { type: 'geojson', data: 'https://tiles.satcatch.com/algeria_dangers.geojson' }); map.addLayer({ id: 'cartes-rocks-layer', type: 'circle', source: 'cartes-dangers', map.addLayer({ id: 'cartes-wrecks-layer', type: 'symbol', source: 'cartes-dangers', map.addLayer({ id: 'cartes-reefs-layer', type: 'circle', source: 'cartes-dangers', map.addSource('cartes-infrastructure', { type: 'geojson', data: 'https://tiles.satcatch.com/algeria_infrastructure.geojson' }); map.addLayer({ id: 'cartes-infrastructure-layer', type: 'fill', source: 'cartes-infrastructure', map.addLayer({ id: 'cartes-infrastructure-lines', type: 'line', source: 'cartes-infrastructure', map.addSource('cartes-restrictions', { type: 'geojson', data: 'https://tiles.satcatch.com/algeria_restrictions.geojson' }); map.addLayer({ id: 'cartes-cables-layer', type: 'line', source: 'cartes-restrictions', map.addLayer({ id: 'cartes-cables-label', type: 'symbol', source: 'cartes-restrictions', map.addSource('cartes-submarine', { type: 'geojson', data: 'https://tiles.satcatch.com/algeria_submarine_features.geojson' }); map.addSource('cartes-contours-key', { type: 'geojson', data: 'https://tiles.satcatch.com/med_contours_key.geojson' }); map.addLayer({ id: 'cartes-contours-key-lines', type: 'line', source: 'cartes-contours-key', map.addLayer({ id: 'cartes-canyons-label', type: 'symbol', source: 'cartes-submarine', map.addLayer({ id: 'cartes-basins-label', type: 'symbol', source: 'cartes-submarine', map.addLayer({ id: 'cartes-shelves-label', type: 'symbol', source: 'cartes-submarine', map.addSource('mostaganem-port', { type: 'geojson', data: MOSTAGANEM_PORT }); map.addLayer({ id: 'port-harbour-fill', type: 'fill', source: 'mostaganem-port', map.addLayer({ id: 'port-harbour-outline', type: 'line', source: 'mostaganem-port', map.addLayer({ id: 'port-breakwater', type: 'line', source: 'mostaganem-port', map.addLayer({ id: 'port-construction-fill', type: 'fill', source: 'mostaganem-port', map.addLayer({ id: 'port-construction-outline', type: 'line', source: 'mostaganem-port', map.addLayer({ id: 'port-construction-labels', type: 'symbol', source: 'mostaganem-port', map.addLayer({ id: 'port-piers', type: 'line', source: 'mostaganem-port', map.addLayer({ id: 'port-slipways', type: 'line', source: 'mostaganem-port', map.addLayer({ id: 'port-lights-red', type: 'circle', source: 'mostaganem-port', map.addLayer({ id: 'port-lights-green', type: 'circle', source: 'mostaganem-port', map.addLayer({ id: 'port-lighthouse', type: 'circle', source: 'mostaganem-port', map.addLayer({ id: 'port-labels', type: 'symbol', source: 'mostaganem-port', map.addLayer({ id: 'port-light-chars', type: 'symbol', source: 'mostaganem-port', map.addLayer({ id: 'enc-anchorages', type: 'symbol', source: 'cartes-seamarks', map.addLayer({ id: 'enc-lighthouses', type: 'symbol', source: 'cartes-lighthouses', map.addLayer({ id: 'enc-rocks', type: 'symbol', source: 'cartes-seamarks', map.addLayer({ id: 'enc-wrecks', type: 'symbol', source: 'cartes-seamarks', map.addLayer({ id: 'enc-buoys-green', type: 'symbol', source: 'cartes-seamarks', map.addLayer({ id: 'enc-buoys-red', type: 'symbol', source: 'cartes-seamarks', map.addLayer({ id: 'enc-marinas', type: 'symbol', source: 'cartes-seamarks', map.addLayer({ id: 'enc-towers', type: 'symbol', source: 'cartes-infrastructure', map.addLayer({ id: 'enc-facilities', type: 'symbol', source: 'cartes-infrastructure', map.addLayer({ id: 'enc-soundings', type: 'symbol', source: 'cartes-soundings', __swapEmodnetBED?: (layerId: string) => void; f?.layer?.id?.includes('land') || const addLayer = ( map.addSource(sourceId, { map.addLayer({ addLayer('cmems-sst', 'cmems-sst', url); addLayer('cmems-chla', 'cmems-chla', url); // No WMTS layer needed here - the iframe provides the currents visualization addLayer('cmems-waves', 'cmems-waves', url); addLayer('cmems-wave-direction', 'cmems-wave-direction', url); addLayer('cmems-adt', 'cmems-adt', url); addLayer('cmems-oxygen', 'cmems-oxygen', url); addLayer('cmems-salinity', 'cmems-salinity', url); addLayer('cmems-nitrate', 'cmems-nitrate', url); map.addSource('gebco', { 'https://wms.gebco.net/mapserv?service=WMS&version=1.1.1&request=GetMap&layers=GEBCO_LATEST&styles=&format=image/png&transparent=true&srs=EPSG:3857&bbox={bbox-epsg-3857}&width=256&height=256' map.addLayer({ .select('geojson, timestamp') if (!data || !data.geojson) { const geojson = data.geojson as unknown as GeoJSON.FeatureCollection; if (!geojson || geojson.type !== 'FeatureCollection') { console.log(`🌊 [TZMapShell] Loaded ${geojson.features?.length || 0} fronts from Supabase`); map.addLayer({ map.addLayer({ map.addSource(SOURCE_ID, { type: 'geojson', data: geojson }); source.setData(geojson);