clienthelpers.py 51 KB

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