123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008 |
- /*
- * geoid.c -- ECEF to WGS84 conversions, including ellipsoid-to-MSL height
- * and magnetic variation.
- *
- * Geoid separation code by Oleg Gusev, from data by Peter Dana.
- * ECEF conversion by Rob Janssen.
- *
- * This file is Copyright (c) 2010-2019 by the GPSD project
- * SPDX-License-Identifier: BSD-2-clause
- */
- #include "gpsd_config.h" /* must be before all includes */
- #include <math.h>
- #include "gpsd.h"
- #include "os_compat.h"
- #ifdef __UNUSED
- static double fix_minuz(double d);
- static double atan2z(double y, double x);
- #endif /* __UNUSED */
- #define GEOID_ROW 37
- #define GEOID_COL 73
- /* This table is EGM2008. Values obtained from GeoidEval, part of
- * geographiclib., by using devtools/get_geoid_table.py
- *
- * geoid_delta[][] has the geoid separation, in cm, on a 5 degree by 5
- * degree grid for the entire planet.
- */
- /* *INDENT-OFF* */
- const short geoid_delta[GEOID_ROW][GEOID_COL] = {
- /* -90 */
- { -3015, -3015, -3015, -3015, -3015, -3015, -3015, -3015, -3015, -3015,
- -3015, -3015, -3015, -3015, -3015, -3015, -3015, -3015, -3015, -3015,
- -3015, -3015, -3015, -3015, -3015, -3015, -3015, -3015, -3015, -3015,
- -3015, -3015, -3015, -3015, -3015, -3015, -3015, -3015, -3015, -3015,
- -3015, -3015, -3015, -3015, -3015, -3015, -3015, -3015, -3015, -3015,
- -3015, -3015, -3015, -3015, -3015, -3015, -3015, -3015, -3015, -3015,
- -3015, -3015, -3015, -3015, -3015, -3015, -3015, -3015, -3015, -3015,
- -3015, -3015, -3015},
- /* -85 */
- { -3568, -3608, -3739, -3904, -4039, -4079, -4033, -3946, -3845, -3734,
- -3603, -3458, -3310, -3163, -2994, -2827, -2695, -2667, -2737, -2823,
- -2840, -2757, -2634, -2567, -2547, -2540, -2452, -2247, -1969, -1704,
- -1540, -1507, -1552, -1592, -1573, -1513, -1465, -1478, -1542, -1577,
- -1483, -1256, -1029, -957, -1066, -1216, -1262, -1194, -1118, -1129,
- -1231, -1370, -1504, -1641, -1813, -2028, -2255, -2455, -2630, -2811,
- -3022, -3242, -3436, -3578, -3658, -3676, -3640, -3578, -3527, -3490,
- -3532, -3570, -3568},
- /* -80 */
- { -5232, -5276, -5275, -5301, -5286, -5276, -5218, -5001, -4775, -4580,
- -4319, -4064, -3854, -3691, -3523, -3205, -2910, -2608, -2337, -2355,
- -2417, -2445, -2471, -2350, -2230, -2136, -1869, -1689, -1732, -1748,
- -1540, -1236, -1048, -794, -569, -603, -501, -305, -166, 19,
- 146, 274, 444, 510, 534, 550, 458, 373, 473, 575,
- 607, 732, 562, 153, -271, -825, -1300, -1861, -2475, -2866,
- -3434, -4001, -4196, -4533, -4989, -5152, -5094, -4983, -4987, -5065,
- -5055, -5115, -5232},
- /* -75 */
- { -6155, -6339, -6266, -6344, -6282, -6100, -6009, -5492, -5088, -4547,
- -4187, -3901, -3586, -3234, -3051, -2886, -2577, -2289, -1981, -1655,
- -1435, -1096, -557, -617, -998, -961, -655, -464, -170, 79,
- -103, -64, 150, 223, 819, 1006, 1174, 1136, 1211, 1278,
- 1467, 1686, 1783, 1706, 1833, 1721, 1653, 1580, 1267, 953,
- 629, 807, 774, 607, 217, -386, -814, -1354, -2452, -3542,
- -3833, -3932, -4259, -4962, -4977, -5536, -5753, -5800, -6012, -5835,
- -5751, -5820, -6155},
- /* -70 */
- { -6218, -6432, -6333, -6150, -6021, -5948, -5705, -5480, -5213, -4789,
- -4365, -4003, -3757, -3514, -3250, -3000, -2672, -2541, -2138, -1220,
- -844, -277, 249, 906, 458, 69, 26, 98, 166, 130,
- 118, 253, 303, 437, 1010, 1341, 1423, 1558, 1682, 1825,
- 1766, 1917, 2027, 2047, 2164, 2909, 2882, 2997, 3010, 2687,
- 1749, 1703, 1799, 1438, 1099, 346, -813, -1432, -2149, -2320,
- -2704, -3085, -3907, -4172, -4287, -4846, -5466, -5592, -5576, -5525,
- -5800, -5954, -6218},
- /* -65 */
- { -5152, -5115, -5049, -4943, -4858, -4714, -4580, -4369, -4202, -4060,
- -3806, -3454, -3210, -3007, -2749, -2484, -2264, -1928, -1501, -1113,
- -614, 31, 642, 1502, 1833, 1844, 1268, 1442, 1441, 1302,
- 1164, 1041, 945, 874, 896, 1059, 1368, 1680, 1736, 1975,
- 1891, 1979, 2131, 2338, 2672, 2861, 3114, 3097, 2801, 2695,
- 2422, 2022, 1648, 1340, 713, 352, -127, -895, -1740, -2040,
- -2854, -3292, -3453, -3922, -4395, -4538, -4554, -4356, -4445, -4669,
- -4988, -5122, -5152},
- /* -60 */
- { -4598, -4449, -4278, -4056, -3732, -3417, -3205, -3094, -3008, -2876,
- -2669, -2478, -2350, -2272, -2218, -1969, -1660, -1381, -1123, -716,
- -350, 247, 924, 1712, 2016, 2066, 2032, 1556, 2123, 2322,
- 2384, 1034, 2121, 1923, 1720, 1571, 1517, 1668, 2008, 2366,
- 2546, 2736, 2914, 3169, 3395, 3467, 3315, 3286, 3279, 3073,
- 2930, 2727, 2502, 1783, 893, 311, -328, -778, -1364, -1973,
- -2467, -2833, -3143, -3283, -3311, -3120, -2956, -3027, -3485, -3972,
- -4454, -4679, -4598},
- /* -55 */
- { -3414, -3429, -3223, -3013, -2704, -2474, -2292, -2185, -1962, -1818,
- -1828, -1485, -1259, -1284, -1327, -1304, -1097, -1071, -628, -326,
- 174, 340, 1331, 1217, 1712, 1441, 1467, 1578, 1654, 2179,
- 764, 1486, 2074, 2245, 2462, 2655, 2720, 2581, 2423, 2731,
- 3145, 3383, 3436, 3909, 4448, 4422, 4032, 3938, 3665, 3461,
- 3465, 3317, 2487, 1908, 1311, 683, 52, -582, -1196, -1798,
- -2158, -2450, -2475, -2429, -2277, -2011, -2140, -2306, -2551, -2726,
- -3016, -3319, -3414},
- /* -50 */
- { -1615, -1938, -1875, -1827, -1839, -1793, -1605, -1650, -1737, -1773,
- -1580, -1237, -1010, -983, -1051, -1025, -838, -653, -316, 48,
- 502, 1382, 1186, 1114, 1264, 785, 231, 329, 353, 556,
- 1084, 1597, 2065, 2475, 2744, 2701, 2518, 2545, 2584, 2963,
- 3323, 3537, 3792, 4085, 4520, 4505, 4459, 4287, 3818, 4112,
- 3975, 3293, 2748, 2043, 1272, 569, -207, -898, -1498, -1990,
- -2242, -2358, -2212, -1968, -1843, -1695, -1705, -1688, -1400, -1177,
- -1013, -1168, -1615},
- /* -45 */
- { 338, -20, -606, -849, -777, -838, -1123, -1322, -1485, -1503,
- -1413, -1203, -1077, -1004, -960, -829, -662, -371, -88, 322,
- 710, 1323, 1831, 1202, 908, 47, -292, -367, -495, -174,
- 688, 1500, 2194, 2673, 2568, 2423, 2099, 2168, 2617, 2834,
- 3254, 3328, 3443, 4442, 4639, 4588, 4524, 4223, 3575, 3187,
- 3101, 2651, 2155, 1506, 774, -55, -961, -1719, -2355, -2719,
- -2731, -2670, -2430, -2026, -1715, -1477, -1144, -901, -646, -303,
- 871, 565, 338},
- /* -40 */
- { 2048, 1283, 637, 317, 109, -156, -679, -1023, -1186, -1277,
- -1275, -1202, -1282, -1150, -1022, -881, -690, -300, -84, 130,
- 694, 937, 2220, 1511, 1341, 558, -266, -623, -670, -209,
- 643, 1459, 2101, 2385, 2307, 2000, 1765, 1992, 2496, 2733,
- 2941, 3431, 3298, 3327, 3877, 4306, 4069, 3446, 2844, 2601,
- 2333, 1786, 1318, 599, -238, -1184, -2098, -2786, -3250, -3406,
- -3351, -3095, -2741, -2101, -1482, -148, -201, 221, 491, 1179,
- 1877, 1206, 2048},
- /* -35 */
- { 2833, 2556, 1700, 1059, 497, -21, -370, -752, -959, -1103,
- -1093, -1104, -1198, -1097, -960, -785, -596, -362, -211, 103,
- 739, 1300, 3029, 2021, 1712, 1269, -23, -616, -701, -255,
- 684, 1237, 1701, 1903, 1696, 1789, 1795, 2034, 2398, 2561,
- 3187, 2625, 2609, 2897, 2564, 3339, 3118, 3121, 2240, 2102,
- 1529, 991, 387, -559, -1464, -2380, -3138, -3999, -3899, -3446,
- -3473, -3300, -2823, -1043, 143, 970, 2058, 1555, 1940, 2621,
- 3154, 3839, 2833},
- /* -30 */
- { 4772, 3089, 2257, 1381, 566, 64, -136, -612, -868, -1186,
- -1309, -1131, -1033, -903, -780, -625, -443, -242, 100, 269,
- 815, 1489, 3633, 2424, 1810, 1138, 297, -720, -847, -2,
- 347, 579, 1025, 1408, 1504, 1686, 2165, 2353, 2599, 3182,
- 3332, 3254, 3094, 2042, 1369, 1945, 1468, 1487, 1505, 1048,
- 613, 26, -904, -1757, -2512, -3190, -3751, -3941, -3939, -2896,
- -2222, -1766, -1442, 70, 1262, 2229, 3189, 2910, 3371, 3608,
- 4379, 4520, 4772},
- /* -25 */
- { 4984, 2801, 2475, 1374, 798, 198, -269, -628, -1063, -1262,
- -1090, -970, -692, -516, -458, -313, -143, 19, 183, 403,
- 837, 1650, 3640, 2990, 2084, 628, 422, -597, -1130, -712,
- -474, -110, 446, 1043, 1349, 1571, 2008, 2572, 2405, 3175,
- 2766, 2407, 2100, 1130, 367, 840, 89, 114, 49, -25,
- -494, -1369, -2345, -3166, -3804, -4256, -4141, -3730, -3337, -1814,
- -901, -388, 298, 1365, 2593, 3490, 4639, 4427, 4795, 4771,
- 5325, 5202, 4984},
- /* -20 */
- { 4994, 5152, 2649, 1466, 935, 427, -115, -518, -838, -1135,
- -1134, -917, -525, -280, -218, -310, -396, -306, -137, 148,
- 811, 1643, 3496, 4189, 1958, 358, -784, -684, -740, -800,
- -579, -638, -49, 704, 1221, 1358, 1657, 1957, 2280, 2639,
- 2157, 1246, 728, -364, -1021, -586, -1098, -1055, -1032, -1244,
- -2065, -3158, -4028, -4660, -4802, -4817, -4599, -3523, -2561, -1260,
- 446, 1374, 2424, 3310, 4588, 5499, 5724, 5479, 5698, 5912,
- 6400, 6116, 4994},
- /* -15 */
- { 4930, 4158, 2626, 1375, 902, 630, 150, -275, -667, -1005,
- -954, -847, -645, -376, -315, -479, -639, -681, -550, -268,
- 709, 2996, 4880, 2382, 1695, -136, -964, -1211, -1038, -1045,
- -695, -595, 23, 733, 1107, 1318, 1348, 1376, 1630, 2240,
- 1248, 454, -737, -1252, -2001, -2513, -1416, -2169, -2269, -3089,
- -4063, -5194, -5715, -6105, -5700, -4873, -3919, -2834, -1393, -112,
- 1573, 3189, 3907, 4863, 5437, 6548, 6379, 6281, 6289, 5936,
- 6501, 5794, 4930},
- /* -10 */
- { 3525, 2747, 2135, 1489, 1078, 739, 544, -39, -268, -588,
- -917, -1025, -1087, -940, -771, -923, -1177, -1114, -919, -383,
- -108, 2135, 2818, 1929, 386, -1097, -1911, -1619, -1226, -1164,
- -952, -583, 399, 1070, 1280, 1345, 1117, 993, 1306, 1734,
- 538, -463, -1208, -1602, -2662, -3265, -3203, -3408, -3733, -5014,
- -6083, -7253, -7578, -7096, -6418, -4658, -2647, -586, -87, 1053,
- 3840, 3336, 5240, 6253, 6898, 7070, 7727, 7146, 6209, 5826,
- 5068, 4161, 3525},
- /* -5 */
- { 2454, 1869, 1656, 1759, 1404, 1263, 1012, 605, 108, -511,
- -980, -1364, -1620, -1633, -1421, -1342, -1412, -1349, -1006, -229,
- 1711, 1293, 1960, 605, -793, -2058, -2108, -2626, -1195, -606,
- -513, -108, 671, 1504, 1853, 1711, 1709, 940, 570, 296,
- -913, -1639, -1471, -1900, -3000, -4164, -4281, -4062, -5366, -6643,
- -7818, -8993, -9275, -8306, -6421, -4134, -1837, 1367, 2850, 4286,
- 5551, 5599, 5402, 6773, 7736, 7024, 8161, 6307, 5946, 4747,
- 3959, 3130, 2454},
- /* 0 */
- { 2128, 1774, 1532, 1470, 1613, 1589, 1291, 783, 79, -676,
- -1296, -1941, -2298, -2326, -2026, -1738, -1412, -1052, -406, 82,
- 1463, 1899, 1352, -170, -1336, -2446, -2593, -2328, -1863, -833,
- 245, 1005, 1355, 1896, 1913, 1888, 1723, 1642, 940, -127,
- -1668, -1919, -1078, -1633, -2762, -4357, -4885, -5143, -6260, -7507,
- -8947, -10042, -10259, -8865, -6329, -3424, -692, 1445, 3354, 5132,
- 5983, 4978, 7602, 7274, 7231, 6941, 6240, 5903, 4944, 4065,
- 3205, 2566, 2128},
- /* 5 */
- { 1632, 1459, 1243, 1450, 1643, 1432, 867, 283, -420, -1316,
- -1993, -2614, -3012, -3016, -2555, -1933, -1256, -688, -133, 634,
- 1369, 2095, -92, -858, -1946, -3392, -3666, -3110, -1839, -371,
- 674, 1221, 1657, 1994, 2689, 2577, 2020, 2126, 1997, 987,
- -739, -989, -1107, -1369, -1914, -3312, -4871, -5365, -6171, -7732,
- -9393, -10088, -10568, -9022, -6053, -4104, -1296, 373, 2310, 4378,
- 6279, 6294, 6999, 6852, 6573, 6302, 5473, 5208, 4502, 3445,
- 2790, 2215, 1632},
- /* 10 */
- { 1285, 1050, 1212, 1439, 1055, 638, 140, -351, -1115, -2060,
- -2904, -3593, -3930, -3694, -2924, -2006, -1145, -441, 164, 1059,
- 91, -440, -1043, -2791, -4146, -4489, -4259, -3218, -1691, -683,
- 306, 1160, 1735, 3081, 3275, 2807, 2373, 2309, 2151, 1245,
- 207, -132, -507, -564, -956, -1917, -3167, -5067, -5820, -7588,
- -9107, -9732, -9732, -8769, -6308, -4585, -2512, -891, 1108, 3278,
- 5183, 6391, 5985, 5969, 6049, 5616, 4527, 4156, 3531, 2776,
- 2456, 1904, 1285},
- /* 15 */
- { 862, 804, 860, 969, 544, 89, -417, -1008, -1641, -2608,
- -3607, -4234, -4482, -4100, -3232, -2092, -1105, -1092, 238, 330,
- -571, -1803, -2983, -3965, -5578, -4864, -3777, -2572, -1690, -536,
- 806, 2042, 2323, 3106, 3019, 2833, 2260, 2064, 2036, 1358,
- 1030, 908, 391, -54, -377, -885, -2172, -3359, -5309, -6686,
- -8058, -8338, -8695, -8322, -6404, -5003, -3420, -2060, -255, 1833,
- 4143, 4218, 4771, 5031, 5241, 5504, 4399, 3471, 2832, 2266,
- 1643, 1190, 862},
- /* 20 */
- { 442, 488, 986, 877, 757, 1175, -696, -1473, -2285, -3128,
- -3936, -4520, -4739, -4286, -3350, -2092, -747, -1894, -1083, -1508,
- -2037, -2528, -4813, -6316, -4698, -4222, -3279, -1814, -1001, 212,
- 1714, 2273, 2535, 3367, 3112, 2736, 3086, 2742, 2679, 2071,
- 1422, 1333, 922, 619, 183, -945, -3070, -3680, -4245, -5461,
- -6064, -6652, -6806, -6210, -5947, -5177, -3814, -2589, -1319, 551,
- 2150, 3262, 3799, 4177, 4898, 4658, 4149, 2833, 2148, 1410,
- 899, 551, 442},
- /* 25 */
- { -248, 12, 716, 415, 327, -187, -1103, -1729, -2469, -3296,
- -4040, -4545, -4642, -4232, -3466, -2064, -1667, -3232, -2660, -2685,
- -2789, -4262, -5208, -5084, -4935, -4077, -2622, -804, 131, 946,
- 1859, 2203, 3038, 3433, 3758, 3029, 2757, 3524, 3109, 2511,
- 2300, 1554, 1316, 1114, 954, -81, -2642, -3389, -3167, -4211,
- -4634, -5193, -6014, -6245, -5347, -5313, -3846, -3149, -2130, -354,
- 1573, 2760, 3310, 3713, 4594, 3862, 2827, 1939, 1019, 313,
- -142, -378, -248},
- /* 30 */
- { -720, -717, -528, -573, -867, -1224, -1588, -2135, -2796, -3432,
- -4036, -4329, -4246, -3464, -2996, -2389, -2323, -2844, -2744, -2884,
- -3238, -4585, -5164, -4463, -4064, -3238, -1751, 150, 1657, 2501,
- 3023, 3007, 3404, 3976, 4354, 4648, 3440, 2708, 2813, 2968,
- 2611, 2104, 1606, 1808, 1086, -392, -1793, -689, -1527, -2765,
- -3766, -4709, -3687, -2800, -3375, -3793, -3365, -4182, -2385, -1115,
- 785, 2302, 3020, 3564, 4178, 2993, 1940, 1081, 331, -364,
- -683, -690, -720},
- /* 35 */
- { -1004, -1222, -1315, -1304, -1463, -1680, -2160, -2675, -3233, -3746,
- -4021, -4053, -3373, -3012, -2447, -2184, -2780, -3219, -2825, -3079,
- -3181, -4284, -4548, -3867, -3123, -2302, -785, 943, 2687, 4048,
- 4460, 4290, 4118, 4585, 4282, 4437, 4898, 3818, 3696, 3414,
- 2299, 2057, 627, 1915, 1833, 451, 678, -876, -1602, -2167,
- -3344, -2549, -2860, -3514, -4043, -4207, -4005, -3918, -3121, -1521,
- 471, 2023, 2980, 3679, 3465, 2405, 1475, 553, -142, -880,
- -1178, -963, -1004},
- /* 40 */
- { -1223, -1218, -1076, -1116, -1298, -1541, -2085, -2648, -3120, -3473,
- -3679, -3342, -2334, -1912, -1787, -1756, -2482, -3182, -3322, -3429,
- -3395, -3374, -3372, -3341, -2654, -1509, 105, 1620, 3250, 4603,
- 5889, 5776, 5198, 4840, 4903, 5370, 5086, 4536, 4519, 4601,
- 3395, 4032, 3890, 3537, 3113, 2183, -1769, -1552, -2856, -3694,
- -4092, -3614, -5468, -6518, -6597, -5911, -5476, -4465, -2802, -1076,
- 232, 1769, 2305, 3018, 3768, 1721, 1694, 667, -154, -799,
- -1068, -1196, -1223},
- /* 45 */
- { -634, -460, -330, -267, -413, -818, -1310, -1763, -2352, -2738,
- -2632, -2685, -1929, -1340, -737, -1441, -2254, -2685, -3358, -3488,
- -3635, -3187, -2665, -2142, -1515, -124, 1727, 2798, 3965, 5065,
- 6150, 6513, 6089, 5773, 5044, 4471, 4677, 5052, 3938, 4537,
- 4425, 3652, 3063, 2178, 1267, 84, -1109, -1974, -2905, -3650,
- -4264, -4741, -4136, -6324, -5826, -5143, -4851, -4344, -3225, -1386,
- 5, 1153, 2198, 2833, 2835, 2563, 1337, 1194, 503, -329,
- -289, -754, -634},
- /* 50 */
- { -578, -40, 559, 880, 749, 464, 0, -516, -1140, -1655,
- -1818, -1589, -1555, -1337, -1769, -1919, -2372, -2981, -3485, -3976,
- -3941, -3565, -2614, -2223, -1253, 802, 2406, 3239, 4434, 5428,
- 6265, 6394, 6180, 5690, 5855, 5347, 4506, 4685, 4799, 4445,
- 3972, 3165, 2745, 1601, 1084, 41, -1170, -1701, -1916, -2914,
- -3305, -3790, -4435, -4128, -4163, -4535, -4190, -3891, -2951, -1869,
- -414, 851, 1494, 2097, 2268, 1939, 2031, 2460, 638, 578,
- 325, 98, -578},
- /* 55 */
- { -18, 482, 905, 1562, 1739, 983, 1097, 568, 34, -713,
- -695, -1072, -1576, -1879, -2479, -2884, -3275, -3971, -4456, -4654,
- -4461, -3688, -2697, -1623, -823, 1270, 2523, 3883, 4967, 5977,
- 6049, 6149, 6095, 5776, 5820, 5575, 4642, 4099, 4025, 3462,
- 2679, 2447, 1951, 1601, 1151, 663, 157, -603, -952, -1987,
- -2609, -3316, -3600, -3684, -3717, -3836, -4024, -3452, -2950, -1861,
- -903, 89, 975, 1499, 1560, 1601, 1922, 2031, 2326, -58,
- 506, -177, -18},
- /* 60 */
- { 93, 673, 969, 1168, 1498, 1486, 1439, 1165, 1128, 720,
- 5, -689, -1610, -2409, -3094, -3585, -4193, -4772, -4678, -4521,
- -4184, -2955, -2252, -834, 503, 1676, 2882, 4130, 4892, 5611,
- 6390, 6338, 6069, 5974, 5582, 5461, 4788, 4503, 4080, 2957,
- 1893, 1773, 1586, 1544, 1136, 1026, 622, 50, -389, -1484,
- -2123, -2625, -3028, -3143, -3366, -3288, -3396, -3069, -2770, -2605,
- -1663, -555, 25, 491, 1168, 1395, 1641, 1597, 1426, 1299,
- 921, -160, 93},
- /* 65 */
- { 419, 424, 443, 723, 884, 1030, 1077, 1191, 1065, 734,
- 265, -1052, -1591, -2136, -2773, -3435, -3988, -3978, -3698, -3509,
- -3370, -2490, -1347, -263, 1647, 2582, 3291, 4802, 4447, 5609,
- 5879, 6454, 6709, 6606, 5988, 5365, 5103, 4385, 3996, 3250,
- 2526, 1766, 1817, 1751, 1275, 857, 636, 29, -12, -918,
- -1364, -1871, -2023, -2102, -2258, -2441, -2371, -2192, -1908, -1799,
- -1720, -1662, -385, 86, 466, 880, 715, 834, 1010, 1105,
- 877, 616, 419},
- /* 70 */
- { 242, 93, 98, 62, -54, -25, -127, -156, -253, -412,
- -805, -1106, -1506, -1773, -2464, -2829, -2740, -2579, -2559, -2271,
- -1849, -853, 294, 1055, 2357, 2780, 2907, 3909, 4522, 5272,
- 5594, 5903, 5966, 5930, 5592, 5188, 4878, 4561, 4190, 3834,
- 2963, 2451, 1981, 1525, 1064, 694, 253, -70, -318, -781,
- -979, -1048, -1274, -1413, -1175, -1313, -1449, -1206, -850, -1087,
- -828, -933, -540, -301, -35, 53, 279, 267, 345, 371,
- 334, 289, 242},
- /* 75 */
- { 128, 228, 376, 46, -173, -355, -417, -548, -764, -925,
- -419, -950, -1185, -1102, -1293, -1355, -1075, -713, -365, 167,
- 516, 1381, 1882, 1826, 1956, 2492, 3192, 3541, 3750, 4123,
- 4462, 4592, 4472, 4705, 4613, 4559, 4340, 4392, 4144, 3973,
- 3119, 2582, 2057, 1684, 1199, 834, 477, 325, 295, -198,
- -459, -670, -706, -677, -766, -852, -939, -905, -637, -601,
- -531, -433, -292, -158, 88, 85, 118, 121, 147, 179,
- 173, 149, 128},
- /* 80 */
- { 342, 293, 244, 159, 38, 20, 15, -15, -109, -119,
- -240, -182, 16, 397, 550, 264, 350, 670, 865, 681,
- 1188, 1136, 703, 1153, 1930, 2412, 2776, 3118, 3351, 3634,
- 3653, 3272, 3177, 3161, 3354, 3671, 3615, 3572, 3522, 3274,
- 2914, 2682, 2426, 2185, 1845, 1584, 1297, 1005, 809, 507,
- 248, 314, 230, 96, 149, 240, 274, 297, 153, 109,
- 164, 91, 104, 43, 12, 153, 243, 170, 184, 59,
- 99, 158, 342},
- /* 85 */
- { 912, 961, 1013, 1013, 997, 1032, 1026, 1050, 1072, 1132,
- 1156, 1253, 1310, 1389, 1441, 1493, 1508, 1565, 1621, 1642,
- 1768, 1888, 2036, 2089, 2117, 2106, 2010, 2120, 2276, 2376,
- 2426, 2427, 2526, 2582, 2493, 2534, 2628, 2564, 2471, 2509,
- 2407, 2332, 2214, 2122, 1987, 1855, 1714, 1619, 1517, 1474,
- 1406, 1351, 1308, 1264, 1181, 1081, 1047, 1084, 1043, 964,
- 851, 755, 732, 706, 697, 785, 864, 762, 686, 729,
- 789, 856, 912},
- /* 90 */
- { 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490,
- 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490,
- 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490,
- 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490,
- 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490,
- 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490,
- 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490,
- 1490, 1490, 1490}
- };
- /* This table is wmm2015. Values obtained from MagneticField, part of
- * geographiclib., by using devtools/get_mag_var_table.py
- *
- * magvar[][] has the magnetic variation (declination), in hundreths of
- * a degree, on a 5 degree by 5 * degree grid for the entire planet.
- *
- * This table is duplicated in gps/clienthelpers.py. Keep them in sync.
- */
- /* *INDENT-OFF* */
- const short magvar[GEOID_ROW][GEOID_COL] = {
- /* -90 */
- { 14920, 14420, 13920, 13420, 12920, 12420, 11920, 11420, 10920,
- 10420, 9920, 9420, 8920, 8420, 7920, 7420, 6920, 6420,
- 5920, 5420, 4920, 4420, 3920, 3420, 2920, 2420, 1920,
- 1420, 920, 420, -80, -580, -1080, -1580, -2080, -2580,
- -3080, -3580, -4080, -4580, -5080, -5580, -6080, -6580, -7080,
- -7580, -8080, -8580, -9080, -9580, -10080, -10580, -11080, -11580,
- -12080, -12580, -13080, -13580, -14080, -14580, -15080, -15580, -16080,
- -16580, -17080, -17580, 17920, 17420, 16920, 16420, 15920, 15420,
- 14920},
- /* -85 */
- { 14174, 13609, 13052, 12504, 11965, 11435, 10914, 10402, 9898,
- 9403, 8915, 8434, 7960, 7492, 7029, 6572, 6119, 5671,
- 5226, 4784, 4346, 3909, 3475, 3042, 2611, 2180, 1750,
- 1319, 889, 457, 25, -409, -845, -1283, -1723, -2166,
- -2612, -3061, -3514, -3971, -4431, -4895, -5364, -5837, -6315,
- -6798, -7285, -7778, -8277, -8781, -9291, -9808, -10331, -10860,
- -11397, -11940, -12491, -13048, -13613, -14184, -14761, -15344, -15931,
- -16523, -17117, -17714, 17690, 17094, 16500, 15910, 15325, 14746,
- 14174},
- /* -80 */
- { 12958, 12331, 11733, 11163, 10619, 10099, 9600, 9121, 8659,
- 8211, 7776, 7352, 6937, 6529, 6127, 5730, 5338, 4949,
- 4563, 4180, 3799, 3420, 3043, 2667, 2292, 1918, 1544,
- 1170, 795, 419, 40, -342, -727, -1117, -1512, -1912,
- -2318, -2729, -3147, -3571, -4002, -4438, -4880, -5328, -5782,
- -6241, -6707, -7180, -7659, -8146, -8641, -9146, -9662, -10190,
- -10732, -11290, -11866, -12461, -13077, -13716, -14379, -15064, -15772,
- -16500, -17244, -17999, 17241, 16485, 15738, 15007, 14298, 13614,
- 12958},
- /* -75 */
- { 11045, 10435, 9882, 9378, 8915, 8485, 8081, 7699, 7335,
- 6983, 6640, 6304, 5972, 5642, 5313, 4982, 4651, 4317,
- 3982, 3646, 3309, 2972, 2635, 2300, 1966, 1634, 1304,
- 975, 646, 316, -16, -352, -694, -1042, -1398, -1764,
- -2138, -2523, -2916, -3319, -3729, -4146, -4569, -4997, -5430,
- -5866, -6306, -6750, -7197, -7650, -8109, -8576, -9054, -9545,
- -10054, -10585, -11143, -11736, -12371, -13058, -13806, -14624, -15519,
- -16489, -17525, 17396, 16307, 15245, 14242, 13317, 12478, 11723,
- 11045},
- /* -70 */
- { 8567, 8144, 7771, 7437, 7132, 6851, 6587, 6336, 6095,
- 5858, 5623, 5386, 5144, 4896, 4639, 4372, 4094, 3807,
- 3510, 3206, 2895, 2582, 2266, 1952, 1641, 1334, 1033,
- 736, 444, 155, -136, -429, -729, -1038, -1359, -1693,
- -2042, -2406, -2782, -3170, -3568, -3973, -4383, -4795, -5208,
- -5620, -6030, -6437, -6843, -7246, -7650, -8054, -8463, -8880,
- -9308, -9756, -10230, -10744, -11314, -11965, -12737, -13686, -14889,
- -16424, 17708, 15701, 13867, 12382, 11234, 10344, 9636, 9056,
- 8567},
- /* -65 */
- { 6318, 6126, 5946, 5777, 5617, 5466, 5322, 5183, 5046,
- 4910, 4770, 4622, 4464, 4291, 4101, 3891, 3661, 3411,
- 3142, 2857, 2558, 2250, 1938, 1625, 1318, 1019, 730,
- 454, 189, -67, -318, -570, -827, -1096, -1381, -1685,
- -2009, -2354, -2717, -3095, -3485, -3881, -4279, -4676, -5068,
- -5453, -5828, -6193, -6546, -6887, -7218, -7538, -7849, -8152,
- -8450, -8744, -9037, -9335, -9645, -9979, -10368, -10886, -11809,
- -15193, 10922, 8778, 8037, 7595, 7264, 6988, 6744, 6523,
- 6318},
- /* -60 */
- { 4768, 4709, 4640, 4566, 4490, 4416, 4344, 4274, 4208,
- 4141, 4071, 3993, 3902, 3794, 3663, 3505, 3318, 3100,
- 2852, 2578, 2280, 1965, 1640, 1313, 991, 682, 392,
- 123, -125, -354, -569, -778, -991, -1215, -1458, -1726,
- -2023, -2347, -2695, -3064, -3445, -3833, -4220, -4600, -4969,
- -5323, -5658, -5972, -6264, -6532, -6776, -6993, -7181, -7338,
- -7458, -7532, -7546, -7474, -7273, -6857, -6058, -4557, -2058,
- 727, 2633, 3688, 4259, 4572, 4736, 4812, 4830, 4812,
- 4768},
- /* -55 */
- { 3771, 3768, 3750, 3720, 3685, 3647, 3611, 3577, 3546,
- 3519, 3492, 3462, 3421, 3364, 3283, 3171, 3023, 2835,
- 2607, 2339, 2036, 1705, 1356, 1001, 652, 319, 13,
- -261, -501, -709, -891, -1058, -1222, -1394, -1587, -1810,
- -2069, -2365, -2694, -3048, -3419, -3795, -4168, -4529, -4871,
- -5189, -5479, -5737, -5961, -6148, -6293, -6394, -6445, -6436,
- -6355, -6184, -5896, -5455, -4817, -3939, -2818, -1532, -251,
- 866, 1747, 2404, 2878, 3214, 3446, 3600, 3697, 3750,
- 3771},
- /* -50 */
- { 3099, 3120, 3123, 3115, 3098, 3077, 3056, 3036, 3021,
- 3011, 3006, 3001, 2992, 2971, 2929, 2856, 2743, 2584,
- 2373, 2111, 1800, 1449, 1071, 680, 294, -71, -401,
- -686, -925, -1118, -1273, -1401, -1516, -1633, -1767, -1932,
- -2138, -2392, -2689, -3021, -3374, -3734, -4089, -4425, -4736,
- -5014, -5253, -5450, -5601, -5700, -5743, -5724, -5634, -5465,
- -5202, -4832, -4344, -3732, -3008, -2203, -1368, -556, 188,
- 839, 1387, 1838, 2201, 2485, 2704, 2865, 2979, 3054,
- 3099},
- /* -45 */
- { 2611, 2642, 2656, 2658, 2651, 2639, 2625, 2610, 2598,
- 2592, 2591, 2595, 2601, 2600, 2583, 2539, 2456, 2321,
- 2128, 1871, 1554, 1183, 774, 346, -76, -472, -823,
- -1120, -1357, -1540, -1675, -1774, -1850, -1915, -1987, -2083,
- -2220, -2411, -2657, -2951, -3276, -3612, -3941, -4248, -4522,
- -4755, -4940, -5073, -5147, -5158, -5102, -4972, -4762, -4467,
- -4083, -3612, -3068, -2474, -1858, -1251, -675, -141, 343,
- 777, 1161, 1495, 1781, 2020, 2214, 2366, 2479, 2559,
- 2611},
- /* -40 */
- { 2236, 2269, 2287, 2295, 2295, 2289, 2279, 2266, 2253,
- 2243, 2238, 2239, 2245, 2250, 2246, 2220, 2157, 2043,
- 1864, 1613, 1290, 903, 468, 12, -438, -854, -1216,
- -1513, -1745, -1916, -2038, -2121, -2172, -2202, -2220, -2243,
- -2294, -2397, -2566, -2798, -3077, -3376, -3672, -3945, -4180,
- -4367, -4499, -4570, -4575, -4509, -4370, -4157, -3867, -3504,
- -3076, -2600, -2099, -1602, -1131, -697, -301, 62, 396,
- 706, 992, 1252, 1485, 1688, 1860, 1999, 2106, 2183,
- 2236},
- /* -35 */
- { 1934, 1966, 1985, 1996, 2001, 2000, 1994, 1982, 1967,
- 1952, 1939, 1932, 1930, 1932, 1930, 1911, 1860, 1758,
- 1589, 1343, 1016, 618, 167, -305, -767, -1187, -1544,
- -1830, -2047, -2204, -2315, -2387, -2426, -2432, -2406, -2360,
- -2315, -2308, -2368, -2508, -2716, -2964, -3222, -3462, -3666,
- -3818, -3909, -3934, -3888, -3771, -3584, -3331, -3015, -2645,
- -2236, -1809, -1390, -1003, -658, -355, -85, 165, 403,
- 634, 856, 1066, 1261, 1436, 1588, 1714, 1813, 1885,
- 1934},
- /* -30 */
- { 1687, 1715, 1732, 1744, 1752, 1755, 1753, 1744, 1728,
- 1709, 1689, 1672, 1660, 1653, 1647, 1629, 1581, 1485,
- 1321, 1075, 746, 343, -113, -588, -1045, -1453, -1792,
- -2056, -2251, -2390, -2484, -2542, -2565, -2544, -2475, -2360,
- -2220, -2093, -2026, -2049, -2164, -2349, -2568, -2786, -2976,
- -3116, -3193, -3201, -3138, -3007, -2815, -2567, -2271, -1936,
- -1577, -1218, -883, -590, -345, -140, 41, 212, 385,
- 563, 742, 918, 1085, 1238, 1374, 1488, 1578, 1643,
- 1687},
- /* -25 */
- { 1485, 1507, 1520, 1530, 1539, 1544, 1545, 1539, 1525,
- 1504, 1479, 1454, 1434, 1420, 1407, 1385, 1336, 1239,
- 1074, 827, 497, 93, -359, -823, -1262, -1647, -1960,
- -2198, -2366, -2478, -2546, -2575, -2564, -2502, -2380, -2200,
- -1978, -1753, -1575, -1486, -1504, -1617, -1794, -1998, -2189,
- -2341, -2432, -2454, -2406, -2295, -2131, -1920, -1670, -1388,
- -1089, -796, -531, -312, -141, -8, 108, 224, 353,
- 495, 646, 798, 945, 1082, 1204, 1308, 1389, 1447,
- 1485},
- /* -20 */
- { 1322, 1337, 1344, 1350, 1356, 1363, 1366, 1363, 1351,
- 1330, 1303, 1275, 1249, 1230, 1212, 1186, 1132, 1030,
- 859, 609, 278, -121, -561, -1006, -1420, -1775, -2058,
- -2264, -2401, -2478, -2506, -2489, -2425, -2309, -2134, -1903,
- -1633, -1359, -1122, -961, -902, -945, -1074, -1254, -1445,
- -1612, -1727, -1778, -1764, -1691, -1570, -1409, -1213, -986,
- -743, -504, -294, -131, -15, 66, 135, 213, 311,
- 430, 563, 699, 832, 957, 1070, 1165, 1240, 1291,
- 1322},
- /* -15 */
- { 1194, 1201, 1202, 1201, 1204, 1209, 1213, 1211, 1202,
- 1183, 1157, 1128, 1101, 1080, 1059, 1028, 968, 858,
- 680, 425, 94, -296, -718, -1138, -1522, -1846, -2096,
- -2268, -2367, -2401, -2378, -2304, -2182, -2013, -1798, -1545,
- -1270, -996, -752, -566, -462, -451, -529, -673, -849,
- -1019, -1151, -1228, -1246, -1212, -1135, -1023, -876, -700,
- -505, -311, -145, -23, 53, 97, 133, 184, 262,
- 366, 488, 615, 739, 856, 963, 1054, 1124, 1170,
- 1194},
- /* -10 */
- { 1097, 1098, 1090, 1083, 1081, 1083, 1087, 1087, 1080,
- 1063, 1039, 1011, 986, 965, 943, 906, 838, 718,
- 531, 271, -56, -434, -835, -1226, -1578, -1869, -2085,
- -2221, -2279, -2265, -2188, -2059, -1886, -1678, -1446, -1198,
- -946, -703, -482, -302, -181, -135, -170, -275, -425,
- -583, -719, -810, -851, -848, -808, -736, -633, -500,
- -346, -191, -59, 32, 78, 96, 109, 141, 205,
- 300, 415, 537, 658, 772, 877, 966, 1035, 1078,
- 1097},
- /* -5 */
- { 1026, 1022, 1009, 995, 988, 987, 990, 992, 987,
- 973, 951, 926, 903, 882, 856, 813, 734, 603,
- 407, 144, -179, -542, -919, -1281, -1601, -1858, -2038,
- -2136, -2152, -2094, -1971, -1797, -1589, -1363, -1131, -903,
- -685, -480, -293, -131, -10, 55, 50, -22, -143,
- -284, -412, -507, -561, -578, -565, -525, -457, -360,
- -242, -121, -18, 47, 71, 69, 66, 85, 140,
- 229, 339, 460, 580, 695, 803, 895, 966, 1010,
- 1026},
- /* 0 */
- { 975, 971, 953, 935, 924, 922, 926, 930, 928,
- 917, 898, 875, 852, 828, 796, 743, 651, 506,
- 300, 34, -282, -629, -981, -1314, -1601, -1823, -1967,
- -2028, -2006, -1910, -1753, -1553, -1327, -1096, -873, -669,
- -484, -315, -160, -20, 94, 166, 181, 134, 38,
- -84, -201, -293, -352, -380, -384, -367, -327, -261,
- -175, -84, -9, 33, 39, 23, 8, 17, 64,
- 147, 255, 375, 497, 617, 731, 831, 908, 957,
- 975},
- /* 5 */
- { 937, 936, 920, 901, 890, 888, 895, 902, 904,
- 897, 880, 858, 832, 803, 761, 693, 584, 423,
- 205, -65, -374, -704, -1031, -1333, -1587, -1773, -1881,
- -1906, -1853, -1730, -1554, -1341, -1112, -885, -675, -490,
- -331, -191, -62, 58, 162, 235, 260, 231, 154,
- 50, -56, -142, -201, -234, -249, -248, -228, -188,
- -130, -67, -18, 2, -9, -38, -64, -63, -24,
- 52, 157, 276, 402, 529, 652, 763, 852, 911,
- 937},
- /* 10 */
- { 901, 911, 902, 889, 881, 883, 895, 908, 916,
- 913, 899, 876, 845, 806, 749, 662, 532, 352,
- 120, -155, -459, -773, -1076, -1347, -1565, -1715, -1787,
- -1781, -1703, -1564, -1380, -1167, -942, -724, -526, -357,
- -216, -96, 13, 117, 210, 280, 312, 294, 232,
- 142, 47, -33, -89, -125, -145, -153, -149, -129,
- -97, -61, -38, -40, -67, -110, -146, -156, -127,
- -58, 40, 159, 289, 424, 559, 683, 787, 861,
- 901},
- /* 15 */
- { 859, 887, 893, 892, 893, 904, 924, 945, 959,
- 962, 950, 925, 888, 836, 760, 651, 497, 294,
- 45, -238, -540, -841, -1120, -1360, -1542, -1655, -1694,
- -1661, -1565, -1418, -1234, -1028, -812, -604, -416, -257,
- -128, -21, 75, 165, 249, 315, 349, 340, 290,
- 212, 127, 53, 0, -35, -58, -73, -80, -78,
- -68, -58, -61, -85, -131, -189, -238, -260, -243,
- -185, -94, 22, 155, 298, 445, 584, 706, 799,
- 859},
- /* 20 */
- { 803, 856, 885, 903, 921, 945, 976, 1006, 1029,
- 1037, 1027, 1000, 955, 888, 793, 658, 478, 250,
- -18, -314, -617, -908, -1167, -1377, -1524, -1602, -1610,
- -1554, -1446, -1296, -1117, -920, -715, -516, -336, -184,
- -60, 40, 127, 208, 284, 346, 381, 379, 339,
- 273, 198, 131, 81, 46, 22, 3, -14, -27,
- -38, -54, -83, -131, -198, -273, -338, -374, -371,
- -326, -244, -131, 3, 153, 310, 464, 605, 720,
- 803},
- /* 25 */
- { 731, 813, 871, 916, 957, 1000, 1045, 1086, 1117,
- 1131, 1123, 1094, 1040, 958, 842, 682, 475, 221,
- -70, -381, -690, -976, -1218, -1402, -1518, -1565, -1546,
- -1472, -1354, -1203, -1030, -841, -646, -455, -281, -130,
- -8, 90, 173, 249, 318, 377, 413, 418, 389,
- 336, 273, 214, 167, 134, 107, 83, 57, 29,
- -4, -45, -101, -176, -267, -361, -444, -497, -509,
- -477, -404, -296, -162, -7, 159, 326, 483, 621,
- 731},
- /* 30 */
- { 643, 756, 848, 926, 996, 1062, 1124, 1178, 1217,
- 1235, 1230, 1197, 1134, 1038, 902, 718, 484, 203,
- -113, -443, -762, -1046, -1276, -1439, -1530, -1551, -1511,
- -1422, -1297, -1145, -975, -792, -604, -418, -246, -96,
- 29, 129, 213, 287, 354, 411, 450, 464, 449,
- 411, 362, 313, 272, 238, 208, 176, 139, 94,
- 38, -31, -117, -220, -337, -454, -556, -626, -654,
- -634, -569, -466, -331, -174, -1, 176, 348, 506,
- 643},
- /* 35 */
- { 547, 691, 818, 930, 1031, 1123, 1205, 1273, 1321,
- 1345, 1340, 1304, 1234, 1124, 968, 760, 499, 189,
- -153, -505, -837, -1125, -1347, -1495, -1567, -1570, -1514,
- -1413, -1281, -1126, -956, -776, -590, -406, -233, -80,
- 50, 157, 246, 323, 392, 452, 498, 523, 525,
- 507, 476, 440, 405, 371, 335, 292, 239, 173,
- 90, -10, -129, -265, -411, -553, -675, -761, -801,
- -792, -734, -633, -499, -338, -161, 25, 210, 386,
- 547},
- /* 40 */
- { 454, 626, 784, 929, 1061, 1180, 1283, 1366, 1424,
- 1454, 1452, 1413, 1335, 1211, 1036, 804, 513, 173,
- -199, -576, -925, -1219, -1439, -1577, -1637, -1627, -1560,
- -1450, -1311, -1152, -978, -795, -607, -422, -245, -85,
- 54, 172, 271, 358, 435, 504, 562, 603, 627,
- 632, 622, 602, 575, 541, 497, 439, 365, 271,
- 156, 19, -139, -312, -489, -657, -799, -900, -950,
- -947, -892, -792, -656, -492, -310, -117, 79, 271,
- 454},
- /* 45 */
- { 374, 569, 754, 927, 1087, 1230, 1354, 1454, 1525,
- 1563, 1565, 1525, 1439, 1301, 1105, 845, 522, 145,
- -262, -668, -1037, -1341, -1562, -1696, -1748, -1729, -1654,
- -1538, -1392, -1225, -1045, -855, -661, -469, -284, -114,
- 39, 172, 289, 392, 486, 572, 648, 712, 761,
- 793, 808, 807, 790, 756, 702, 627, 526, 397,
- 241, 59, -144, -359, -573, -769, -930, -1043, -1099,
- -1098, -1042, -940, -799, -630, -442, -241, -34, 172,
- 374},
- /* 50 */
- { 313, 526, 732, 928, 1110, 1276, 1419, 1536, 1622,
- 1671, 1679, 1641, 1549, 1396, 1175, 882, 518, 96,
- -355, -797, -1192, -1508, -1733, -1864, -1910, -1885, -1804,
- -1680, -1526, -1350, -1159, -960, -755, -552, -354, -168,
- 4, 160, 301, 430, 549, 661, 764, 857, 935,
- 997, 1040, 1060, 1055, 1023, 960, 864, 731, 561,
- 355, 119, -139, -405, -660, -886, -1066, -1187, -1245,
- -1241, -1181, -1072, -925, -749, -552, -342, -125, 94,
- 313},
- /* 55 */
- { 270, 499, 721, 935, 1135, 1319, 1480, 1614, 1716,
- 1779, 1797, 1761, 1664, 1495, 1245, 909, 490, 9,
- -500, -988, -1413, -1744, -1971, -2099, -2138, -2105, -2015,
- -1881, -1716, -1528, -1324, -1110, -890, -670, -454, -246,
- -48, 137, 311, 475, 629, 776, 914, 1041, 1155,
- 1250, 1322, 1366, 1377, 1351, 1281, 1164, 997, 779,
- 514, 211, -114, -441, -744, -1003, -1201, -1329, -1387,
- -1377, -1308, -1191, -1034, -849, -642, -422, -194, 38,
- 270},
- /* 60 */
- { 240, 482, 719, 946, 1162, 1361, 1539, 1690, 1808,
- 1886, 1914, 1882, 1779, 1590, 1302, 908, 415, -149,
- -734, -1280, -1738, -2081, -2305, -2422, -2447, -2399, -2294,
- -2145, -1963, -1758, -1536, -1302, -1062, -819, -577, -340,
- -110, 113, 326, 532, 730, 919, 1099, 1267, 1420,
- 1551, 1657, 1730, 1764, 1749, 1680, 1548, 1349, 1080,
- 747, 364, -44, -446, -809, -1108, -1328, -1464, -1519,
- -1502, -1424, -1297, -1130, -934, -717, -487, -247, -4,
- 240},
- /* 65 */
- { 214, 468, 717, 957, 1186, 1399, 1592, 1759, 1891,
- 1982, 2018, 1988, 1872, 1652, 1308, 830, 230, -448,
- -1130, -1738, -2220, -2559, -2763, -2853, -2849, -2773, -2641,
- -2467, -2260, -2030, -1782, -1523, -1255, -983, -709, -437,
- -168, 96, 355, 608, 853, 1090, 1316, 1529, 1725,
- 1899, 2044, 2155, 2220, 2232, 2178, 2047, 1828, 1514,
- 1111, 635, 124, -376, -819, -1174, -1426, -1577, -1635,
- -1615, -1530, -1394, -1218, -1013, -787, -546, -296, -42,
- 214},
- /* 70 */
- { 178, 442, 702, 955, 1195, 1421, 1625, 1802, 1944,
- 2040, 2074, 2030, 1881, 1600, 1159, 546, -215, -1041,
- -1821, -2461, -2924, -3215, -3362, -3394, -3337, -3214, -3040,
- -2827, -2585, -2320, -2040, -1747, -1445, -1138, -828, -517,
- -207, 101, 406, 706, 999, 1283, 1558, 1819, 2062,
- 2284, 2479, 2637, 2752, 2811, 2799, 2700, 2496, 2170,
- 1716, 1147, 511, -125, -689, -1136, -1450, -1637, -1714,
- -1702, -1619, -1481, -1302, -1092, -859, -611, -352, -88,
- 178},
- /* 75 */
- { 114, 385, 652, 911, 1157, 1386, 1592, 1767, 1899,
- 1975, 1973, 1868, 1622, 1193, 548, -307, -1284, -2226,
- -2997, -3542, -3876, -4038, -4070, -4006, -3869, -3677, -3445,
- -3182, -2895, -2589, -2269, -1939, -1600, -1257, -909, -559,
- -210, 140, 486, 829, 1167, 1497, 1818, 2128, 2423,
- 2698, 2951, 3173, 3356, 3491, 3562, 3550, 3431, 3177,
- 2759, 2165, 1420, 605, -165, -797, -1254, -1540, -1684,
- -1714, -1659, -1539, -1370, -1166, -936, -687, -426, -157,
- 114},
- /* 80 */
- { -8, 249, 501, 742, 965, 1164, 1327, 1442, 1489,
- 1441, 1262, 902, 306, -553, -1618, -2716, -3648, -4317,
- -4731, -4941, -4998, -4945, -4811, -4617, -4378, -4104, -3804,
- -3483, -3146, -2796, -2436, -2068, -1693, -1315, -933, -549,
- -164, 220, 603, 984, 1361, 1733, 2099, 2457, 2805,
- 3140, 3459, 3758, 4031, 4273, 4472, 4616, 4686, 4657,
- 4492, 4146, 3573, 2755, 1755, 731, -142, -778, -1181,
- -1395, -1468, -1438, -1333, -1176, -980, -758, -517, -265,
- -8},
- /* 85 */
- { -546, -534, -552, -627, -794, -1097, -1585, -2300, -3236,
- -4294, -5297, -6100, -6655, -6988, -7144, -7167, -7093, -6945,
- -6742, -6496, -6217, -5912, -5585, -5241, -4883, -4513, -4134,
- -3746, -3352, -2952, -2547, -2138, -1726, -1312, -896, -478,
- -60, 359, 778, 1196, 1612, 2028, 2441, 2851, 3257,
- 3660, 4057, 4448, 4831, 5205, 5567, 5916, 6248, 6558,
- 6841, 7088, 7287, 7421, 7465, 7378, 7100, 6543, 5611,
- 4289, 2795, 1493, 572, 0, -325, -488, -553, -561,
- -546},
- /* 90 */
- { -17825, -17325, -16825, -16325, -15825, -15325, -14825, -14325, -13825,
- -13325, -12825, -12325, -11825, -11325, -10825, -10325, -9825, -9325,
- -8825, -8325, -7825, -7325, -6825, -6325, -5825, -5325, -4825,
- -4325, -3825, -3325, -2825, -2325, -1825, -1325, -825, -325,
- 175, 675, 1175, 1675, 2175, 2675, 3175, 3675, 4175,
- 4675, 5175, 5675, 6175, 6675, 7175, 7675, 8175, 8675,
- 9175, 9675, 10175, 10675, 11175, 11675, 12175, 12675, 13175,
- 13675, 14175, 14675, 15175, 15675, 16175, 16675, 17175, 17675,
- -17825}
- };
- /* *INDENT-ON* */
- /* compute bilinear approximation
- * since our data set rows and columns are integer degree, the corner
- * points can be integers.
- *
- * since the geoid_delta is shorts, the z11, z12, z21 an z22 can be ints.
- */
- static double bilinear(int x1, int y1, int x2, int y2, double x,
- double y, int z11, int z12, int z21,
- int z22)
- {
- int delta;
- double xx1 = x - x1;
- double x2x = x2 - x;
- double yy1 = y - y1;
- double y2y = y2 - y;
- /* handle some corner cases */
- if (y1 == y2) {
- if (x1 == x2)
- return z11;
- else
- return (z22 * (xx1) + z11 * (x2x)) / (x2 - x1);
- } else if (x1 == x2) {
- return (z22 * (yy1) + z11 * (y2y)) / (y2 - y1);
- }
- delta = (y2 - y1) * (x2 - x1);
- #ifdef __UNUSED
- fprintf(stderr, "x1 %d x2 %d y1 %d y2 %d delta %d\n",
- x1, x2, y1, y2, delta);
- #endif
- return (z22 * yy1 * xx1 + z12 * y2y * xx1 +
- z21 * yy1 * x2x + z11 * y2y * x2x) / delta;
- }
- /* return geoid separation (MSL-WGS84) in meters, given a lat/lon in degrees.
- * Online calculator here:
- * https://geographiclib.sourceforge.io/cgi-bin/GeoidEval
- *
- * Or use GeoidEval from the geographiclib.
- *
- * The value for any lat/lon is computed from the 5x5 using bilinear
- * interpolation. Should probably use cubic interpolation as GeoidEval
- * does by default?
- *
- * Calculated separation can differ from geoidEval by up to 12m!
- */
- double wgs84_separation(double lat, double lon)
- {
- int ilat, ilon;
- int ilat1, ilat2, ilon1, ilon2;
- const int span = 5;
- if (0 == isfinite(lat) ||
- 0 == isfinite(lon)) {
- return 0.0;
- }
- /* ilat is 0 to 18
- * lat -90 (90S) is ilat 0
- * lat 0 is ilat 9
- * lat 90 (90N) is ilat 18 */
- ilat = (int)floor((90. + lat) / span);
- /* ilon is 0 to 36
- * lon -180 is ilon 0
- * long 0 (Prime Median) is ilon 18
- * long 180 is ilon 36 */
- ilon = (int)floor((180. + lon) / span);
- /* sanity checks to prevent segfault on bad data */
- if ((GEOID_ROW <= ilat) || (0 > ilat) ||
- (GEOID_COL <= ilon) || (0 > ilon))
- return 0.0;
- ilat1 = ilat;
- ilon1 = ilon;
- ilat2 = (ilat < GEOID_ROW - 1) ? ilat + 1 : ilat;
- ilon2 = (ilon < GEOID_COL - 1) ? ilon + 1 : ilon;
- #ifdef __UNUSED
- fprintf(stderr, "ilat1 %3d lat %9.4f ilat2 %3d\n"
- "ilon1 %3d lon %9.4f ilon2 %3d\n",
- ilat1, lat, ilat2,
- ilon1, lon, ilon2);
- #endif
- /* the "/ 100" is to convert cm to meters */
- return bilinear(ilon1 * span - 180, ilat1 * span - 90,
- ilon2 * span - 180, ilat2 * span - 90,
- lon, lat,
- geoid_delta[ilat1][ilon1],
- geoid_delta[ilat1][ilon2],
- geoid_delta[ilat2][ilon1],
- geoid_delta[ilat2][ilon2]
- ) / 100;
- }
- /* return magnetic variation (deviation) degrees, given a lat/lon in degrees.
- * Online calculator here:
- * https://www.ngdc.noaa.gov/geomag/calculators/magcalc.shtml
- *
- * Or use MagneticField from the geographiclib.
- *
- * The value for any lat/lon is computed from the 5x5 using bilinear
- * interpolation.
- *
- * Substantially similar code to wgs84_separation() but may
- * diverge eventually, so separate.
- *
- */
- double mag_var(double lat, double lon)
- {
- int ilat, ilon;
- int ilat1, ilat2, ilon1, ilon2;
- const int span = 5;
- if (0 == isfinite(lat) ||
- 0 == isfinite(lon)) {
- return 0.0;
- }
- /* ilat is 0 to 18
- * lat -90 (90S) is ilat 0
- * lat 0 is ilat 9
- * lat 90 (90N) is ilat 18 */
- ilat = (int)floor((90. + lat) / span);
- /* ilon is 0 to 36
- * lon -180 is ilon 0
- * long 0 (Prime Median) is ilon 18
- * long 180 is ilon 36 */
- ilon = (int)floor((180. + lon) / span);
- /* sanity checks to prevent segfault on bad data */
- if ((GEOID_ROW <= ilat) || (0 > ilat) ||
- (GEOID_COL <= ilon) || (0 > ilon))
- return 0.0;
- ilat1 = ilat;
- ilon1 = ilon;
- ilat2 = (ilat < GEOID_ROW - 1) ? ilat + 1 : ilat;
- ilon2 = (ilon < GEOID_COL - 1) ? ilon + 1 : ilon;
- #ifdef __UNUSED
- fprintf(stderr, "ilat1 %3d lat %9.4f ilat2 %3d\n"
- "ilon1 %3d lon %9.4f ilon2 %3d\n",
- ilat1, lat, ilat2,
- ilon1, lon, ilon2);
- fprintf(stderr, "12 %3d 22 %3d\n"
- "11 %3d 12 %3d\n",
- magvar[ilat1][ilon1],
- magvar[ilat1][ilon2],
- magvar[ilat2][ilon1],
- magvar[ilat2][ilon2]);
- #endif
- /* the "/ 100" is to convert cm to meters */
- return bilinear(ilon1 * span - 180, ilat1 * span - 90,
- ilon2 * span - 180, ilat2 * span - 90,
- lon, lat,
- magvar[ilat1][ilon1],
- magvar[ilat1][ilon2],
- magvar[ilat2][ilon1],
- magvar[ilat2][ilon2]
- ) / 100;
- }
- /* fill in WGS84 position/velocity fields from ECEF coordinates
- * x, y, z are all in meters
- * vx, vy, vz are all in meters/second
- */
- gps_mask_t ecef_to_wgs84fix(struct gps_fix_t *fix,
- double x, double y, double z,
- double vx, double vy, double vz)
- {
- double lambda, phi, p, theta, n,vnorth, veast, vup;
- double cos_lambda, sin_lambda;
- double cos_phi, sin_phi;
- double cos_theta, sin_theta;
- gps_mask_t mask = 0;
- if (0 == isfinite(x) ||
- 0 == isfinite(y) ||
- 0 == isfinite(z)) {
- /* invalid inputs */
- return mask;
- }
- /* geodetic location */
- lambda = atan2(y, x);
- sincos(lambda, &sin_lambda, &cos_lambda);
- p = sqrt(pow(x, 2) + pow(y, 2));
- theta = atan2(z * WGS84A, p * WGS84B);
- sincos(theta, &sin_theta, &cos_theta);
- phi = atan2(z + WGS84E2 * WGS84B * pow(sin_theta, 3),
- p - WGS84E * WGS84A * pow(cos_theta, 3));
- sincos(phi, &sin_phi, &cos_phi);
- n = WGS84A / sqrt(1.0 - WGS84E * pow(sin_phi, 2));
- /* altitude is WGS84 */
- fix->altHAE = (p / cos_phi) - n;
- fix->latitude = phi * RAD_2_DEG;
- fix->longitude = lambda * RAD_2_DEG;
- mask |= LATLON_SET | ALTITUDE_SET;
- /* velocity computation */
- vnorth = -vx * sin_phi * cos_lambda - vy * sin_phi * sin_lambda +
- vz * cos_phi;
- veast = -vx * sin_lambda + vy * cos_lambda;
- vup = vx * cos_phi * cos_lambda + vy * cos_phi * sin_lambda + vz * sin_phi;
- /* save velNED */
- fix->NED.velN = vnorth;
- fix->NED.velE = veast;
- fix->NED.velD = -vup;
- mask |= VNED_SET;
- /* velNED is saved, let gpsd_error_model() do the
- * sanity checks and calculate climb/speed/track */
- return mask;
- }
- #ifdef __UNUSED
- /*
- * Some systems propagate the sign along with zero. This messes up
- * certain trig functions, like atan2():
- * atan2(+0, +0) = 0
- * atan2(+0, -0) = PI
- * Obviously that will break things. Luckily the "==" operator thinks
- * that -0 == +0; we will use this to return an unambiguous value.
- *
- * I hereby decree that zero is not allowed to have a negative sign!
- */
- static double fix_minuz(double d)
- {
- return ((d == 0.0) ? 0.0 : d);
- }
- /* atan2() protected by fix_minuz() */
- static double atan2z(double y, double x)
- {
- return atan2(fix_minuz(y), fix_minuz(x));
- }
- #endif /* __UNUSED */
|