1 | #!/usr/bin/python
|
---|
2 |
|
---|
3 | def to_dms(angle):
|
---|
4 | m = 60 * (angle % 1)
|
---|
5 | s = 60 * (m % 1)
|
---|
6 | return (int(angle), int(m), s)
|
---|
7 |
|
---|
8 | def encode(lat, long):
|
---|
9 | if lat < -90 or lat > 90:
|
---|
10 | raise ValueError("latitude out of range")
|
---|
11 | if lat == -90:
|
---|
12 | # South Pole special case.
|
---|
13 | return b''
|
---|
14 | if lat == 90:
|
---|
15 | # North Pole special case.
|
---|
16 | return b'\xff\xff'
|
---|
17 | # Wrap longitude to range [0,360).
|
---|
18 | while long >= 360:
|
---|
19 | long -= 360
|
---|
20 | while long < 0:
|
---|
21 | long += 360
|
---|
22 | lat = to_dms(lat + 90)
|
---|
23 | long = to_dms(long)
|
---|
24 | result = bytearray()
|
---|
25 | dd = lat[0] * 360 + long[0]
|
---|
26 | result.append(dd >> 8)
|
---|
27 | result.append(dd & 255)
|
---|
28 | m1 = (lat[1] // 4) << 4 | (long[1] // 4)
|
---|
29 | result.append(m1)
|
---|
30 | ms = (lat[1] % 4) << 6 | (long[1] % 4) << 4
|
---|
31 | ms |= int(lat[2] // 15) << 2 | int(long[2] // 15)
|
---|
32 | result.append(ms)
|
---|
33 | s2 = int(lat[2] % 15) << 4 | int(long[2] % 15)
|
---|
34 | result.append(s2)
|
---|
35 | s3 = (int(lat[2] / 15) & 0x0f) << 4 | (int(long[2] / 15) & 0x0f);
|
---|
36 | result.append(s3)
|
---|
37 |
|
---|
38 | # Remove trailing zeros.
|
---|
39 | while len(result) and result[-1] == 0:
|
---|
40 | result.pop()
|
---|
41 | return result
|
---|
42 |
|
---|
43 | def decode(value):
|
---|
44 | if len(value) == 0:
|
---|
45 | return (-90.0, 0.0)
|
---|
46 | if value == b'\xff\xff':
|
---|
47 | return (90.0, 0.0)
|
---|
48 | if len(value) == 1:
|
---|
49 | dd = 0
|
---|
50 | else:
|
---|
51 | dd = value[1]
|
---|
52 | dd |= (value[0] << 8)
|
---|
53 | lat = dd // 360;
|
---|
54 | long = dd % 360;
|
---|
55 | if len(value) > 2:
|
---|
56 | m1 = value[2]
|
---|
57 | lat_m = (m1 >> 4) * 4
|
---|
58 | long_m = (m1 & 15) * 4
|
---|
59 | if len(value) > 3:
|
---|
60 | ms = value[3]
|
---|
61 | lat_m += ms >> 6
|
---|
62 | long_m += (ms >> 4) & 3
|
---|
63 | lat_s = ((ms >> 2) & 3) * 15
|
---|
64 | long_s = (ms & 3) * 15
|
---|
65 | if len(value) > 4:
|
---|
66 | s2 = value[4]
|
---|
67 | lat_s += s2 >> 4
|
---|
68 | long_s += s2 & 15
|
---|
69 | if len(value) > 5:
|
---|
70 | s3 = value[5]
|
---|
71 | lat_s += ((s3 >> 4) + 0.5) / 16.0
|
---|
72 | long_s += ((s3 & 15) + 0.5) / 16.0
|
---|
73 | else:
|
---|
74 | lat_s += 0.5
|
---|
75 | long_s += 0.5
|
---|
76 | else:
|
---|
77 | lat_s += 7.5
|
---|
78 | long_s += 7.5
|
---|
79 | lat_m += lat_s / 60.0
|
---|
80 | long_m += long_s / 60.0
|
---|
81 | else:
|
---|
82 | lat_m += 2
|
---|
83 | long_m += 2
|
---|
84 | lat += lat_m / 60.0
|
---|
85 | long += long_m / 60.0
|
---|
86 | else:
|
---|
87 | lat += 0.5
|
---|
88 | long += 0.5
|
---|
89 | return (lat - 90, long)
|
---|