Skip to content

Track view

Garmin Wear OS Apple Watch
Status 🟡 ✅ ⏳
Code source/views/TrackView.mc, source/views/TrackPlot.mc, source/views/MapTrackView.mc, source/TripDelegate.mc, source/TripContext.mc (position buffer) wear/…/presentation/views/TrackView.kt, wear/…/presentation/TrackMapLayer.kt, core/…/TrackMap.kt, wear/…/presentation/TrackingScreen.kt, wear/…/recording/TripEngine.kt (position buffer) —

Verified against code: 2026-10-13

Purpose

Instrument screen 2. It shows the shape of the last 50 minutes of the track around the boat, north up, so the skipper sees tacks, drift and the course made good at a glance. Course and speed stay on screen as numbers; the plot is for shape. After a tack or jibe it shows the turn angle.

The screen sits between the Dashboard and the Environment view in the instrument pager (input.md). Colours and fonts come from the visual system.

Layout / behaviour

The screen is black, or shows a map with the setting Track map (Map background). Positions are fractions of screen width (x) and height (y); x 0.50 / y 0.50 is the centre. Nothing on this screen is a header: the top stays empty except for the turn angle.

Element Position Font / size Colour Content & format Constraints
Turn angle x 0.50, y 0.12, centred Header font Orange 0xFF5500 Signed whole degrees: +75° (clockwise turn), -66° (anticlockwise) Only while a turn is detected; otherwise nothing is drawn here
Track line Around the centre — Accent of the current vessel state; newest two segments orange Line through the buffered positions, oldest to newest Needs at least 2 buffered positions
Course vector From the centre — White Line in the COG direction, tip dot Only while COG is valid and at least 2 positions are buffered
Boat marker x 0.50, y 0.50 — White ring Hollow circle Only while at least 2 positions are buffered
no fix x 0.50, y 0.50, centred Label font (Garmin FONT_XTINY) Dim 0xAAAAAA no fix Instead of line, vector and marker while fewer than 2 positions are buffered
COG x 0.30, y 0.76, centred Small font (Garmin FONT_TINY) White Whole degrees with °, e.g. 215°; - without a valid COG Always shown
SOG x 0.70, y 0.76, centred Small font White One decimal plus unit: 5.3 kn; 0.0 kn without speed Always shown
Zoom-in badge x 0.86, y 0.24 Small font for the sign Disc sail blue 0x00AAFF, + in black Filled disc with + Radius width/22, at least 8 px
Zoom-out badge x 0.86, y 0.68 Small font for the sign Disc engine red 0xFF5555, - in black Filled disc with - Same radius
Scale bar Centre of the group at x 0.50, y 0.89 Label in FONT_XTINY White \|____\| then the distance label, e.g. 0.1nm Always shown, also without a fix

Plot

  • Projection. Flat (equirectangular) around the newest buffered position. Longitude differences are scaled by cos(latitude of that position). One degree of latitude is 60 nm.
  • Centre. The newest buffered position sits at the screen centre. It is up to 5 s old, not the live fix.
  • North up. The plot never rotates.
  • Line. Each pair of consecutive positions is one straight segment, pen 2 px, in the accent of the current vessel state (vessel-state.md). The whole line takes the current colour; it does not keep the colour each part was recorded in.
  • Turn highlight. While a turn angle is shown and at least 3 positions are buffered, the newest two segments are drawn orange 0xFF5500 with pen 3 px. These are always the newest two segments (about the last 10 s), not the part of the line where the turn began.
  • Course vector. A 2 px white line from the centre in the COG direction, 0.20 × width long, ending in a filled white dot of radius width/60 + 1.
  • Boat marker. A white disc of radius width/40 + 1 with a black disc of radius 2 px smaller inside, so a 2 px white ring. Drawn last, on top of the line and the vector.
  • Segments that run off the screen are clipped by the screen edge. Nothing marks the start of the track.

Position buffer

The plot reads a ring buffer of positions kept for the current track.

Property Value
Sampling One position every 5 s of the 1 Hz tick
Capacity 600 positions
History 600 × 5 s = 50 minutes; when full, the oldest position is overwritten
Empty at The start of every new track
Pause Not sampled while paused. The buffer is saved with the paused track and restored on resume (lifecycle.md)

This buffer is only for the plot. What gets recorded and uploaded is described in recording.md.

Garmin

A sample takes Activity.Info.currentLocation, or the last Position event when that is null. Any position is accepted, whatever its quality. Without a position the sample is skipped.

Wear OS

A sample takes the last location fix, and only if it is current (younger than 10 s). Otherwise the sample is skipped.

Turn angle

The turn angle is the course change the COG calculation reports: the signed difference between the mean of the first two and the mean of the last two of the last 30 one-second COG values, shown only when it is more than 30° either way. Positive is clockwise. The maths is in shared/calculations.md.

  • It appears as soon as the newest courses differ by more than 30° from the oldest in the 30 s window, and disappears when the window no longer spans the turn, so it stays for up to about 30 s.
  • It is cleared at once when COG becomes invalid (speed below 1 kn or no usable GPS course).
  • There is no text label (no "TRACK", no "Jibe"); only the angle.

Zoom

Seven zoom steps, 0 to 6. The default is step 3. The scale bar is 10 % of the screen width (rounded, at least 16 px), and the zoom step sets how far that bar is.

Step Scale bar label Bar distance Screen width spans about
0 (widest) 1nm 1.0 nm 10 nm
1 0.5nm 0.5 nm 5 nm
2 0.2nm 0.2 nm 2 nm
3 (default) 0.1nm 0.1 nm 1 nm
4 0.05nm 0.05 nm 0.5 nm
5 0.02nm 0.02 nm 0.2 nm
6 (closest) 0.01nm 0.01 nm 0.1 nm

Zoom in raises the step, zoom out lowers it. Both stop at the ends; nothing wraps.

Scale bar

  • Bar: 2 px white line, round(0.10 × width) px long (at least 16 px).
  • End ticks: 2 px white vertical lines at both ends, reaching round(0.015 × width) px (at least 3 px) above and below the bar.
  • Label: the zoom step's label in FONT_XTINY, white, left-aligned, round(0.02 × width) px (at least 4 px) right of the bar, vertically centred on it.
  • Bar, gap and label together are centred horizontally at y 0.89.

Garmin

Input On the Track view
START/STOP Zoom in
BACK Zoom out
Tap, right half, upper half (touch screens) Zoom in
Tap, right half, lower half Zoom out
Tap, left half Nothing (default handling)
UP / DOWN Previous / next instrument screen, as on every instrument screen

On the Track view START/STOP and BACK do not open the action menu or the vessel state menu. To reach them the user pages to another instrument screen (input.md, menus.md).

The zoom step is not kept: each time the Track view is shown it starts at step 3.

Wear OS

Input On the Track view
Tap, right half, upper half (on or near the + badge) Zoom in
Tap, right half, lower half (on or near the - badge) Zoom out
Tap anywhere else Toggle crown zoom mode
Crown, zoom mode off Pages the instruments, as on every instrument screen
Crown, zoom mode on Zooms one step per 40 px of rotary scroll; the direction that pages forward zooms in
Stem button 1 (KEYCODE_STEM_1, = Garmin BACK) Zoom out
Stem button 2 / 3 (= Garmin START) Zoom in
Swipe right Controls page, as on every instrument screen
  • Zoom mode is shown by a 2 px ring of radius r + 4 around both badges, in each badge's colour. It ends when the user taps outside the badges again or leaves the Track view.
  • While touch lock is on, taps do nothing; the first crown turn or a 2 s hold unlocks (input.md).
  • While an alert or auto-stats overlay is up, a stem press only closes the overlay.
  • The zoom step is kept when the user pages away and back, and across detours (picker, stats). It resets to step 3 only when the app's screen is created again.

Apple Watch

⏳ As decided in docs/apple_watch_port_plan.md: the crown pages the instruments, so zoom uses on-screen + / - buttons, or a tap on the map puts the crown into zoom mode until the next tap. Same zoom steps, plot and scale bar as above.

Map background

With the setting Track map on, a map is drawn behind the Track view instead of the black backdrop. The overlay above stays the same in content and position.

  • Map area: centred on the newest buffered position, north up, at the zoom step's scale, so the map and the plot match. The map moves with the 5 s position samples and with each zoom step, not every second.
  • Contrast: the track line gets a black outline 2 px wider than the line; the course vector, its tip dot and the boat marker get a 1 px black outline; the turn angle, COG, SOG and the scale bar sit on black rounded boxes; the zoom badges get a 1 px black ring. Without the map none of this is drawn.
  • Without a fix (fewer than 2 positions): the black Track view with no fix. If GPS is lost later, the map stays where it was.
  • No map for the area: whatever the watch's map shows there; SailEver adds no error text.
  • Not on the Pause view.

Garmin

  • Map: the map the firmware gives Connect IQ apps (WatchUi.MapView in preview mode, so it takes no buttons; all inputs stay as in Garmin). Apps can't list or choose the installed maps or a map theme: on a quatix 6 it is the general (topo) map, not the marine chart that Garmin's own activities offer. Nothing leaves the watch.
  • Scale: the firmware fits the requested area into the round screen with the area's diagonal on the screen's diameter, so it shows √2 times as far as asked for (measured on a quatix 6 at all seven zoom steps, 2026-11-01: map 1.27–1.52 × our scale, mean 1.39). The app asks for the plot's area divided by √2, so map, track line and scale bar share one scale. No API reports the map's actual scale.
  • Map area updates come from a 1 s timer and from the zoom keys, never from onUpdate (setting the area there makes the map flicker).
  • Devices: only those whose SDK device file has MapView (the (:maps) list in monkey.jungle: fēnix 5X / 5 Plus and later map models, epix 2, MARQ, D2 Delta / Mach, Descent Mk2 / Mk3, FR945 / 955 / 965 / 970, enduro 3). On every other device the setting isn't shown and the Track view stays black.
  • Setting: Track map toggle in the Settings menu, default off on every watch, quatix included (owner, 2026-11-01): a quatix shares its device file and app build with a fēnix or epix (quatix 6 = fenix6pro), and the app can't tell them apart at runtime. It takes effect the next time the Track view is shown.

Wear OS

  • Map: SailEver's tiles from tiles.sailever.com (base map and depth, maps.md), drawn by MapLibre with the watch style assets/track_map_style.json: water, depth bands, drying and no-depth areas, depth lines, land, coastline; no labels, no seamarks. Why: ADR 018.
  • Paired watches only: the map needs the pairing and the current privacy consent. An unpaired watch makes no tile request and its Track view is black.
  • Setting: Track map in the Settings menu, shown on a paired watch only, default on; ON / OFF, a tap switches it.
  • When: only while the Track view is the page on screen; in the low-power layout and in ambient mode there's no map. While it's shown the app holds an internet network request.
  • Offline: tiles already loaded stay in a 50 MB cache and keep showing; where nothing is cached the Track view stays black, with no error.
  • Scale: the camera zoom is computed so the scale bar's pixels cover its distance (TrackMap.cameraZoom); the map shows the zoom steps beyond the tiles' data (zoom 15) scaled up.

States and edge cases

Situation What the screen shows
Fewer than 2 buffered positions (first ~10 s of a track, or no position yet) no fix in the centre; COG - or a value, SOG, scale bar and badges as normal
Positions buffered but COG invalid (below 1 kn, or no GPS course) Line and boat marker, no course vector, COG -, no turn angle
GPS lost after positions were buffered The last line stays, centred on the last buffered position. no fix does not come back
Boat stationary for a long time All positions pile up in the centre; the line shrinks to a dot under the marker
Track longer than 50 min Only the newest 50 min are drawn
Vessel state changed The whole line switches to the new state's colour at the next redraw
Track wider than the screen at the current step Parts outside the screen are cut off; the user zooms out
Small screens (218 px) Scale bar keeps its 16 px minimum; badges keep their 8 px minimum radius

Known deviations

  • Garmin — zoom is not kept. Garmin resets the zoom step to 3 each time the Track view is shown, because TripDelegate.viewFor creates a new TrackView on every page switch. Wear OS keeps it. Garmin is behind (parity.md P2).
  • Garmin — code comment. TrackView.mc line 9 says zoom in is the LIGHT button. The code binds zoom in to START/STOP (TripDelegate.onSelect). The behaviour above is the code's.
  • Both — turn highlight. The orange highlight always covers the newest two segments, not the segments where the turn happened. With 5 s sampling these lag the start of the turn.