10 KiB
Earth Frontend Context
This document describes the current real structure of the Earth display frontend. The focus is on helping future changes to the HUD, layers, media panel, real terrain, and BGP visualization avoid repeating past structural and state-sync pitfalls.
Related references:
Current Goal
The Earth frontend is not an ordinary admin page — it is an independent large-screen display frontend. Current product goals:
- Maintain the spatial depth and readability of the globe view
- Keep HUD, layers, media panel, BGP, satellites, cables, and similar elements in a unified interaction model
- Clearly represent states like loading, enabled, hidden, and locked
Current Entry Point
React route entry:
The current approach is simple:
- The React page only provides a full-screen
iframe - The actual Earth application runs at:
Earth frontend is essentially a standalone static application under public/earth.
Current File Layers
1. Page Entry and Structure
Responsibilities:
- Base HUD DOM
- Layer panel
- Media panel
- Toolbar
- Settings dialog
- Legacy element ID compatibility
2. Main Runtime
Responsibilities:
- Globe initialization
- Three.js scene assembly
- Data loading and refresh
- Layer module integration
- Earth-level state synchronization
3. Earth Control Layer
Responsibilities:
- Toolbar interaction
- Layer panel interaction
- Rotation / zoom / layout
- HUD panel drag
- Layer toggle state machine
- Earth settings read, persist, and reset
This is currently the most critical UI control entry point for the Earth frontend.
4. UI and Status Messages
Responsibilities:
- Loading panel
- Status message
- Tooltip / error / cleanup logic
5. Globe and Terrain
Responsibilities:
- Globe sphere, cloud layer, atmosphere
- Real terrain mesh
- Terrain tile fetch, decode, displacement, and shading
6. Layer Modules
- satellites.js
- cables.js
- vessels.js
- bgp.js
- bgp-cruise-adapter.js
- compute-centers.js
- country-boundaries.js
Each module is responsible for its own:
- Data fetching
- Three.js mesh creation and update
- State tracking (loaded, visible, hover, locked)
- Self-cleanup (dispose on scene destroy)
AIS Vessel Layer
The vessel layer fetches /api/v1/visualization/geo/vessels and renders the aggregated AIS GeoJSON through createInteractableLayer(). By default it does not send a limit parameter, and VESSEL_CONFIG.maxRenderedMarkers = 0 means the frontend does not clip the result to 5000 vessels. A positive options.limit or positive maxRenderedMarkers can still be used as an explicit temporary cap.
Vessel color and vessel type text must use the same normalized classification. vessels.js derives type from both vessel_type_name and the AIS numeric vessel_type code; that type drives marker color. It also derives vessel_type_display, which main.js uses for the info card, hover summary, and search result subtitle. Do not make the info card read only the raw vessel_type_name, because AISStream can provide a numeric type while the raw name is still Other.
AISStream PositionReport messages commonly carry live position and MetaData.ShipName, while vessel type usually comes from lower-frequency ShipStaticData.Type. The backend normalizes MetaData.ShipName into the vessel name and maps numeric type codes into Cargo / Tanker / Passenger / Fishing / Military where available. Missing type detail should wait for a static AIS message or the planned vessel profile enrichment; the frontend should not invent a more specific type.
7. HUD Panels and Search
8. Cruise Mode
The cruise sequencer handles generic logic: current target, queue order, camera focus, and dwell / hide / switch. Business modules supply target queues and content — they should not contain camera control logic.
9. Constants
All material, layer, satellite, BGP, cable, terrain, celestial, and other style parameters are maintained here. Do not scatter magic numbers in module files.
Current Style Layers
CSS files in frontend/public/earth/css/ each correspond to a specific component scope. Do not write global Earth styles into base.css unless they genuinely apply to everything.
Current Layer Toggle State Semantics
data-status-target
Layer toggle buttons use data-status-target attributes to link button state to layer state. The state machine in controls.js handles:
loading: showing the loading indicatorenabled: layer is activehidden: layer is hiddenerror: layer failed to load
This is the canonical way to synchronize button visual state with actual layer state. Do not maintain separate boolean flags for button display.
Current Settings Persistence
Earth settings are stored in localStorage. The key is typically a namespaced string defined in constants.js. controls.js handles read, write, and reset.
Settings that affect visual layers (terrain opacity, day/night mode, satellite display style, etc.) are read during initialization and applied immediately.
Current Terrain Pipeline
terrain.jscreates a sphere geometry with enough segments- On load, fetches Terrarium-format elevation tiles from the backend
- Decodes R/G/B into elevation values
- Displaces vertex positions radially based on elevation
- Applies a vertex alpha that fades terrain edges at coastlines
- Terrain writes to the scene as a mesh above the HD texture layer
When HD texture is off, terrain is temporarily hidden and its state is remembered. When HD texture comes back on, terrain restores its prior visibility.
Current High-Frequency Risk Points
1. Visual State and Business State Out of Sync
The most common class of Earth bugs:
- Button shows "loaded," but layer has no objects rendered
- Button shows "hidden," but objects are still visible
- Loading ended, but button still looks like it hasn't
All future changes must prioritize checking state sync.
2. HUD Layout: Check Structure First, Not CSS Patches
Earth HUD has repeatedly experienced:
- Panel compressed to a sliver
- Markdown content clipped
- Tabs/iframe content consumed by
overflow: hidden
Inspection order:
- Who is responsible for height
- Who is responsible for scrolling
- Which layer is doing the clipping
Do not immediately add overflow: hidden or extra wrapper layers.
3. Transitional Paths Must Be Closed Off
Earth has gone through multiple rounds of HUD, toolbar, and media panel refactoring, making it easy to accumulate:
- Old helpers
- Old classes
- Old fallback logic
- Deprecated variants
After each major feature is complete, do a cleanup pass.
4. Cruise Mode and Business Events Must Not Be Deeply Coupled
The correct boundary:
- The generic cruise layer only knows:
- Current target
- Queue order
- Camera focus
- Dwell / hide / switch
- Business modules only supply:
- Target queues
- Focus coordinates
- Card content
- Highlight / layer side effects
If future cable, satellite, or news cruise is added, do not copy a new set of main.js state variables. Instead reuse:
- cruise-sequencer.js
- callout-connector.js
- The business adapter pattern from bgp-cruise-adapter.js
Recommended Change Approach
For future Earth changes:
- First identify what you're changing:
- Three.js rendering layer
- HUD structure layer
- Layer state layer
- Panel content layer
- If involving layer buttons, connect to the unified state machine
- If involving visibility toggle, check whether tooltip / legend / info-card / lock all close together
- If involving panel layout, check structure before touching CSS
Current Boundary with the Console Frontend
The Earth frontend and the console frontend are not the same UI system:
- Console frontend: React + Ant Design workbench
- Earth frontend: native HUD + Three.js display under
public/earth
Therefore:
- Earth should not directly reuse Ant Table / AppLayout semantics
- The console should not copy Earth HUD animations and glass-layer design language
For console structure, see: