11
11
"""
12
12
13
13
import re
14
+ import math
14
15
from ..exceptions import SbpyException
15
16
16
17
__all__ = ['Names' , 'TargetNameParseError' , 'natural_sort_key' ]
@@ -68,6 +69,9 @@ class Names():
68
69
pkd = ('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
69
70
'abcdefghijklmnopqrstuvwxyz' )
70
71
72
+ # packed numbers translation string with no I
73
+ pkd_noI = 'ABCDEFGHJKLMNOPQRSTUVWXYZ'
74
+
71
75
@staticmethod
72
76
def to_packed (s ):
73
77
"""Convert designation or number to packed identifier.
@@ -94,14 +98,22 @@ def to_packed(s):
94
98
s = int (s )
95
99
if s < 100000 :
96
100
return '{:05d}' .format (s )
97
- elif s > 619999 :
98
- raise TargetNameParseError (
99
- '{} cannot be turned into a packed number' .format (s )
100
- )
101
- else :
101
+ elif (s > 99999 and s < 620000 ):
102
102
mod = (s % 10000 )
103
103
return '{}{:04d}' .format (
104
104
Names .pkd [int ((s - mod ) / 10000 )], mod )
105
+ elif (s > 619999 and s < 15396336 ):
106
+ s = s - 620000
107
+ d = ['0' , '0' , '0' , '0' ]
108
+ for idx in reversed (range (0 , 4 )):
109
+ d [idx ] = Names .pkd [math .floor (s % 62 )]
110
+ s //= 62
111
+ return ('~' + '' .join (d ))
112
+ else :
113
+ raise TargetNameParseError (
114
+ '{} cannot be turned into a packed number' .format (s )
115
+ )
116
+
105
117
elif s .endswith ('P-L' ):
106
118
return 'PLS{}' .format (s [:4 ])
107
119
elif s [- 3 :] in ['T-1' , 'T-2' , 'T-3' ]:
@@ -123,42 +135,61 @@ def to_packed(s):
123
135
frag = '0'
124
136
num = s [6 :]
125
137
126
- if num == '' :
127
- num = '00'
128
- elif len ( num ) == 1 :
129
- num = '0' + num
130
- elif len ( num ) > 2 :
131
- try :
138
+ try :
139
+ if num == '' :
140
+ num = '00'
141
+ elif len ( num ) == 1 :
142
+ num = '0' + num
143
+ elif len ( num ) > 2 :
132
144
num = Names .pkd [int (num [:- 1 ])]+ num [- 1 ]
133
- except ( IndexError , ValueError ):
134
- raise TargetNameParseError (
135
- ( '{} cannot be turned into a '
136
- 'packed designation' ). format ( s ))
137
- return '{}{}{}{}{}' . format (
138
- Names . pkd [ int ( float ( s [: 2 ]))],
139
- s [ 2 : 4 ],
140
- s [ 5 ],
141
- num ,
142
- frag . lower ()
143
- )
145
+ return '{}{}{}{}{}' . format (
146
+ Names . pkd [ int ( float ( s [: 2 ]))],
147
+ s [ 2 : 4 ],
148
+ s [ 5 ],
149
+ num ,
150
+ frag . lower ()
151
+ )
152
+ except ( IndexError , ValueError ):
153
+ raise TargetNameParseError (
154
+ ( '{} cannot be turned into a '
155
+ 'packed designation' ). format ( s ) )
144
156
else :
145
- yr = s .strip ()[:4 ]
146
- yr = Names .pkd [int (yr [:2 ])] + yr [2 :]
147
- let = s .strip ()[4 :7 ].strip ()
148
- num = s .strip ()[7 :].strip ()
149
- if num == '' :
150
- num = '00'
151
- elif len (num ) == 1 :
152
- num = '0' + num
153
- elif len (num ) > 2 :
154
- try :
155
- num = Names .pkd [int (num [:- 1 ])]+ num [- 1 ]
156
- except (IndexError , ValueError ):
157
- raise TargetNameParseError (
158
- ('{} cannot be turned into a '
159
- 'packed designation' ).format (s ))
160
- return (yr + let [0 ] + num + let [1 ])
161
-
157
+ try :
158
+ yr = s .strip ()[:4 ]
159
+ yr = Names .pkd [int (yr [:2 ])] + yr [2 :]
160
+ let = s .strip ()[4 :7 ].strip ()
161
+ num = s .strip ()[7 :].strip ()
162
+
163
+ if num == '' :
164
+ return (yr + let [0 ] + '00' + let [1 ])
165
+ elif len (num ) == 1 :
166
+ return (yr + let [0 ] + '0' + num + let [1 ])
167
+ elif len (num ) > 1 :
168
+ obj_num = int (num )* 25 + Names .pkd_noI .find (let [1 ]) + 1
169
+ # use original packed desigs for first 15500 objs per month
170
+ if obj_num < 15501 :
171
+ num = Names .pkd [int (num [:- 1 ])]+ num [- 1 ]
172
+ return (yr + let [0 ] + num + let [1 ])
173
+ # use extended packed desigs for >15500 objs per month
174
+ elif obj_num < 14791837 :
175
+ obj_num = obj_num - 15501
176
+ year = Names .pkd [int (yr [1 :])]
177
+ month = let [0 ]
178
+ d = ['0' , '0' , '0' , '0' ]
179
+ for idx in reversed (range (0 , 4 )):
180
+ d [idx ] = Names .pkd [math .floor (obj_num % 62 )]
181
+ obj_num //= 62
182
+ return ('_' + Names .pkd [int (yr [1 :])]+ let [0 ]+ '' .join (d ))
183
+ # if more than maximum of 14,791,836 objects per half-month
184
+ # accommodated by the extended provisional designation scheme
185
+ else :
186
+ raise TargetNameParseError (
187
+ ('{} cannot be turned into a '
188
+ 'packed number or designation' ).format (s ))
189
+ except (IndexError , ValueError ):
190
+ raise TargetNameParseError (
191
+ ('{} cannot be turned into a '
192
+ 'packed number or designation' ).format (s ))
162
193
else :
163
194
raise TargetNameParseError (
164
195
('{} cannot be turned into a '
@@ -189,6 +220,17 @@ def from_packed(p):
189
220
return int (p )
190
221
elif p [0 ].isalpha () and p [1 :].isdigit ():
191
222
return int (str (Names .pkd .find (p [0 ])) + p [1 :])
223
+ elif p [0 ] == '~' and p [1 :].isalnum ():
224
+ if len (p ) == 5 :
225
+ obj_num = 620000 + Names .pkd .find (p [1 ])* (62 ** 3 ) \
226
+ + Names .pkd .find (p [2 ])* (62 ** 2 ) \
227
+ + Names .pkd .find (p [3 ])* (62 ) \
228
+ + Names .pkd .find (p [4 ])
229
+ return int (obj_num )
230
+ else :
231
+ raise TargetNameParseError (
232
+ ('{} cannot be turned into an '
233
+ 'unpacked designation' ).format (p ))
192
234
193
235
# old designation style, e.g.: 1989AB
194
236
if (len (p .strip ()) < 7 and p [:4 ].isdigit () and p [4 :6 ].isalpha ()):
@@ -216,6 +258,27 @@ def from_packed(p):
216
258
(str (Names .pkd .find (p [4 ])) + p [5 ]).lstrip ('0' ),
217
259
'-{}' .format (p [6 ].upper ()) if p [6 ].islower () else ''
218
260
)
261
+ # MPC extended packed provisional designation
262
+ elif p [0 ] == '_' :
263
+ if (
264
+ (p [1 ].isalpha () and p [1 ].isupper ())
265
+ and re .search ("[A-H,J-Y]" , p [2 ])
266
+ and p [3 :].isalnum ()
267
+ and len (p ) == 7
268
+ ):
269
+ obj_num = 15501 + Names .pkd .find (p [3 ])* (62 ** 3 ) \
270
+ + Names .pkd .find (p [4 ])* (62 ** 2 ) \
271
+ + Names .pkd .find (p [5 ])* (62 ) \
272
+ + Names .pkd .find (p [6 ])
273
+ return '20{} {}{}{}' .format (
274
+ str (Names .pkd .find (p [1 ])),
275
+ p [2 ],
276
+ Names .pkd_noI [((obj_num - 1 ) % 25 )],
277
+ math .floor ((obj_num - 1 )/ 25 ))
278
+ else :
279
+ raise TargetNameParseError (
280
+ ('{} cannot be turned into an '
281
+ 'unpacked designation' ).format (p ))
219
282
else :
220
283
# nothing to do
221
284
return p
0 commit comments