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