- Flat Earth overview for satellite monitoring: satellites, ground tracks (past/future), coverage/visibility shapes, ground stations, optional day/night terminator.
- Operator overview, not a GIS/map app; aims for correctness, deterministic behaviour, and smooth performance on phones and WASM with minimal UI.
- Reusable
EarthOverviewItemwith correct seam handling, subdued background, and smooth performance on desktop/phone/WASM. - The bundled Qt/QML application is for testing & development only; not a reference UI.
- Single renderer: one custom C++
QQuickItemdraws background and overlays via the GPU scenegraph (no Canvas/runtime SVG, no per-satellite QML items). - Flat equirectangular projection: latitude → Y, longitude → X; polar distortion is acceptable.
- Viewer owns projection; data is provided in WGS84/ECEF. Projection, centring, and seam handling live in the view.
- Demo application derives data inputs via NATS (subscription & KV), but the view is transport-agnostic.
- Single bundled RGBA PNG, equirectangular 2:1, desaturated/low contrast; land mid-grey and partially transparent, ocean more transparent, no labels/borders.
- Embedded via
.qrc, loaded once, reused for the lifetime of the view.
- Background texture is wrapped (not split): same texture drawn multiple times horizontally.
- Horizontal offset derived from
centerLongitude; at least two copies drawn for coverage. - Foreground geometry is seam-split; background is seam-wrapped.
- Same
QQuickItemusingQSGGeometryNodes:- Satellites → points or small quads
- Tracks → line strips
- Coverage/visibility → polygon outlines or filled fans
- Ground stations → points + optional footprint outlines
- Geometry is built in C++ with shared projection/seam logic.
- Longitude wraps at ±180°; any polyline or polygon crossing the seam must be split.
- Rule: if
abs(lon[i] - lon[i-1]) > 180°, treat as a seam crossing and draw resulting segments separately. - Applies to satellite tracks, coverage polygons, and the terminator line.
EarthView consumes two payload types (regardless of transport):
-
Satellites: list of maps
- Required:
Lat,Lon(degrees; lat in [-90, 90], lon in [-180, 180]); optionallyID/id. - Optional:
Alt/alt(km),LatPast/LonPast,LatFuture/LonFuture(degrees) for short past/future track segments. - Field names are case-tolerant (
lat/Lat,lon/Lon, etc.); entries with non-finite coords are ignored. - Payload is handed directly to
EarthView::setSatellites(const QVariantList &); extra fields are preserved in the hover signal.
- Required:
-
Ground stations: list of maps
- Position:
lat/Lat,lon/Lon(degrees). If absent but a mask is present, the centroid of the mask is used. - Footprint/mask (optional): array under
mask/Mask,boundary/footprint/points; each point is[lat, lon]or{lat, lon}. - Optional radius:
radius_km/RadiusKm/radiusKm/radius(km). - Optional ID:
id/ID(otherwise empty). - Payload is handed to
EarthView::setGroundStations(const QVariantList &).
- Position:
All geometry is expected in WGS84 lat/lon; EarthView handles projection, seam-splitting, and rendering. Invalid or out-of-range entries are skipped.
- Messages carry truth data only: time reference; lat/lon/alt (or ECEF); optional sampled past/future track points; optional coverage parameters; status/health.
- Altitude does not affect map position but does affect coverage & visibility.
- KV stores semi-static definitions: lat/lon/alt, masks, optionally precomputed footprint polygons (e.g., 72 points = 5deg).
- Geometry published in NATS is WGS84 lat/lon, never screen-space.
Example content (as JSON for readability)
{
"id": "gnd_london",
"name": "London",
"lat": 51.5074,
"lon": -0.1278,
"alt_m": 500,
"avg_sat_alt_km": 763.8349771950732,
"radius_km": 2976.918665134186,
"boundary": [
{"lat": 78.3, "lon": -0.1},
{"lat": 78.2, "lon": 4.8},
…
{"lat": 78.2, "lon": -5.1}
],
"computed_at": 1.736268e+09
}Renderer should use only the boundary points for footprint rendering.
- Per-user/device, not shared:
centerLongitude, zoom (if supported), aspect-ratio dependent behaviour, selection state, declutter level. - Changing
centerLongitudeshifts the background texture and rebuilds foreground geometry; it does not change NATS data.
- Landscape is primary: tablets/laptops assumed landscape, full Earth overview.
- Portrait is constrained: Earth shown as a horizontal band (letterboxed), fewer overlays, optional horizontal scrollbar for longitude recentering.
- Aspect ratio drives behaviour, not device type.
- Not a map engine/Qt Location/Cesium, not SVG- or Canvas-based, not free-pan/zoom GIS.
- Goal is very lightweight rendering & smooth performance on low-end devices e.g. in WASM.
- Coupling to NATS messages/KV is at application level
- All heavy rendering stays in one C++
QQuickItem.
This project is distributed under the Mozilla Public License 2.0. See LICENSE.txt for details.
