Files
planet/docs/technical/en/earth-frontend-context.md
linkong e1984c7a35 release: bump version to 0.49.0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 17:42:27 +08:00

12 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 renders supercomputer and GPU-cluster markers. The backend renders compute centers only from source-provided coordinates or compute_center_locations dimension-table coordinates during startup; manual candidate collection can query ROR and Nominatim/OpenStreetMap, and the layer keeps the ? badge for unconfirmed positions while the details card shows precision, confidence, source notes, and verification date.
  • 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)

The compute-center layer row has a notification badge for GeoJSON unresolved records. The badge means "no trustworthy coordinates, cannot render on the globe"; it is different from the ? marker drawn on already positioned but unconfirmed compute centers. Clicking the badge opens a fixed info card beside the layer panel. Row-level 采集 fetches candidates only. Header-level 一键采用 processes the queue top-to-bottom, saves the highest-confidence valid candidate, removes successful rows, renumbers the list, and dispatches earth:compute-center-unresolved-count-change so the badge updates immediately. When the batch ends, earth:compute-center-location-saved refreshes the real layer.

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.

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 indicator
  • enabled: layer is active
  • hidden: layer is hidden
  • error: 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.

Terrain should not block startup when it is not the restored visible layer. After deferred layer visibility settings are applied, controls.js schedules scheduleTerrainPrefetch() only when HD texture is enabled, terrain is not ready, and no prefetch is already running. The prefetch uses setTimeout plus requestIdleCallback so cloud, HD texture, and startup layer work keep first-screen priority.

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

  1. terrain.js creates a sphere geometry with enough segments
  2. On load, fetches Terrarium-format elevation tiles from the backend
  3. Decodes R/G/B into elevation values
  4. Displaces vertex positions radially based on elevation
  5. Applies a vertex alpha that fades terrain edges at coastlines
  6. 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.

Terrain tile fetching is batched. terrain.js deduplicates required Terrarium tile keys and sends chunks sized by TERRAIN_CONFIG.batchRequestSize to /api/v1/visualization/terrain/terrarium/batch. The backend proxies S3 Terrarium tiles with an in-memory LRU cache, per-batch deduplication, and bounded concurrency. The single tile endpoint remains for fallback paths and browser cache semantics.

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:

  1. Who is responsible for height
  2. Who is responsible for scrolling
  3. 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:

For future Earth changes:

  1. First identify what you're changing:
    • Three.js rendering layer
    • HUD structure layer
    • Layer state layer
    • Panel content layer
  2. If involving layer buttons, connect to the unified state machine
  3. If involving visibility toggle, check whether tooltip / legend / info-card / lock all close together
  4. 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: