// Selectable basemaps for the dashboard map - mirrors kepler.gl's base-map // picker. Most are CARTO's free, no-API-key GL styles; "Satellite" and // "No Basemap" are built as inline style objects so switching is just a // map.setStyle() with the resolved style. import type { StyleSpecification } from 'maplibre-gl' export type BasemapId = | 'no-basemap' | 'dark-matter' | 'positron' | 'voyager' | 'satellite' | 'dark' | 'light' | 'muted-light' | 'muted-night' export interface Basemap { id: BasemapId label: string /** Either a CARTO style URL or an inline MapLibre style object. */ style: string | StyleSpecification /** Small swatch colour for the list thumbnail (fallback behind the image). */ swatch: string /** Tiny map preview image (a single Bengaluru tile in this style). */ thumb?: string /** Whether this is a light-toned basemap (used by the theme toggle). */ light: boolean } const CARTO = 'https://basemaps.cartocdn.com/gl' // A single 256px tile centered on Bengaluru (z11) per style, used as the list // thumbnail. CARTO raster sets use z/x/y order; ESRI satellite uses z/y/x. const TILE_Z = 11 const TILE_X = 1465 const TILE_Y = 950 const cartoThumb = (set: string) => `https://a.basemaps.cartocdn.com/rastertiles/${set}/${TILE_Z}/${TILE_X}/${TILE_Y}.png` const SATELLITE_THUMB = `https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/${TILE_Z}/${TILE_Y}/${TILE_X}` // Minimal "no basemap" style - just a flat dark canvas for the overlays. const NO_BASEMAP_STYLE: StyleSpecification = { version: 8, sources: {}, layers: [ { id: 'background', type: 'background', paint: { 'background-color': '#0a0a0b' }, }, ], } // ESRI World Imagery satellite raster with a CARTO label/road overlay on top. const SATELLITE_STYLE: StyleSpecification = { version: 8, sources: { satellite: { type: 'raster', tiles: [ 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', ], tileSize: 256, attribution: 'Tiles © Esri - Source: Esri, Maxar, Earthstar Geographics', }, }, layers: [{ id: 'satellite', type: 'raster', source: 'satellite' }], } export const BASEMAPS: Basemap[] = [ { id: 'no-basemap', label: 'No Basemap', style: NO_BASEMAP_STYLE, swatch: '#000000', light: false }, { id: 'dark-matter', label: 'DarkMatter', style: `${CARTO}/dark-matter-gl-style/style.json`, swatch: '#0e1116', thumb: cartoThumb('dark_all'), light: false }, { id: 'positron', label: 'Positron', style: `${CARTO}/positron-gl-style/style.json`, swatch: '#d9dde2', thumb: cartoThumb('light_all'), light: true }, { id: 'voyager', label: 'Voyager', style: `${CARTO}/voyager-gl-style/style.json`, swatch: '#9fb6c6', thumb: cartoThumb('voyager'), light: true }, { id: 'satellite', label: 'Satellite With Streets', style: SATELLITE_STYLE, swatch: '#3a4a3a', thumb: SATELLITE_THUMB, light: false }, { id: 'dark', label: 'Dark', style: `${CARTO}/dark-matter-nolabels-gl-style/style.json`, swatch: '#15191f', thumb: cartoThumb('dark_nolabels'), light: false }, { id: 'light', label: 'Light', style: `${CARTO}/positron-nolabels-gl-style/style.json`, swatch: '#e8ebee', thumb: cartoThumb('light_nolabels'), light: true }, { id: 'muted-light', label: 'Muted Light', style: `${CARTO}/voyager-nolabels-gl-style/style.json`, swatch: '#c7d2da', thumb: cartoThumb('voyager_nolabels'), light: true }, { id: 'muted-night', label: 'Muted Night', style: `${CARTO}/dark-matter-gl-style/style.json`, swatch: '#1a1d24', thumb: cartoThumb('dark_all'), light: false }, ] // Defaults the theme toggle flips between. export const DEFAULT_DARK_BASEMAP: BasemapId = 'dark-matter' export const DEFAULT_LIGHT_BASEMAP: BasemapId = 'positron' export function getBasemap(id: BasemapId): Basemap { return BASEMAPS.find((b) => b.id === id) ?? BASEMAPS[1] }