Repository navigation
GPS Track Recording
🇮🇱 עברית
NavAid can record the path you actually fly from your device's GPS and save it as a track overlay — a coloured line on the map, kept separately from your planned waypoint route. This is handy for debriefing a flight, comparing the flown line against the plan, or exporting the track to another tool.
The controls live in the toolbar footer (next to Terms / Privacy and the Simulator ✈ icon), so they're reachable no matter which section is open.
| Button | What it does |
|---|---|
| ⏺ Record | Starts recording your flown path from the device GPS. While recording the label changes to ⏹ Stop. |
| 📍 Location | Shows your live own-ship on the map without recording. While active the label changes to Hide. |
A small live readout next to the buttons shows, while recording: number of
points, elapsed time (MM:SS), and — when the fix provides them — ground speed
(kt) and GPS altitude (ft), e.g. 142 pts · 07:31 · 96 kt · 1250 ft.
Both buttons are disabled when the browser has no Geolocation support.
- Tap ⏺ Record. NavAid draws a live breadcrumb as you move and keeps your own-ship centred (it follows you — the follow lock in the control column turns that off and on).
- Fixes are filtered as they arrive: readings worse than ~100 m accuracy are dropped, and sub-10 m jitter steps are ignored.
- Tap ⏹ Stop. The track is simplified (redundant points removed
while keeping the flown line's shape) and saved to your
Saved routes library as a timestamped entry named
Record - YYYY-MM-DD HH:MM.
Saved tracks are stored as a track (a line), not a waypoint route, so a long flight doesn't bloat your saved-routes storage. In the Saved routes list a track row shows point count, distance in NM, and the date — and offers Show / Hide, Profile, GPX and JSON instead of the usual route Load / Save / Duplicate.
Recordings sit in their own frame, under Recordings, separate from the saved routes above them — they are two kinds of thing, and a recording is never loaded over the route on the map. A Show dropdown narrows the list to one kind or the other, remembered on the device, for a pilot who opens the library with a season of flights in it.
When you show a track — either from Saved routes → Show, or automatically right after a recording stops — NavAid now:
- shows only one recorded track at a time — showing one hides any other that was on the map;
- zooms / fits the map to the shown track so you can see the whole line;
- highlights it with an amber glow for 10 seconds, then reverts to the plain coloured line.
Tapping Show again on a track that's already shown re-zooms and re-glows it. Use Hide to remove it. The shown track survives a reload.
📍 Location just puts your live position on the map as an own-ship marker — nothing is recorded and nothing is saved. The map recenters on your first fix and, while following, keeps you in view. Tap Hide to turn it off. (If a recording is running, the recording drives the own-ship.) Starting Location or a recording removes an A4 / A3 print frame from the map, with a short message — pick the page again to print.
While the phone's own position is showing (Location or a recording), one short line sits under the top strip on a phone, or under the menubar on a computer:
🛰 ±6 m · 1 Hz · 14/27
- Accuracy and fix rate, on every platform. They come from the fixes themselves, before the app's accuracy filter, so a coarse fix shows as coarse instead of as silence.
- Satellites used / in view, in the Android app.
- A quality colour on the line's edge: green at 20 m or better, amber, red when coarser than the map accepts or stale. The numbers say it too, so colour is never the only signal.
- "Searching for satellites…" until the first fix; "no fix for N s" when fixes stop.
- BT in place of the satellite icon while a Bluetooth GPS delivers.
It always reads left to right, in Hebrew too, and is not shown for the simulator, which is not a
GPS. Gist switch: featureGpsStatus (default on).
Tap it for the details — at most seven rows, so it fits a phone without scrolling:
| Row | Shows |
|---|---|
| Accuracy |
±6 m alt ±9 m
|
| Last fix |
now 1.0 Hz first fix 12.3 s
|
| Source (Bluetooth GPS only) | the device's name, satellites used |
| Satellites |
18 of 31 used 34 dB-Hz
|
| Systems |
GPS 7/11 Galileo 5/8 GLONASS 4/7 BeiDou 2/5
|
| Altitude from |
GPS, or Barometer + QNH 29.91″ — see Settings
|
| Barometer |
28.64″ 1,240 ft +600 fpm — pressure, pressure altitude (ISA), vertical speed |
Each value is its own small pill, so a wrapped row never strands a separator.
No satellites? Browsers and iPhones do not expose satellite data, and the details say so. In the Android app, satellites are reported only while the phone's GPS receiver runs, and indoors or on a Wi-Fi or cell fix it may not; the details then say which it is — waiting for satellite data, receiver on, no satellites in view yet, precise location not granted (with where to turn it on), or this phone does not report satellite data.
The barometer is the phone's own pressure sensor (Android app, featureBarometer, on). In an
unpressurised aircraft it reads cabin pressure, which is close to static. Its pressure follows
Settings → Pressure unit; with Altitude from → Barometer + QNH it drives the in-flight
altitude.
Inside the Android app:
- recording holds a screen wake-lock so the phone doesn't sleep mid-track, and
- runs an Android foreground service (with a persistent notification) via the background-geolocation plugin, so fixes keep flowing while the phone is locked.
Device extras, each with its own gist switch:
| Default | ||
|---|---|---|
Keep the screen on (featureKeepAwake) |
on | While a position shows. Browsers use the web Wake Lock. |
Vibrate with every alert (featureHaptics) |
on | A warning vibration with each in-flight alert, for a phone on the kneeboard under a headset. |
Screen brightness (featureBrightness) |
on | Settings → Screen brightness — see Toolbar. |
Barometer (featureBarometer) |
on | Pressure, pressure altitude and vertical speed in the GPS details. |
Battery warning (featureBatteryWarn) |
off | In flight and not charging: a warning and a vibration at 20 % and 10 %. |
Full screen in flight (featureFullscreenFlight) |
off | Hides the status bar while a position shows. |
ADS-B receiver (featureGdl90) |
off | Traffic from a cockpit receiver (Stratux, SkyEcho, Sentry) over Wi-Fi, GDL90 on UDP 4000. Its targets join the traffic layer, and win over the internet feed for the same aircraft; a target unheard for 20 s is dropped. |
Bluetooth GPS (featureBleGps) |
off | Settings → Connect Bluetooth GPS — see Toolbar. |
The ADS-B receiver and Bluetooth GPS paths are tested with synthetic data, not yet with real hardware.
In a plain browser / PWA there's no background plugin, so recording falls back to the standard geolocation watch, which the browser pauses when the tab is hidden or the screen locks. The wake-lock is re-acquired automatically when you return to the page.
While a track is recording, or Location is on, or a simulator is connected, NavAid watches your position against the plan and raises alerts. They arrive as ordinary device notifications, so anything already mirroring your phone shows them — a paired smartwatch or fitness band (for example Garmin's Smart Notifications, or an Apple Watch), a car head unit, or the phone's own lock screen. There is no NavAid watch app, and none is needed.
On the screen too. While the app is in view, each alert also shows its text in a bubble at the
bottom — Next leg: BAZRA 095° 2500 ft — and in the Android app the phone vibrates
(featureHaptics). The notification still goes out, because it is what the lock screen and a
watch show.
| Alert | When |
|---|---|
| Next leg | About two minutes out from the next waypoint (half that on a short leg). Names the point and the leg after it — altitude, heading and time — so it doubles as prep for the turn. |
| TOP | Overhead the waypoint, the moment of the CVFR "TOP" radio call. If that waypoint changes frequency, the alert carries the station and frequency too. |
| Altitude | Once you leave the current leg's planned altitude by more than 100 ft (altToleranceFt). Fires once per excursion, again only after you return inside tolerance — and at most twice on any one leg (altMaxAlertsPerLeg), so a leg flown slightly off plan reports the fact instead of nagging the whole way. |
| Off course | Track-angle error past 10°, on its own two-minute timer. Before the leg's midpoint it gives the classic double-the-error intercept; past it, the correction direct to the waypoint. Stays quiet for 30 s after a TOP, while the turn onto the new leg settles. |
| Off route | You are outside every leg (see below) for 15 s. Names the nearest waypoint still ahead and the course to it. |
| Destination hours | The planned arrival falls outside the destination's published operating hours (the same AIP hours the inspector shows). Once per flight. |
| Last light | The planned arrival is after, or within 15 minutes of, last light at the destination (lastLightMarginMin) — said while turning back is still by day. A caution: night VFR is not always forbidden. Once per flight. |
All of them come from the plan, not from live GPS speed: flying faster or slower than planned still gets the alert relative to what you filed.
Every threshold above is tunable — tolerance, lead time, capture radius, track-error angle and the timers behind them — along with the fix-quality filters (worst usable accuracy, the jitter step that counts as movement, and how old a fix may be). See Tuning Panel.
Alerts are moments, not messages: "next leg" matters for the minute before the turn and is noise
afterwards. Each one withdraws itself after 15 seconds (alertNotifyTtlSec), so an hour's flight
does not leave an hour of stale notifications to clear off the phone. Set it to 0 to keep them until
dismissed. (The app's default is 60 s; the gist sets 15.) Withdrawing an alert on the phone also
removes it from a paired watch.
In the app (APK) the alerts are ordinary Android notifications, so a paired watch (Wear OS, e.g. a
Pixel Watch) shows them and buzzes. They go to their own Flight alerts channel at high importance —
in Android's settings it can be tuned or silenced apart from anything else — under NavAid's own aircraft
icon (alertIconColor; needs an APK built with it, older ones show Android's default icon), grouped so
a burst of alerts stacks. The spoken alert plays on the phone, not the watch.
A leg is the overlap of a 90° cone from each of its ends — a diamond, pinched to a point at each waypoint and widest halfway along. Your position is matched against those cones on every fix, so rejoining a route mid-way, flying it backwards or skipping a leg all track correctly, and the current leg is kept while it still contains you rather than flipping between two that overlap near a shared waypoint.
Outside every cone, NavAid says so rather than guessing: the other four alerts go quiet — an altitude "deviation" from a leg you are not flying is noise — and the off route alert gives you a way back. It names the nearest waypoint still ahead on the route, never one you have already overflown, preferring one within 45° of where the nose is pointing and otherwise telling you which way to turn. It repeats only when that course has genuinely moved.
The Voice alerts speaker in the map's control column (The map) reads the alerts aloud. Off by default — it talks in the cockpit, so it is opt-in.
In the Android app this uses the device's own text-to-speech, which keeps working with the phone locked and the app in the background. In a plain browser it falls back to the browser's speech, which is fine for testing but stops when the tab goes to the background — so treat browser voice as a way to try the feature, not as something to fly with.
It speaks the interface language, falling back to English wording if the device has no voice installed for it — a missing voice never means a missed alert. Headings and frequencies are read digit by digit ("zero zero four", "one one eight decimal four"), because a heading misheard as a number is a heading flown wrong.
Beside the GPS buttons, the footer shows ground speed, altitude and magnetic
heading from the current fix — 90 kt · 800 ft · 045° — the same three whether
the position comes from the device GPS or a connected simulator. Its text size is
tunable (gpsReadoutFontPx) for a kneeboard at arm's length.
It always fits on one line. The toolbar is a fixed-width panel, so a line too long for it
is not wrapped but cut — and what it loses is the tail. Instead the readout measures itself and
drops the least useful field until it fits: the subscale setting first (it is a setting, and
the airfield panel carries it), then the point count, then the elapsed clock. Ground speed,
altitude and heading are the instrument and are never dropped. While recording, a wide screen
shows all six — 128 pts · 12:34 · 104 kt · 2450 ft · 29.83″ · 045°.
A GPS gives you a course, derived from movement, so it says nothing useful while you sit on the
apron — and nothing at all below a walking pace. Under 3 kt (compassMaxKt) NavAid falls back to
the device compass, so the readout and the heading-up map still point where the nose points.
A compass heading is marked with a leading tilde — ~045° against a GPS course's 045° —
because it is where the phone points, not where the aircraft is going. The degree sign stays
on either way, so the number always reads as a heading. (It used to be a trailing m, for
magnetic, which beside an altitude in feet read as metres.)
It only accepts an absolute heading — a compass reading referenced to true north, not a relative
one that drifts — so a device without a magnetometer simply keeps the GPS course. On iOS the browser
asks permission for motion sensors the first time, from a tap. The fallback can be switched off
entirely (compassFallback).
The orientation control in the bottom-right column
switches between north up and heading up. Heading up rotates the chart so your track is
always at the top; small heading changes are ignored (headingUpMinDeltaDeg) so the map does not
twitch on every fix. The number under the button's needle is your heading magnetic, like the
data strip; the needle itself is true — along your track when north up, at north when heading up.
While a track is recording, your location is shown, or a simulator is connected, the route layout is locked: waypoints, kites, notes and comm callouts do not move. The plan the alerts measure against is not something to nudge in flight. See Inspector.
The own-ship draws a line out along its current track, marked at 2, 5 and
10 nm and — once there is a groundspeed to derive them from — at 2 and
5 min. The distance marks are always there; the time marks appear only while you
are moving. The magnetic heading is in the footer beside speed and altitude, not at
the end of the line (liveHeadingEndLabel puts it back there). Same line for a real
fix and for a simulator feed. A mark that would fall on the aircraft symbol itself — on the
ground "2 min" is a few metres ahead — is not drawn.
Between fixes the aircraft glides. The phone gives about one fix a second; at 500 km/h that is
~140 m, and the symbol (and the map, while following) jumped by it. Between fixes it is now drawn
where the aircraft is by now — the last fix carried along its track at the ground speed — and the
next fix corrects it. The redraw rate follows the speed and the zoom (a ~2 px step): up to
gpsGlideMaxHz (10) a second when fast and close, once per fix when slow or zoomed out, off below
gpsGlideMinKt (30 kt). A late fix holds it after 2.5 s instead of flying on. gpsGlide turns it off.
In a turn the line curves. A straight projection is a lie the moment you bank: it points
where you were going, not where you will be. Above livePredictorTurnMinDegSec (1 °/s) and
livePredictorTurnMinKt (10 kt) NavAid measures the turn rate and draws the arc you are
actually flying. In a turn the line becomes a trend vector, as on a G1000: only
livePredictorTurnMaxArcSec (60 s) of flying ahead, curving through at most
livePredictorTurnMaxArcDeg (60°) and then straight to the end of the minute, with a
1 min tick at its end and no 10 NM tail — a half-mile arc under a 10 NM line hides
behind the aircraft symbol. Rolled out, the full straight line and its marks come back. A rate beyond
livePredictorTurnMaxDegSec (4 °/s) is treated as noise rather than a turn; the measured rate
is held for livePredictorTurnHoldSec (6 s) so the line does not snap straight between fixes,
and livePredictorTurnSmoothing damps the rest.
Gentle turns count too. The rate is a least-squares slope over the last few fixes, and each
slope comes with its own standard error. A turn below 1 °/s — a lazy correction, a wide
circuit — is still drawn when it stands out from the GPS scatter by
livePredictorTurnSignificance (3) standard errors, down to livePredictorTurnGentleDegSec
(0.25 °/s). When the line starts to bend it starts from the measured rate, not from zero, so
smoothing does not delay the roll-in.
With the phone's gyro. GPS only sees a turn after it has happened. On a phone, while
Location is on, NavAid also listens to the gyro, which feels the roll-in and the roll-out the
moment they happen, as an AHRS does in a glass cockpit. The gyro is fused, not trusted: it
supplies only the change since the GPS window, so a steady turn is still measured by GPS and
a constant gyro drift cancels out. It first learns how the gyro compares with GPS over four
clear turns — which also takes care of how the phone sits in its mount and the bank angle —
and does nothing until then. It works with the phone flat, upright or on a kneeboard. Not used
with a simulator feed. Turn it off with livePredictorGyro. On iOS the motion permission is
asked for when Location starts.
While Location or Record is on, Follow me shares a live link with someone on the ground. See Follow me.
Extra layers → Traffic → Show live traffic draws the other aeroplanes being heard on ADS-B: a top-down aircraft, nose along its track, with its callsign and altitude in hundreds of feet beside it. Tap one for the Inspector — altitude, ground speed, track, aircraft type, squawk and position.
It asks around your position when you have one — that is the traffic that matters — and otherwise around the middle of the map, so it works while planning too. Panning somewhere else asks about there. Your own aircraft is filtered out of the feed (a second aeroplane drawn on top of yourself reads as traffic in your lap), and an aeroplane that stops being heard takes its inspector panel with it rather than leaving a stale altitude on screen looking current.
The switch is remembered per device and syncs like the other layer toggles.
The public ADS-B aggregators serve data to anyone and CORS headers to nobody: adsb.lol and adsb.fi answer a command-line request and fail in a browser, airplanes.live and adsb.one answer 403, OpenSky allows only its own origin, and the public CORS proxies either time out or rate-limit long before an 8-second poll. A static site has nothing to call.
The APK is not a browser. Capacitor's native HTTP makes the request in Java, where the
same-origin rule does not apply, so the app calls the feed directly — no proxy, nothing
hosted. In a browser the Traffic box is still there but dimmed, with the reason on it:
a control that vanishes between the phone and the desktop makes you wonder what else moved.
Only featureLiveTraffic removes it.
featureLiveTraffic in the tuning gist decides whether the feature exists. It is on in
the live app — the Traffic box is there, dimmed in a browser and live in the APK.
| Key | What it does |
|---|---|
trafficApiUrl |
Where to ask. {lat} / {lon} / {dist} are filled in; a URL without them gets them as query parameters. Default: adsb.lol. |
trafficRadiusNm |
How far around you to ask for (40 nm). |
trafficRefreshSec |
How often (8 s). |
trafficFailsBeforeWarn |
Failed requests in a row before saying so (3). |
trafficIconPx |
Aircraft size (22 px). |
trafficArrowColor / trafficLabelColor
|
Aircraft and label colour. Magenta, not red: red on an aviation display means resolve it now, and this is information. |
A single dropped request says nothing and leaves what is on the map alone. Only after several failures in a row, and with nothing on the map to look at, does it say Live traffic unavailable — with the reason in brackets.
Profile opens the flight underneath the row: altitude flown and ground speed against distance, with the terrain beneath them. It is drawn from the saved fixes alone — no fetch — so it answers on the ground and in flight mode, and without loading anything over the route you are working on.
- Altitude is the height the receiver reported, put through the same geoid correction as the live readout, so the strip agrees with what the altimeter showed rather than reading ~59 ft high. A fix that reported no height leaves a gap rather than a line drawn across ground that was never measured; a recording with no height at all says so.
-
Ground speed is derived between consecutive fixes, because a recording carries no speed
of its own — the exported GPX does not either. One fix landing a few metres off becomes a
spike of tens of knots, so the trace is averaged over a short run (
trackProfileSmoothFixes). - Nothing is dashed and there is no TOC or safe-altitude line: a recording has no plan to be measured against, and marking one would invent it.
- A key names each line, drawn inside the picture so the export carries it too.
- ⤓ PNG saves the strip as an image — the browser's download in a browser, the system share sheet in the APK — redrawn at export size with the name and figures across the top.
- ⤢ opens it larger, over the map: 150px is enough to see the shape of a flight and not enough to read it. The larger view shows whatever the panel is showing.
The totals read NM · time · max ft · flown.
Compare with — above the strip — draws a saved route underneath the flown line, dashed and in its own colour. That is the debrief: where the climb actually finished, where the cruise sat low, where the descent began early.
The list offers the route on the map first when there is one, then every saved route in the library. A saved plan is read the way the profile itself is read — without loading it — so the route you are working on is never replaced to answer a question about a past flight.
Both lines are drawn against absolute distance from the start, on one scale. A flight that turned back early therefore looks short against its plan rather than being stretched to agree with it.
Each saved track has a GPX button in the Saved routes list that downloads it
as a GPX <trk> (track), the natural format for a flown path — with elevation
and timestamps where recorded (in metres, as the GPX spec requires). A JSON button saves
the library entry itself, which imports back. On a phone both go to the share sheet rather
than a download. See Print and Export.
- Toolbar — where the GPS buttons and Saved routes live.
- Offline and PWA — installing the app and the Android APK.
- Settings and Persistence — what's stored on device.
For pilots
- Quick Start
- Video tutorials · סרטונים
- Features
- The Map
- Auto zoom
- Toolbar
- Phone layout
- Safety notice
- Route and Legs
- Waypoints and Notes
- Inspector
- AI Assistant
- User Guide
- Frequency Changes
- VOR and Radial/DME
- Map Layers
- Bearing dial
- Extra Layers
- Airport charts
- Flight Plan
- Route check
- Flight planning form
- Submit a flight plan
- Fuel
- Print and Export
- Simulator Connect
- Google Earth
- GPS Track Recording
- Comm failure
- Follow me
- Bilingual UI
- Offline and PWA
- Settings and Persistence
- Keyboard and Touch
- FAQ and Troubleshooting
For developers
- Architecture
- Directory Structure
- Tuning Panel
- Hidden Tools
- LocalStorage Schema
- Nav-waypoints dataset
- Airfields dataset
- Service Worker
- Deployment
- Contributing
- Changelog
🇮🇱 עברית
לטייסים
- התחלה מהירה
- תכונות
- עוזר AI
- מדריך למשתמש
- זום אוטומטי
- שינויי תדר
- VOR ו-Radial/DME
- סרגל הכלים
- פריסת הטלפון
- הודעת הבטיחות
- שכבות מפה
- שכבות נוספות
- תוכנית טיסה
- בדיקת מסלול
- טופס תכנון טיסה
- הגשת תוכנית טיסה
- הדפסה וייצוא
- חיבור סימולטור
- Google Earth
- הקלטת מסלול GPS
- תקלת קשר
- עקבו אחריי
- ממשק דו-לשוני
- לא מקוון ו-PWA
- הגדרות ושמירה
- מקלדת ומגע
- שאלות נפוצות ופתרון תקלות
למפתחים
🌐 Live 🧪 Staging 📦 Repo 💡 Ideas / bugs