3D globe and flat map rendering, textures, shaders, clustering, and mobile touch gestures in World Monitor.
Two rendering engines are available, switchable at runtime via Settings or the VITE_MAP_INTERACTION_MODE environment variable (globe or flat). The preference is persisted in localStorage.
3D Globe (globe.gl + Three.js) — a photorealistic 3D Earth with full pitch and rotation:
- Earth textures — topographic-bathymetric day surface (
earth-topo-bathy.jpg), specular water map for ocean reflections, and a starfield night-sky background - Atmosphere shader — a Fresnel limb-glow effect simulates atmospheric scattering at the globe's edge
- Auto-rotation — the globe slowly rotates when idle, pausing on any user interaction and resuming after 60 seconds of inactivity
- HTML marker layer — all 28+ data categories (conflicts, intel hotspots, AIS vessels, flights, protests, fires, etc.) render as HTML elements pinned to geographic coordinates on the globe surface
- Geopolitical polygon overlays — the Korean DMZ and other boundary polygons render directly on the globe under the conflicts layer
- Debounced marker flush — rapid data updates are coalesced via
debounceFlushMarkers()to prevent Three.js scene graph crashes during high-frequency data refresh - Configurable render quality — a Settings dropdown offers five pixel-ratio presets: Auto (matches device DPR, capped at 2×), Eco (1×), Sharp (1.5×), 4K (2×), and Insane (3×). The setting updates the Three.js renderer live without page reload. Desktop (Tauri) builds cap the default at 1.25× to avoid software-rendering fallback on machines without discrete GPUs
- Desktop-optimized defaults — Tauri desktop builds request the high-performance GPU (
powerPreference: 'high-performance'), disable the logarithmic depth buffer (saves shader overhead), and turn off auto-rotation and camera damping to eliminate continuous render loop wakeups when idle — addressing reports of 1 fps performance on some machines - Background pause — when the desktop app window loses focus or the globe panel is hidden, the WebGL render loop pauses entirely, stopping the Three.js animation loop and canceling auto-rotate. Data updates received while paused are queued and flushed in a single batch when the globe returns to view, eliminating background GPU load on laptops
- Beta indicator — a pulsing cyan "BETA" badge appears when the globe is active, signaling the feature is newer than the flat map
Flat Map (deck.gl + MapLibre GL JS) — a WebGL-accelerated 2D map with smooth 60fps rendering and thousands of concurrent markers:
- Layer types —
GeoJsonLayer,ScatterplotLayer,PathLayer,IconLayer,TextLayer,PolygonLayer,ArcLayer,HeatmapLayercomposited in a single render pass - Smart clustering — Supercluster groups markers at low zoom, expands on zoom in. Cluster thresholds adapt to zoom level
- Progressive disclosure — detail layers (bases, nuclear, datacenters) appear only when zoomed in; zoom-adaptive opacity fades markers from 0.2 at world view to 1.0 at street level
- Label deconfliction — overlapping labels (e.g., multiple BREAKING badges) are automatically suppressed by priority, highest-severity first
- Day/night overlay — a terminator line divides the map into sunlit and dark hemispheres based on the current UTC time
Shared across both engines:
- 45 data layers — conflicts, military bases, nuclear facilities, undersea cables, pipelines, satellite fire detection, protests, natural disasters, datacenters, displacement flows, climate anomalies, cyber threat IOCs, GPS/GNSS jamming zones, Iran attacks, CII country risk heatmap, day/night terminator, geopolitical boundaries (Korean DMZ), stock exchanges, financial centers, central banks, commodity hubs, Gulf investments, trade routes, airport delays, sanctions regimes, and more. All layer definitions are maintained in a single shared catalog (
map-layer-definitions.ts) consumed by both renderers — adding a new layer is a single-file operation. Layers are variant-specific: full (29 geopolitical + military + infrastructure), tech (12 startup/cloud/cyber), finance (15 exchange/banking/trade), and happy (5 positive-events/conservation) - 8 regional presets — Global, Americas, Europe, MENA, Asia, Africa, Oceania, Latin America
- Time filtering — 1h, 6h, 24h, 48h, 7d event windows
- URL state sharing — map center, zoom, active layers, and time range are encoded in the URL for shareable views (
?view=mena&zoom=4&layers=conflicts,bases) - Mobile touch gestures — single-finger pan with inertial velocity animation (0.92 decay factor, computed from 4-entry circular touch history), two-finger pinch-to-zoom with center-point preservation, and bottom-sheet popups with drag-to-dismiss. An 8px movement threshold prevents accidental interaction during taps
- Timezone-based region detection — on first load, the map centers on the user's approximate region derived from
Intl.DateTimeFormat().resolvedOptions().timeZone— no network dependency, no geolocation prompt. On mobile, the browser's Geolocation API is queried (5-second timeout) and the map auto-centers on the user's precise GPS coordinates at zoom level 6. If the URL already contains shared coordinates, the shared view takes precedence and geolocation is skipped - Cmd+K map navigation — the command palette supports
Map:prefixed commands to fly to any country or region on either engine