--- /dev/null
+51342 3 sat 17:14:36 38°09.3533'N 104°48.5326'W 1668m 38.155888 -104.808877 1668
+52542 3 sat 17:14:48 38°09.3491'N 104°48.5294'W 1670m 38.155818 -104.808823 1670
+52642 4 sat 17:14:49 38°09.3481'N 104°48.5234'W 1670m 38.155801 -104.808723 1670
+52742 6 sat 17:14:50 38°09.4074'N 104°48.5546'W 1671m 38.156790 -104.809243 1671
+52842 4 sat 17:14:51 38°09.4232'N 104°48.5496'W 1671m 38.157053 -104.809160 1671
+52943 6 sat 17:14:52 38°09.4350'N 104°48.5304'W 1671m 38.157250 -104.808840 1671
+53043 6 sat 17:14:53 38°09.4349'N 104°48.5257'W 1672m 38.157248 -104.808761 1672
+53143 6 sat 17:14:54 38°09.4367'N 104°48.5240'W 1672m 38.157278 -104.808733 1672
+53243 6 sat 17:14:55 38°09.4324'N 104°48.5165'W 1702m 38.157207 -104.808608 1702
+53343 6 sat 17:14:56 38°09.4300'N 104°48.5200'W 1705m 38.157167 -104.808667 1705
+53442 6 sat 17:14:57 38°09.4248'N 104°48.5180'W 1738m 38.157080 -104.808633 1738
+53543 6 sat 17:14:58 38°09.4212'N 104°48.5249'W 1744m 38.157020 -104.808748 1744
+53643 6 sat 17:14:59 38°09.4160'N 104°48.5246'W 1780m 38.156933 -104.808743 1780
+53743 5 sat 17:15:00 38°09.4125'N 104°48.5301'W 1786m 38.156875 -104.808835 1786
+53842 5 sat 17:15:01 38°09.4038'N 104°48.5331'W 1825m 38.156730 -104.808885 1825
+53943 6 sat 17:15:02 38°09.4004'N 104°48.5382'W 1832m 38.156673 -104.808970 1832
+54043 6 sat 17:15:03 38°09.3985'N 104°48.5445'W 1840m 38.156641 -104.809075 1840
+54143 6 sat 17:15:04 38°09.3974'N 104°48.5522'W 1849m 38.156623 -104.809203 1849
+54243 6 sat 17:15:05 38°09.3900'N 104°48.5526'W 1891m 38.156500 -104.809210 1891
+54343 6 sat 17:15:06 38°09.3880'N 104°48.5571'W 1902m 38.156467 -104.809285 1902
+54443 6 sat 17:15:07 38°09.3822'N 104°48.5599'W 1947m 38.156370 -104.809331 1947
+54542 6 sat 17:15:08 38°09.3777'N 104°48.5716'W 1962m 38.156295 -104.809527 1962
+54643 6 sat 17:15:09 38°09.3705'N 104°48.5774'W 2007m 38.156175 -104.809623 2007
+54743 6 sat 17:15:10 38°09.3663'N 104°48.5843'W 2022m 38.156105 -104.809738 2022
+54844 6 sat 17:15:11 38°09.3622'N 104°48.5958'W 2038m 38.156037 -104.809930 2038
+54942 6 sat 17:15:12 38°09.3581'N 104°48.6044'W 2053m 38.155968 -104.810073 2053
+55043 6 sat 17:15:13 38°09.3547'N 104°48.6090'W 2068m 38.155911 -104.810150 2068
+55143 4 sat 17:15:14 38°09.3513'N 104°48.6157'W 2081m 38.155855 -104.810261 2081
+55242 4 sat 17:15:15 38°09.3474'N 104°48.6228'W 2095m 38.155790 -104.810380 2095
+55343 4 sat 17:15:16 38°09.3436'N 104°48.6311'W 2109m 38.155727 -104.810518 2109
+55443 4 sat 17:15:17 38°09.3403'N 104°48.6366'W 2121m 38.155671 -104.810610 2121
+55543 6 sat 17:15:18 38°09.3322'N 104°48.6433'W 2165m 38.155537 -104.810721 2165
+55643 5 sat 17:15:19 38°09.3251'N 104°48.6481'W 2198m 38.155418 -104.810801 2198
+55743 6 sat 17:15:20 38°09.3177'N 104°48.6523'W 2237m 38.155295 -104.810871 2237
+55844 6 sat 17:15:21 38°09.3078'N 104°48.6575'W 2294m 38.155130 -104.810958 2294
+55943 6 sat 17:15:22 38°09.3044'N 104°48.6605'W 2317m 38.155073 -104.811008 2317
+56043 6 sat 17:15:23 38°09.3036'N 104°48.6609'W 2325m 38.155060 -104.811015 2325
+56143 6 sat 17:15:24 38°09.3026'N 104°48.6634'W 2327m 38.155043 -104.811057 2327
+56243 6 sat 17:15:25 38°09.3001'N 104°48.6665'W 2329m 38.155001 -104.811108 2329
+56343 6 sat 17:15:26 38°09.2958'N 104°48.6733'W 2340m 38.154930 -104.811221 2340
+56443 6 sat 17:15:27 38°09.2909'N 104°48.6814'W 2348m 38.154848 -104.811357 2348
+56543 6 sat 17:15:28 38°09.2865'N 104°48.6918'W 2361m 38.154775 -104.811530 2361
+56643 6 sat 17:15:29 38°09.2833'N 104°48.7038'W 2372m 38.154721 -104.811730 2372
+56743 6 sat 17:15:30 38°09.2802'N 104°48.7155'W 2385m 38.154670 -104.811925 2385
+56843 6 sat 17:15:31 38°09.2764'N 104°48.7264'W 2398m 38.154607 -104.812107 2398
+56942 6 sat 17:15:32 38°09.2736'N 104°48.7371'W 2410m 38.154560 -104.812285 2410
+57043 5 sat 17:15:33 38°09.2713'N 104°48.7470'W 2420m 38.154521 -104.812450 2420
+57142 5 sat 17:15:34 38°09.2676'N 104°48.7574'W 2433m 38.154460 -104.812623 2433
+57243 5 sat 17:15:35 38°09.2644'N 104°48.7674'W 2446m 38.154407 -104.812790 2446
+57343 5 sat 17:15:36 38°09.2625'N 104°48.7782'W 2458m 38.154375 -104.812970 2458
+57443 5 sat 17:15:37 38°09.2601'N 104°48.7881'W 2470m 38.154335 -104.813135 2470
+57542 5 sat 17:15:38 38°09.2578'N 104°48.7971'W 2482m 38.154297 -104.813285 2482
+57642 4 sat 17:15:39 38°09.2548'N 104°48.8058'W 2492m 38.154247 -104.813430 2492
+57742 4 sat 17:15:40 38°09.2514'N 104°48.8148'W 2502m 38.154190 -104.813580 2502
+57842 4 sat 17:15:41 38°09.2481'N 104°48.8240'W 2512m 38.154135 -104.813733 2512
+57943 4 sat 17:15:42 38°09.2452'N 104°48.8333'W 2520m 38.154087 -104.813888 2520
+58043 4 sat 17:15:43 38°09.2424'N 104°48.8421'W 2529m 38.154040 -104.814035 2529
+58142 4 sat 17:15:44 38°09.2396'N 104°48.8514'W 2537m 38.153993 -104.814190 2537
+58243 4 sat 17:15:45 38°09.2376'N 104°48.8602'W 2544m 38.153960 -104.814337 2544
+58343 4 sat 17:15:46 38°09.2350'N 104°48.8690'W 2551m 38.153917 -104.814483 2551
+58442 4 sat 17:15:47 38°09.2330'N 104°48.8774'W 2556m 38.153883 -104.814623 2556
+58542 4 sat 17:15:48 38°09.2314'N 104°48.8863'W 2561m 38.153857 -104.814771 2561
+58643 6 sat 17:15:49 38°09.2301'N 104°48.8933'W 2567m 38.153835 -104.814888 2567
+58743 6 sat 17:15:50 38°09.2298'N 104°48.9002'W 2572m 38.153830 -104.815003 2572
+58843 6 sat 17:15:51 38°09.2309'N 104°48.9072'W 2573m 38.153848 -104.815120 2573
+58943 6 sat 17:15:52 38°09.2329'N 104°48.9147'W 2573m 38.153881 -104.815245 2573
+59043 6 sat 17:15:53 38°09.2349'N 104°48.9218'W 2577m 38.153915 -104.815363 2577
+59143 6 sat 17:15:54 38°09.2351'N 104°48.9275'W 2579m 38.153918 -104.815458 2579
+59243 6 sat 17:15:55 38°09.2339'N 104°48.9348'W 2581m 38.153898 -104.815580 2581
+59343 6 sat 17:15:56 38°09.2318'N 104°48.9401'W 2581m 38.153863 -104.815668 2581
+59442 6 sat 17:15:57 38°09.2320'N 104°48.9454'W 2580m 38.153867 -104.815757 2580
+59543 6 sat 17:15:58 38°09.2398'N 104°48.9368'W 2532m 38.153997 -104.815613 2532
+59643 6 sat 17:15:59 38°09.2417'N 104°48.9401'W 2528m 38.154028 -104.815668 2528
+59742 6 sat 17:16:00 38°09.2457'N 104°48.9433'W 2515m 38.154095 -104.815721 2515
+59843 6 sat 17:16:01 38°09.2488'N 104°48.9480'W 2506m 38.154147 -104.815800 2506
+59943 6 sat 17:16:02 38°09.2521'N 104°48.9526'W 2491m 38.154201 -104.815877 2491
+60043 6 sat 17:16:03 38°09.2532'N 104°48.9577'W 2478m 38.154220 -104.815961 2478
+60143 6 sat 17:16:04 38°09.2549'N 104°48.9620'W 2463m 38.154248 -104.816033 2463
+60242 6 sat 17:16:05 38°09.2569'N 104°48.9669'W 2448m 38.154281 -104.816115 2448
+60343 6 sat 17:16:06 38°09.2590'N 104°48.9723'W 2433m 38.154317 -104.816205 2433
+60443 6 sat 17:16:07 38°09.2611'N 104°48.9772'W 2419m 38.154351 -104.816287 2419
+60542 6 sat 17:16:08 38°09.2620'N 104°48.9819'W 2407m 38.154367 -104.816365 2407
+60643 6 sat 17:16:09 38°09.2617'N 104°48.9861'W 2394m 38.154361 -104.816435 2394
+60743 6 sat 17:16:10 38°09.2613'N 104°48.9892'W 2378m 38.154355 -104.816487 2378
+60843 6 sat 17:16:11 38°09.2605'N 104°48.9922'W 2362m 38.154341 -104.816537 2362
+60943 6 sat 17:16:12 38°09.2603'N 104°48.9905'W 2342m 38.154338 -104.816508 2342
+61043 6 sat 17:16:13 38°09.2649'N 104°48.9926'W 2326m 38.154415 -104.816543 2326
+61143 6 sat 17:16:14 38°09.2723'N 104°48.9896'W 2278m 38.154538 -104.816493 2278
+61243 6 sat 17:16:15 38°09.2750'N 104°48.9938'W 2263m 38.154583 -104.816563 2263
+61343 6 sat 17:16:16 38°09.2884'N 104°48.9812'W 2168m 38.154807 -104.816353 2168
+61442 6 sat 17:16:17 38°09.2896'N 104°48.9848'W 2156m 38.154827 -104.816413 2156
+61543 6 sat 17:16:18 38°09.2999'N 104°48.9744'W 2085m 38.154998 -104.816240 2085
+61643 6 sat 17:16:19 38°09.3028'N 104°48.9755'W 2071m 38.155047 -104.816258 2071
+61743 6 sat 17:16:20 38°09.3082'N 104°48.9737'W 2043m 38.155137 -104.816228 2043
+61843 6 sat 17:16:21 38°09.3133'N 104°48.9746'W 2021m 38.155221 -104.816243 2021
+61943 6 sat 17:16:22 38°09.3194'N 104°48.9735'W 1992m 38.155323 -104.816225 1992
+62043 6 sat 17:16:23 38°09.3223'N 104°48.9758'W 1979m 38.155371 -104.816263 1979
+62142 5 sat 17:16:24 38°09.3241'N 104°48.9758'W 1967m 38.155401 -104.816263 1967
+62242 4 sat 17:16:25 38°09.3249'N 104°48.9762'W 1956m 38.155415 -104.816270 1956
+62343 5 sat 17:16:26 38°09.3258'N 104°48.9741'W 1945m 38.155430 -104.816235 1945
+62442 5 sat 17:16:27 38°09.3276'N 104°48.9710'W 1934m 38.155460 -104.816183 1934
+62542 4 sat 17:16:28 38°09.3289'N 104°48.9696'W 1924m 38.155481 -104.816160 1924
+62642 4 sat 17:16:29 38°09.3302'N 104°48.9686'W 1913m 38.155503 -104.816143 1913
+62742 4 sat 17:16:30 38°09.3317'N 104°48.9681'W 1902m 38.155528 -104.816135 1902
+62843 4 sat 17:16:31 38°09.3335'N 104°48.9667'W 1890m 38.155558 -104.816111 1890
+62942 5 sat 17:16:32 38°09.3351'N 104°48.9651'W 1880m 38.155585 -104.816085 1880
+63043 5 sat 17:16:33 38°09.3367'N 104°48.9637'W 1870m 38.155611 -104.816061 1870
+63143 4 sat 17:16:34 38°09.3379'N 104°48.9622'W 1861m 38.155631 -104.816037 1861
+63242 4 sat 17:16:35 38°09.3392'N 104°48.9611'W 1851m 38.155653 -104.816018 1851
+63342 4 sat 17:16:36 38°09.3406'N 104°48.9602'W 1842m 38.155677 -104.816003 1842
+63443 4 sat 17:16:37 38°09.3419'N 104°48.9592'W 1832m 38.155698 -104.815987 1832
+63542 3 sat 17:16:38 38°09.3422'N 104°48.9599'W 1830m 38.155703 -104.815998 1830
+63642 3 sat 17:16:39 38°09.3423'N 104°48.9608'W 1828m 38.155705 -104.816013 1828
+63742 3 sat 17:16:40 38°09.3424'N 104°48.9617'W 1827m 38.155707 -104.816028 1827
+63842 4 sat 17:16:41 38°09.3434'N 104°48.9606'W 1820m 38.155723 -104.816010 1820
+63942 4 sat 17:16:42 38°09.3445'N 104°48.9595'W 1812m 38.155741 -104.815991 1812
+64042 4 sat 17:16:43 38°09.3460'N 104°48.9591'W 1801m 38.155767 -104.815985 1801
+64142 5 sat 17:16:44 38°09.3479'N 104°48.9579'W 1787m 38.155798 -104.815965 1787
+64242 5 sat 17:16:45 38°09.3497'N 104°48.9559'W 1774m 38.155828 -104.815931 1774
+64343 5 sat 17:16:46 38°09.3515'N 104°48.9534'W 1762m 38.155858 -104.815890 1762
+64442 5 sat 17:16:47 38°09.3535'N 104°48.9507'W 1748m 38.155891 -104.815845 1748
+64542 4 sat 17:16:48 38°09.3550'N 104°48.9485'W 1738m 38.155917 -104.815808 1738
+64642 3 sat 17:16:49 38°09.3556'N 104°48.9484'W 1733m 38.155927 -104.815807 1733
+64742 3 sat 17:16:50 38°09.3560'N 104°48.9483'W 1729m 38.155933 -104.815805 1729
--- /dev/null
+typedef struct {
+ int type;
+ int time;
+ int a;
+ int b;
+} flight_record;
+
+flight_record
+read_record(file in) {
+ flight_record r;
+ File::fscanf(in, "%c %x %x %x\n",
+ &r.type, &r.time, &r.a, &r.b);
+ return r;
+}
+
+typedef struct {
+ int degrees;
+ int minutes;
+ int minutes_fraction;
+} gps_pos;
+
+typedef struct {
+ int hour;
+ int minute;
+ int second;
+} gps_time;
+
+real combine_gps_pos(gps_pos p, bool flag)
+{
+ real sign = flag ? -1 : 1;
+ return sign * (p.degrees + (p.minutes +
+ p.minutes_fraction / 10000)
+ / 60);
+}
+
+void read_gps(file in)
+{
+ gps_time time;
+ gps_pos lat, lon;
+ int flags;
+ int alt;
+
+ while (!File::end(in)) {
+ flight_record r = read_record(in);
+ switch (r.type) {
+ case 'G':
+ time.hour = r.a & 0xff;
+ time.minute = r.a >> 8;
+ time.second = r.b & 0xff;
+ flags = r.b >> 8;
+ break;
+ case 'N':
+ lat.degrees = r.a & 0xff;
+ lat.minutes = r.a >> 8;
+ lat.minutes_fraction = r.b;
+ break;
+ case 'W':
+ lon.degrees = r.a & 0xff;
+ lon.minutes = r.a >> 8;
+ lon.minutes_fraction = r.b;
+ break;
+ case 'H':
+ alt = r.a;
+ printf ("%5d %d sat ", r.time, flags & 0xf);
+ if ((flags & (1 << 4)) != 0) {
+ printf ("%02d:%02d:%02d ",
+ time.hour, time.minute, time.second);
+ printf ("%4d°%02d.%04d'%c %2d°%02d.%04d'%c %5dm ",
+ lat.degrees, lat.minutes,
+ lat.minutes_fraction,
+ (flags & (1 << 6)) != 0 ? 'S' : 'N',
+ lon.degrees, lon.minutes,
+ lon.minutes_fraction,
+ (flags & (1 << 5)) != 0 ? 'W' : 'E',
+ alt);
+ printf ("%11.6f %11.6f %5d\n",
+ combine_gps_pos(lat,
+ (flags & (1 << 6)) !=
+ 0),
+ combine_gps_pos(lon,
+ (flags & (1 << 5)) !=
+ 0),
+ alt);
+ } else {
+ printf ("unlocked\n");
+ }
+ break;
+ }
+ }
+}
+
+read_gps(stdin);