Package ais :: Module imo_001_14
[hide private]
[frames] | no frames]

Source Code for Module ais.imo_001_14

   1  #!/usr/bin/env python 
   2   
   3  __version__ = '$Revision: 4791 $'.split()[1] 
   4  __date__ = '$Date: 2008-01-09 $'.split()[1] 
   5  __author__ = 'xmlbinmsg' 
   6   
   7  __doc__=''' 
   8   
   9  Autogenerated python functions to serialize/deserialize binary messages. 
  10   
  11  Generated by: ./aisxmlbinmsg2py.py 
  12   
  13  Need to then wrap these functions with the outer AIS packet and then 
  14  convert the whole binary blob to a NMEA string.  Those functions are 
  15  not currently provided in this file. 
  16   
  17  serialize: python to ais binary 
  18  deserialize: ais binary to python 
  19   
  20  The generated code uses translators.py, binary.py, and aisstring.py 
  21  which should be packaged with the resulting files. 
  22   
  23   
  24  @requires: U{epydoc<http://epydoc.sourceforge.net/>} > 3.0alpha3 
  25  @requires: U{BitVector<http://cheeseshop.python.org/pypi/BitVector>} 
  26   
  27  @author: '''+__author__+''' 
  28  @version: ''' + __version__ +''' 
  29  @var __date__: Date of last svn commit 
  30  @undocumented: __version__ __author__ __doc__ parser 
  31  @status: under development 
  32  @license: Generated code has no license 
  33  @todo: FIX: put in a description of the message here with fields and types. 
  34  ''' 
  35   
  36  import sys 
  37  from decimal import Decimal 
  38  from BitVector import BitVector 
  39   
  40  import binary, aisstring 
  41   
  42  # FIX: check to see if these will be needed 
  43  TrueBV  = BitVector(bitstring="1") 
  44  "Why always rebuild the True bit?  This should speed things up a bunch" 
  45  FalseBV = BitVector(bitstring="0") 
  46  "Why always rebuild the False bit?  This should speed things up a bunch" 
  47   
  48   
  49  fieldList = ( 
  50          'MessageID', 
  51          'RepeatIndicator', 
  52          'UserID', 
  53          'SeqNum', 
  54          'DestinationID', 
  55          'RetransmitFlag', 
  56          'Spare', 
  57          'dac', 
  58          'fid', 
  59          'month', 
  60          'day', 
  61          'window1_longitude', 
  62          'window1_latitude', 
  63          'fromhour1', 
  64          'frommin1', 
  65          'tohour1', 
  66          'tomin1', 
  67          'curdir1', 
  68          'curspeed1', 
  69          'window2_longitude', 
  70          'window2_latitude', 
  71          'fromhour2', 
  72          'frommin2', 
  73          'tohour2', 
  74          'tomin2', 
  75          'curdir2', 
  76          'curspeed2', 
  77          'window3_longitude', 
  78          'window3_latitude', 
  79          'fromhour3', 
  80          'frommin3', 
  81          'tohour3', 
  82          'tomin3', 
  83          'curdir3', 
  84          'curspeed3', 
  85  ) 
  86   
  87  fieldListPostgres = ( 
  88          'MessageID', 
  89          'RepeatIndicator', 
  90          'UserID', 
  91          'SeqNum', 
  92          'DestinationID', 
  93          'RetransmitFlag', 
  94          'Spare', 
  95          'dac', 
  96          'fid', 
  97          'month', 
  98          'day', 
  99          'window1',      # PostGIS data type 
 100          'fromhour1', 
 101          'frommin1', 
 102          'tohour1', 
 103          'tomin1', 
 104          'curdir1', 
 105          'curspeed1', 
 106          'window2',      # PostGIS data type 
 107          'fromhour2', 
 108          'frommin2', 
 109          'tohour2', 
 110          'tomin2', 
 111          'curdir2', 
 112          'curspeed2', 
 113          'window3',      # PostGIS data type 
 114          'fromhour3', 
 115          'frommin3', 
 116          'tohour3', 
 117          'tomin3', 
 118          'curdir3', 
 119          'curspeed3', 
 120  ) 
 121   
 122  toPgFields = { 
 123          'window1_longitude':'window1', 
 124          'window1_latitude':'window1', 
 125          'window2_longitude':'window2', 
 126          'window2_latitude':'window2', 
 127          'window3_longitude':'window3', 
 128          'window3_latitude':'window3', 
 129  } 
 130  ''' 
 131  Go to the Postgis field names from the straight field name 
 132  ''' 
 133   
 134  fromPgFields = { 
 135          'window1':('window1_longitude','window1_latitude',), 
 136          'window2':('window2_longitude','window2_latitude',), 
 137          'window3':('window3_longitude','window3_latitude',), 
 138  } 
 139  ''' 
 140  Go from the Postgis field names to the straight field name 
 141  ''' 
 142   
 143  pgTypes = { 
 144          'window1':'POINT', 
 145          'window2':'POINT', 
 146          'window3':'POINT', 
 147  } 
 148  ''' 
 149  Lookup table for each postgis field name to get its type. 
 150  ''' 
 151   
152 -def encode(params, validate=False):
153 '''Create a imo_tidal_window binary message payload to pack into an AIS Msg imo_tidal_window. 154 155 Fields in params: 156 - MessageID(uint): AIS message number. Must be 6 (field automatically set to "6") 157 - RepeatIndicator(uint): Indicated how many times a message has been repeated 158 - UserID(uint): MMSI number of transmitter broadcasting the message 159 - SeqNum(uint): Sequence number as described in 5.3.1. Assigned to each station 160 - DestinationID(uint): Unique ship identification number (MMSI) 161 - RetransmitFlag(bool): Should be set upon retransmission 162 - Spare(uint): Must be 0 (field automatically set to "0") 163 - dac(uint): Designated Area Code - part 1 of the IAI (field automatically set to "1") 164 - fid(uint): Functional Identifier - part 2 of the IAI (field automatically set to "11") 165 - month(uint): UTC month 166 - day(uint): UTC day 167 - window1_longitude(decimal): Not sure what this position is for? Center? East West location 168 - window1_latitude(decimal): Not sure what this position is for? Center? North South location 169 - fromhour1(uint): From UTC hour 170 - frommin1(uint): From UTC minute 171 - tohour1(uint): To UTC hour 172 - tomin1(uint): To UTC minute 173 - curdir1(uint): Current direction 174 - curspeed1(udecimal): Current speed 175 - window2_longitude(decimal): Not sure what this position is for? Center? East West location 176 - window2_latitude(decimal): Not sure what this position is for? Center? North South location 177 - fromhour2(uint): From UTC hour 178 - frommin2(uint): From UTC minute 179 - tohour2(uint): To UTC hour 180 - tomin2(uint): To UTC minute 181 - curdir2(uint): Current direction 182 - curspeed2(udecimal): Current speed 183 - window3_longitude(decimal): Not sure what this position is for? Center? East West location 184 - window3_latitude(decimal): Not sure what this position is for? Center? North South location 185 - fromhour3(uint): From UTC hour 186 - frommin3(uint): From UTC minute 187 - tohour3(uint): To UTC hour 188 - tomin3(uint): To UTC minute 189 - curdir3(uint): Current direction 190 - curspeed3(udecimal): Current speed 191 @param params: Dictionary of field names/values. Throws a ValueError exception if required is missing 192 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented. 193 @rtype: BitVector 194 @return: encoded binary message (for binary messages, this needs to be wrapped in a msg 8 195 @note: The returned bits may not be 6 bit aligned. It is up to you to pad out the bits. 196 ''' 197 198 bvList = [] 199 bvList.append(binary.setBitVectorSize(BitVector(intVal=6),6)) 200 if 'RepeatIndicator' in params: 201 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['RepeatIndicator']),2)) 202 else: 203 bvList.append(binary.setBitVectorSize(BitVector(intVal=0),2)) 204 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['UserID']),30)) 205 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['SeqNum']),2)) 206 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['DestinationID']),30)) 207 if params["RetransmitFlag"]: bvList.append(TrueBV) 208 else: bvList.append(FalseBV) 209 bvList.append(binary.setBitVectorSize(BitVector(intVal=0),1)) 210 bvList.append(binary.setBitVectorSize(BitVector(intVal=1),10)) 211 bvList.append(binary.setBitVectorSize(BitVector(intVal=11),6)) 212 if 'month' in params: 213 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['month']),4)) 214 else: 215 bvList.append(binary.setBitVectorSize(BitVector(intVal=0),4)) 216 if 'day' in params: 217 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['day']),5)) 218 else: 219 bvList.append(binary.setBitVectorSize(BitVector(intVal=0),5)) 220 if 'window1_longitude' in params: 221 bvList.append(binary.bvFromSignedInt(int(Decimal(params['window1_longitude'])*Decimal('600000')),28)) 222 else: 223 bvList.append(binary.bvFromSignedInt(108600000,28)) 224 if 'window1_latitude' in params: 225 bvList.append(binary.bvFromSignedInt(int(Decimal(params['window1_latitude'])*Decimal('600000')),27)) 226 else: 227 bvList.append(binary.bvFromSignedInt(54600000,27)) 228 if 'fromhour1' in params: 229 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['fromhour1']),5)) 230 else: 231 bvList.append(binary.setBitVectorSize(BitVector(intVal=24),5)) 232 if 'frommin1' in params: 233 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['frommin1']),6)) 234 else: 235 bvList.append(binary.setBitVectorSize(BitVector(intVal=60),6)) 236 if 'tohour1' in params: 237 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['tohour1']),5)) 238 else: 239 bvList.append(binary.setBitVectorSize(BitVector(intVal=24),5)) 240 if 'tomin1' in params: 241 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['tomin1']),6)) 242 else: 243 bvList.append(binary.setBitVectorSize(BitVector(intVal=60),6)) 244 if 'curdir1' in params: 245 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['curdir1']),9)) 246 else: 247 bvList.append(binary.setBitVectorSize(BitVector(intVal=360),9)) 248 if 'curspeed1' in params: 249 bvList.append(binary.setBitVectorSize(BitVector(intVal=int((Decimal(params['curspeed1'])*Decimal('10')))),7)) 250 else: 251 bvList.append(binary.setBitVectorSize(BitVector(intVal=int(127)),7)) 252 if 'window2_longitude' in params: 253 bvList.append(binary.bvFromSignedInt(int(Decimal(params['window2_longitude'])*Decimal('600000')),28)) 254 else: 255 bvList.append(binary.bvFromSignedInt(108600000,28)) 256 if 'window2_latitude' in params: 257 bvList.append(binary.bvFromSignedInt(int(Decimal(params['window2_latitude'])*Decimal('600000')),27)) 258 else: 259 bvList.append(binary.bvFromSignedInt(54600000,27)) 260 if 'fromhour2' in params: 261 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['fromhour2']),5)) 262 else: 263 bvList.append(binary.setBitVectorSize(BitVector(intVal=24),5)) 264 if 'frommin2' in params: 265 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['frommin2']),6)) 266 else: 267 bvList.append(binary.setBitVectorSize(BitVector(intVal=60),6)) 268 if 'tohour2' in params: 269 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['tohour2']),5)) 270 else: 271 bvList.append(binary.setBitVectorSize(BitVector(intVal=24),5)) 272 if 'tomin2' in params: 273 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['tomin2']),6)) 274 else: 275 bvList.append(binary.setBitVectorSize(BitVector(intVal=60),6)) 276 if 'curdir2' in params: 277 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['curdir2']),9)) 278 else: 279 bvList.append(binary.setBitVectorSize(BitVector(intVal=360),9)) 280 if 'curspeed2' in params: 281 bvList.append(binary.setBitVectorSize(BitVector(intVal=int((Decimal(params['curspeed2'])*Decimal('10')))),7)) 282 else: 283 bvList.append(binary.setBitVectorSize(BitVector(intVal=int(127)),7)) 284 if 'window3_longitude' in params: 285 bvList.append(binary.bvFromSignedInt(int(Decimal(params['window3_longitude'])*Decimal('600000')),28)) 286 else: 287 bvList.append(binary.bvFromSignedInt(108600000,28)) 288 if 'window3_latitude' in params: 289 bvList.append(binary.bvFromSignedInt(int(Decimal(params['window3_latitude'])*Decimal('600000')),27)) 290 else: 291 bvList.append(binary.bvFromSignedInt(54600000,27)) 292 if 'fromhour3' in params: 293 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['fromhour3']),5)) 294 else: 295 bvList.append(binary.setBitVectorSize(BitVector(intVal=24),5)) 296 if 'frommin3' in params: 297 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['frommin3']),6)) 298 else: 299 bvList.append(binary.setBitVectorSize(BitVector(intVal=60),6)) 300 if 'tohour3' in params: 301 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['tohour3']),5)) 302 else: 303 bvList.append(binary.setBitVectorSize(BitVector(intVal=24),5)) 304 if 'tomin3' in params: 305 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['tomin3']),6)) 306 else: 307 bvList.append(binary.setBitVectorSize(BitVector(intVal=60),6)) 308 if 'curdir3' in params: 309 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['curdir3']),9)) 310 else: 311 bvList.append(binary.setBitVectorSize(BitVector(intVal=360),9)) 312 if 'curspeed3' in params: 313 bvList.append(binary.setBitVectorSize(BitVector(intVal=int((Decimal(params['curspeed3'])*Decimal('10')))),7)) 314 else: 315 bvList.append(binary.setBitVectorSize(BitVector(intVal=int(127)),7)) 316 317 return binary.joinBV(bvList)
318
319 -def decode(bv, validate=False):
320 '''Unpack a imo_tidal_window message 321 322 Fields in params: 323 - MessageID(uint): AIS message number. Must be 6 (field automatically set to "6") 324 - RepeatIndicator(uint): Indicated how many times a message has been repeated 325 - UserID(uint): MMSI number of transmitter broadcasting the message 326 - SeqNum(uint): Sequence number as described in 5.3.1. Assigned to each station 327 - DestinationID(uint): Unique ship identification number (MMSI) 328 - RetransmitFlag(bool): Should be set upon retransmission 329 - Spare(uint): Must be 0 (field automatically set to "0") 330 - dac(uint): Designated Area Code - part 1 of the IAI (field automatically set to "1") 331 - fid(uint): Functional Identifier - part 2 of the IAI (field automatically set to "11") 332 - month(uint): UTC month 333 - day(uint): UTC day 334 - window1_longitude(decimal): Not sure what this position is for? Center? East West location 335 - window1_latitude(decimal): Not sure what this position is for? Center? North South location 336 - fromhour1(uint): From UTC hour 337 - frommin1(uint): From UTC minute 338 - tohour1(uint): To UTC hour 339 - tomin1(uint): To UTC minute 340 - curdir1(uint): Current direction 341 - curspeed1(udecimal): Current speed 342 - window2_longitude(decimal): Not sure what this position is for? Center? East West location 343 - window2_latitude(decimal): Not sure what this position is for? Center? North South location 344 - fromhour2(uint): From UTC hour 345 - frommin2(uint): From UTC minute 346 - tohour2(uint): To UTC hour 347 - tomin2(uint): To UTC minute 348 - curdir2(uint): Current direction 349 - curspeed2(udecimal): Current speed 350 - window3_longitude(decimal): Not sure what this position is for? Center? East West location 351 - window3_latitude(decimal): Not sure what this position is for? Center? North South location 352 - fromhour3(uint): From UTC hour 353 - frommin3(uint): From UTC minute 354 - tohour3(uint): To UTC hour 355 - tomin3(uint): To UTC minute 356 - curdir3(uint): Current direction 357 - curspeed3(udecimal): Current speed 358 @type bv: BitVector 359 @param bv: Bits defining a message 360 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented. 361 @rtype: dict 362 @return: params 363 ''' 364 365 #Would be nice to check the bit count here.. 366 #if validate: 367 # assert (len(bv)==FIX: SOME NUMBER) 368 r = {} 369 r['MessageID']=6 370 r['RepeatIndicator']=int(bv[6:8]) 371 r['UserID']=int(bv[8:38]) 372 r['SeqNum']=int(bv[38:40]) 373 r['DestinationID']=int(bv[40:70]) 374 r['RetransmitFlag']=bool(int(bv[70:71])) 375 r['Spare']=0 376 r['dac']=1 377 r['fid']=11 378 r['month']=int(bv[88:92]) 379 r['day']=int(bv[92:97]) 380 r['window1_longitude']=Decimal(binary.signedIntFromBV(bv[97:125]))/Decimal('600000') 381 r['window1_latitude']=Decimal(binary.signedIntFromBV(bv[125:152]))/Decimal('600000') 382 r['fromhour1']=int(bv[152:157]) 383 r['frommin1']=int(bv[157:163]) 384 r['tohour1']=int(bv[163:168]) 385 r['tomin1']=int(bv[168:174]) 386 r['curdir1']=int(bv[174:183]) 387 r['curspeed1']=Decimal(int(bv[183:190]))/Decimal('10') 388 r['window2_longitude']=Decimal(binary.signedIntFromBV(bv[190:218]))/Decimal('600000') 389 r['window2_latitude']=Decimal(binary.signedIntFromBV(bv[218:245]))/Decimal('600000') 390 r['fromhour2']=int(bv[245:250]) 391 r['frommin2']=int(bv[250:256]) 392 r['tohour2']=int(bv[256:261]) 393 r['tomin2']=int(bv[261:267]) 394 r['curdir2']=int(bv[267:276]) 395 r['curspeed2']=Decimal(int(bv[276:283]))/Decimal('10') 396 r['window3_longitude']=Decimal(binary.signedIntFromBV(bv[283:311]))/Decimal('600000') 397 r['window3_latitude']=Decimal(binary.signedIntFromBV(bv[311:338]))/Decimal('600000') 398 r['fromhour3']=int(bv[338:343]) 399 r['frommin3']=int(bv[343:349]) 400 r['tohour3']=int(bv[349:354]) 401 r['tomin3']=int(bv[354:360]) 402 r['curdir3']=int(bv[360:369]) 403 r['curspeed3']=Decimal(int(bv[369:376]))/Decimal('10') 404 return r
405
406 -def decodeMessageID(bv, validate=False):
407 return 6
408
409 -def decodeRepeatIndicator(bv, validate=False):
410 return int(bv[6:8])
411
412 -def decodeUserID(bv, validate=False):
413 return int(bv[8:38])
414
415 -def decodeSeqNum(bv, validate=False):
416 return int(bv[38:40])
417
418 -def decodeDestinationID(bv, validate=False):
419 return int(bv[40:70])
420
421 -def decodeRetransmitFlag(bv, validate=False):
422 return bool(int(bv[70:71]))
423
424 -def decodeSpare(bv, validate=False):
425 return 0
426
427 -def decodedac(bv, validate=False):
428 return 1
429
430 -def decodefid(bv, validate=False):
431 return 11
432
433 -def decodemonth(bv, validate=False):
434 return int(bv[88:92])
435
436 -def decodeday(bv, validate=False):
437 return int(bv[92:97])
438
439 -def decodewindow1_longitude(bv, validate=False):
440 return Decimal(binary.signedIntFromBV(bv[97:125]))/Decimal('600000')
441
442 -def decodewindow1_latitude(bv, validate=False):
443 return Decimal(binary.signedIntFromBV(bv[125:152]))/Decimal('600000')
444
445 -def decodefromhour1(bv, validate=False):
446 return int(bv[152:157])
447
448 -def decodefrommin1(bv, validate=False):
449 return int(bv[157:163])
450
451 -def decodetohour1(bv, validate=False):
452 return int(bv[163:168])
453
454 -def decodetomin1(bv, validate=False):
455 return int(bv[168:174])
456
457 -def decodecurdir1(bv, validate=False):
458 return int(bv[174:183])
459
460 -def decodecurspeed1(bv, validate=False):
461 return Decimal(int(bv[183:190]))/Decimal('10')
462
463 -def decodewindow2_longitude(bv, validate=False):
464 return Decimal(binary.signedIntFromBV(bv[190:218]))/Decimal('600000')
465
466 -def decodewindow2_latitude(bv, validate=False):
467 return Decimal(binary.signedIntFromBV(bv[218:245]))/Decimal('600000')
468
469 -def decodefromhour2(bv, validate=False):
470 return int(bv[245:250])
471
472 -def decodefrommin2(bv, validate=False):
473 return int(bv[250:256])
474
475 -def decodetohour2(bv, validate=False):
476 return int(bv[256:261])
477
478 -def decodetomin2(bv, validate=False):
479 return int(bv[261:267])
480
481 -def decodecurdir2(bv, validate=False):
482 return int(bv[267:276])
483
484 -def decodecurspeed2(bv, validate=False):
485 return Decimal(int(bv[276:283]))/Decimal('10')
486
487 -def decodewindow3_longitude(bv, validate=False):
488 return Decimal(binary.signedIntFromBV(bv[283:311]))/Decimal('600000')
489
490 -def decodewindow3_latitude(bv, validate=False):
491 return Decimal(binary.signedIntFromBV(bv[311:338]))/Decimal('600000')
492
493 -def decodefromhour3(bv, validate=False):
494 return int(bv[338:343])
495
496 -def decodefrommin3(bv, validate=False):
497 return int(bv[343:349])
498
499 -def decodetohour3(bv, validate=False):
500 return int(bv[349:354])
501
502 -def decodetomin3(bv, validate=False):
503 return int(bv[354:360])
504
505 -def decodecurdir3(bv, validate=False):
506 return int(bv[360:369])
507
508 -def decodecurspeed3(bv, validate=False):
509 return Decimal(int(bv[369:376]))/Decimal('10')
510 511
512 -def printHtml(params, out=sys.stdout):
513 out.write("<h3>imo_tidal_window</h3>\n") 514 out.write("<table border=\"1\">\n") 515 out.write("<tr bgcolor=\"orange\">\n") 516 out.write("<th align=\"left\">Field Name</th>\n") 517 out.write("<th align=\"left\">Type</th>\n") 518 out.write("<th align=\"left\">Value</th>\n") 519 out.write("<th align=\"left\">Value in Lookup Table</th>\n") 520 out.write("<th align=\"left\">Units</th>\n") 521 out.write("\n") 522 out.write("<tr>\n") 523 out.write("<td>MessageID</td>\n") 524 out.write("<td>uint</td>\n") 525 if 'MessageID' in params: 526 out.write(" <td>"+str(params['MessageID'])+"</td>\n") 527 out.write(" <td>"+str(params['MessageID'])+"</td>\n") 528 out.write("</tr>\n") 529 out.write("\n") 530 out.write("<tr>\n") 531 out.write("<td>RepeatIndicator</td>\n") 532 out.write("<td>uint</td>\n") 533 if 'RepeatIndicator' in params: 534 out.write(" <td>"+str(params['RepeatIndicator'])+"</td>\n") 535 if str(params['RepeatIndicator']) in RepeatIndicatorDecodeLut: 536 out.write("<td>"+RepeatIndicatorDecodeLut[str(params['RepeatIndicator'])]+"</td>") 537 else: 538 out.write("<td><i>Missing LUT entry</i></td>") 539 out.write("</tr>\n") 540 out.write("\n") 541 out.write("<tr>\n") 542 out.write("<td>UserID</td>\n") 543 out.write("<td>uint</td>\n") 544 if 'UserID' in params: 545 out.write(" <td>"+str(params['UserID'])+"</td>\n") 546 out.write(" <td>"+str(params['UserID'])+"</td>\n") 547 out.write("</tr>\n") 548 out.write("\n") 549 out.write("<tr>\n") 550 out.write("<td>SeqNum</td>\n") 551 out.write("<td>uint</td>\n") 552 if 'SeqNum' in params: 553 out.write(" <td>"+str(params['SeqNum'])+"</td>\n") 554 out.write(" <td>"+str(params['SeqNum'])+"</td>\n") 555 out.write("</tr>\n") 556 out.write("\n") 557 out.write("<tr>\n") 558 out.write("<td>DestinationID</td>\n") 559 out.write("<td>uint</td>\n") 560 if 'DestinationID' in params: 561 out.write(" <td>"+str(params['DestinationID'])+"</td>\n") 562 out.write(" <td>"+str(params['DestinationID'])+"</td>\n") 563 out.write("</tr>\n") 564 out.write("\n") 565 out.write("<tr>\n") 566 out.write("<td>RetransmitFlag</td>\n") 567 out.write("<td>bool</td>\n") 568 if 'RetransmitFlag' in params: 569 out.write(" <td>"+str(params['RetransmitFlag'])+"</td>\n") 570 if str(params['RetransmitFlag']) in RetransmitFlagDecodeLut: 571 out.write("<td>"+RetransmitFlagDecodeLut[str(params['RetransmitFlag'])]+"</td>") 572 else: 573 out.write("<td><i>Missing LUT entry</i></td>") 574 out.write("</tr>\n") 575 out.write("\n") 576 out.write("<tr>\n") 577 out.write("<td>Spare</td>\n") 578 out.write("<td>uint</td>\n") 579 if 'Spare' in params: 580 out.write(" <td>"+str(params['Spare'])+"</td>\n") 581 out.write(" <td>"+str(params['Spare'])+"</td>\n") 582 out.write("</tr>\n") 583 out.write("\n") 584 out.write("<tr>\n") 585 out.write("<td>dac</td>\n") 586 out.write("<td>uint</td>\n") 587 if 'dac' in params: 588 out.write(" <td>"+str(params['dac'])+"</td>\n") 589 out.write(" <td>"+str(params['dac'])+"</td>\n") 590 out.write("</tr>\n") 591 out.write("\n") 592 out.write("<tr>\n") 593 out.write("<td>fid</td>\n") 594 out.write("<td>uint</td>\n") 595 if 'fid' in params: 596 out.write(" <td>"+str(params['fid'])+"</td>\n") 597 out.write(" <td>"+str(params['fid'])+"</td>\n") 598 out.write("</tr>\n") 599 out.write("\n") 600 out.write("<tr>\n") 601 out.write("<td>month</td>\n") 602 out.write("<td>uint</td>\n") 603 if 'month' in params: 604 out.write(" <td>"+str(params['month'])+"</td>\n") 605 out.write(" <td>"+str(params['month'])+"</td>\n") 606 out.write("</tr>\n") 607 out.write("\n") 608 out.write("<tr>\n") 609 out.write("<td>day</td>\n") 610 out.write("<td>uint</td>\n") 611 if 'day' in params: 612 out.write(" <td>"+str(params['day'])+"</td>\n") 613 out.write(" <td>"+str(params['day'])+"</td>\n") 614 out.write("</tr>\n") 615 out.write("\n") 616 out.write("<tr>\n") 617 out.write("<td>window1_longitude</td>\n") 618 out.write("<td>decimal</td>\n") 619 if 'window1_longitude' in params: 620 out.write(" <td>"+str(params['window1_longitude'])+"</td>\n") 621 out.write(" <td>"+str(params['window1_longitude'])+"</td>\n") 622 out.write("<td>degrees</td>\n") 623 out.write("</tr>\n") 624 out.write("\n") 625 out.write("<tr>\n") 626 out.write("<td>window1_latitude</td>\n") 627 out.write("<td>decimal</td>\n") 628 if 'window1_latitude' in params: 629 out.write(" <td>"+str(params['window1_latitude'])+"</td>\n") 630 out.write(" <td>"+str(params['window1_latitude'])+"</td>\n") 631 out.write("<td>degrees</td>\n") 632 out.write("</tr>\n") 633 out.write("\n") 634 out.write("<tr>\n") 635 out.write("<td>fromhour1</td>\n") 636 out.write("<td>uint</td>\n") 637 if 'fromhour1' in params: 638 out.write(" <td>"+str(params['fromhour1'])+"</td>\n") 639 out.write(" <td>"+str(params['fromhour1'])+"</td>\n") 640 out.write("<td>hours</td>\n") 641 out.write("</tr>\n") 642 out.write("\n") 643 out.write("<tr>\n") 644 out.write("<td>frommin1</td>\n") 645 out.write("<td>uint</td>\n") 646 if 'frommin1' in params: 647 out.write(" <td>"+str(params['frommin1'])+"</td>\n") 648 out.write(" <td>"+str(params['frommin1'])+"</td>\n") 649 out.write("<td>minutes</td>\n") 650 out.write("</tr>\n") 651 out.write("\n") 652 out.write("<tr>\n") 653 out.write("<td>tohour1</td>\n") 654 out.write("<td>uint</td>\n") 655 if 'tohour1' in params: 656 out.write(" <td>"+str(params['tohour1'])+"</td>\n") 657 out.write(" <td>"+str(params['tohour1'])+"</td>\n") 658 out.write("<td>hours</td>\n") 659 out.write("</tr>\n") 660 out.write("\n") 661 out.write("<tr>\n") 662 out.write("<td>tomin1</td>\n") 663 out.write("<td>uint</td>\n") 664 if 'tomin1' in params: 665 out.write(" <td>"+str(params['tomin1'])+"</td>\n") 666 out.write(" <td>"+str(params['tomin1'])+"</td>\n") 667 out.write("<td>minutes</td>\n") 668 out.write("</tr>\n") 669 out.write("\n") 670 out.write("<tr>\n") 671 out.write("<td>curdir1</td>\n") 672 out.write("<td>uint</td>\n") 673 if 'curdir1' in params: 674 out.write(" <td>"+str(params['curdir1'])+"</td>\n") 675 out.write(" <td>"+str(params['curdir1'])+"</td>\n") 676 out.write("<td>degrees</td>\n") 677 out.write("</tr>\n") 678 out.write("\n") 679 out.write("<tr>\n") 680 out.write("<td>curspeed1</td>\n") 681 out.write("<td>udecimal</td>\n") 682 if 'curspeed1' in params: 683 out.write(" <td>"+str(params['curspeed1'])+"</td>\n") 684 out.write(" <td>"+str(params['curspeed1'])+"</td>\n") 685 out.write("<td>knots</td>\n") 686 out.write("</tr>\n") 687 out.write("\n") 688 out.write("<tr>\n") 689 out.write("<td>window2_longitude</td>\n") 690 out.write("<td>decimal</td>\n") 691 if 'window2_longitude' in params: 692 out.write(" <td>"+str(params['window2_longitude'])+"</td>\n") 693 out.write(" <td>"+str(params['window2_longitude'])+"</td>\n") 694 out.write("<td>degrees</td>\n") 695 out.write("</tr>\n") 696 out.write("\n") 697 out.write("<tr>\n") 698 out.write("<td>window2_latitude</td>\n") 699 out.write("<td>decimal</td>\n") 700 if 'window2_latitude' in params: 701 out.write(" <td>"+str(params['window2_latitude'])+"</td>\n") 702 out.write(" <td>"+str(params['window2_latitude'])+"</td>\n") 703 out.write("<td>degrees</td>\n") 704 out.write("</tr>\n") 705 out.write("\n") 706 out.write("<tr>\n") 707 out.write("<td>fromhour2</td>\n") 708 out.write("<td>uint</td>\n") 709 if 'fromhour2' in params: 710 out.write(" <td>"+str(params['fromhour2'])+"</td>\n") 711 out.write(" <td>"+str(params['fromhour2'])+"</td>\n") 712 out.write("<td>hours</td>\n") 713 out.write("</tr>\n") 714 out.write("\n") 715 out.write("<tr>\n") 716 out.write("<td>frommin2</td>\n") 717 out.write("<td>uint</td>\n") 718 if 'frommin2' in params: 719 out.write(" <td>"+str(params['frommin2'])+"</td>\n") 720 out.write(" <td>"+str(params['frommin2'])+"</td>\n") 721 out.write("<td>minutes</td>\n") 722 out.write("</tr>\n") 723 out.write("\n") 724 out.write("<tr>\n") 725 out.write("<td>tohour2</td>\n") 726 out.write("<td>uint</td>\n") 727 if 'tohour2' in params: 728 out.write(" <td>"+str(params['tohour2'])+"</td>\n") 729 out.write(" <td>"+str(params['tohour2'])+"</td>\n") 730 out.write("<td>hours</td>\n") 731 out.write("</tr>\n") 732 out.write("\n") 733 out.write("<tr>\n") 734 out.write("<td>tomin2</td>\n") 735 out.write("<td>uint</td>\n") 736 if 'tomin2' in params: 737 out.write(" <td>"+str(params['tomin2'])+"</td>\n") 738 out.write(" <td>"+str(params['tomin2'])+"</td>\n") 739 out.write("<td>minutes</td>\n") 740 out.write("</tr>\n") 741 out.write("\n") 742 out.write("<tr>\n") 743 out.write("<td>curdir2</td>\n") 744 out.write("<td>uint</td>\n") 745 if 'curdir2' in params: 746 out.write(" <td>"+str(params['curdir2'])+"</td>\n") 747 out.write(" <td>"+str(params['curdir2'])+"</td>\n") 748 out.write("<td>degrees</td>\n") 749 out.write("</tr>\n") 750 out.write("\n") 751 out.write("<tr>\n") 752 out.write("<td>curspeed2</td>\n") 753 out.write("<td>udecimal</td>\n") 754 if 'curspeed2' in params: 755 out.write(" <td>"+str(params['curspeed2'])+"</td>\n") 756 out.write(" <td>"+str(params['curspeed2'])+"</td>\n") 757 out.write("<td>knots</td>\n") 758 out.write("</tr>\n") 759 out.write("\n") 760 out.write("<tr>\n") 761 out.write("<td>window3_longitude</td>\n") 762 out.write("<td>decimal</td>\n") 763 if 'window3_longitude' in params: 764 out.write(" <td>"+str(params['window3_longitude'])+"</td>\n") 765 out.write(" <td>"+str(params['window3_longitude'])+"</td>\n") 766 out.write("<td>degrees</td>\n") 767 out.write("</tr>\n") 768 out.write("\n") 769 out.write("<tr>\n") 770 out.write("<td>window3_latitude</td>\n") 771 out.write("<td>decimal</td>\n") 772 if 'window3_latitude' in params: 773 out.write(" <td>"+str(params['window3_latitude'])+"</td>\n") 774 out.write(" <td>"+str(params['window3_latitude'])+"</td>\n") 775 out.write("<td>degrees</td>\n") 776 out.write("</tr>\n") 777 out.write("\n") 778 out.write("<tr>\n") 779 out.write("<td>fromhour3</td>\n") 780 out.write("<td>uint</td>\n") 781 if 'fromhour3' in params: 782 out.write(" <td>"+str(params['fromhour3'])+"</td>\n") 783 out.write(" <td>"+str(params['fromhour3'])+"</td>\n") 784 out.write("<td>hours</td>\n") 785 out.write("</tr>\n") 786 out.write("\n") 787 out.write("<tr>\n") 788 out.write("<td>frommin3</td>\n") 789 out.write("<td>uint</td>\n") 790 if 'frommin3' in params: 791 out.write(" <td>"+str(params['frommin3'])+"</td>\n") 792 out.write(" <td>"+str(params['frommin3'])+"</td>\n") 793 out.write("<td>minutes</td>\n") 794 out.write("</tr>\n") 795 out.write("\n") 796 out.write("<tr>\n") 797 out.write("<td>tohour3</td>\n") 798 out.write("<td>uint</td>\n") 799 if 'tohour3' in params: 800 out.write(" <td>"+str(params['tohour3'])+"</td>\n") 801 out.write(" <td>"+str(params['tohour3'])+"</td>\n") 802 out.write("<td>hours</td>\n") 803 out.write("</tr>\n") 804 out.write("\n") 805 out.write("<tr>\n") 806 out.write("<td>tomin3</td>\n") 807 out.write("<td>uint</td>\n") 808 if 'tomin3' in params: 809 out.write(" <td>"+str(params['tomin3'])+"</td>\n") 810 out.write(" <td>"+str(params['tomin3'])+"</td>\n") 811 out.write("<td>minutes</td>\n") 812 out.write("</tr>\n") 813 out.write("\n") 814 out.write("<tr>\n") 815 out.write("<td>curdir3</td>\n") 816 out.write("<td>uint</td>\n") 817 if 'curdir3' in params: 818 out.write(" <td>"+str(params['curdir3'])+"</td>\n") 819 out.write(" <td>"+str(params['curdir3'])+"</td>\n") 820 out.write("<td>degrees</td>\n") 821 out.write("</tr>\n") 822 out.write("\n") 823 out.write("<tr>\n") 824 out.write("<td>curspeed3</td>\n") 825 out.write("<td>udecimal</td>\n") 826 if 'curspeed3' in params: 827 out.write(" <td>"+str(params['curspeed3'])+"</td>\n") 828 out.write(" <td>"+str(params['curspeed3'])+"</td>\n") 829 out.write("<td>knots</td>\n") 830 out.write("</tr>\n") 831 out.write("</table>\n")
832 833
834 -def printKml(params, out=sys.stdout):
835 '''KML (Keyhole Markup Language) for Google Earth, but without the header/footer''' 836 out.write("\ <Placemark>\n") 837 out.write("\t <name>"+str(params['UserID'])+"</name>\n") 838 out.write("\t\t<description>\n") 839 import StringIO 840 buf = StringIO.StringIO() 841 printHtml(params,buf) 842 import cgi 843 out.write(cgi.escape(buf.getvalue())) 844 out.write("\t\t</description>\n") 845 out.write("\t\t<styleUrl>#m_ylw-pushpin_copy0</styleUrl>\n") 846 out.write("\t\t<Point>\n") 847 out.write("\t\t\t<coordinates>") 848 out.write(str(params['window1_longitude'])) 849 out.write(',') 850 out.write(str(params['window1_latitude'])) 851 out.write(",0</coordinates>\n") 852 out.write("\t\t</Point>\n") 853 out.write("\t</Placemark>\n")
854
855 -def printFields(params, out=sys.stdout, format='std', fieldList=None, dbType='postgres'):
856 '''Print a imo_tidal_window message to stdout. 857 858 Fields in params: 859 - MessageID(uint): AIS message number. Must be 6 (field automatically set to "6") 860 - RepeatIndicator(uint): Indicated how many times a message has been repeated 861 - UserID(uint): MMSI number of transmitter broadcasting the message 862 - SeqNum(uint): Sequence number as described in 5.3.1. Assigned to each station 863 - DestinationID(uint): Unique ship identification number (MMSI) 864 - RetransmitFlag(bool): Should be set upon retransmission 865 - Spare(uint): Must be 0 (field automatically set to "0") 866 - dac(uint): Designated Area Code - part 1 of the IAI (field automatically set to "1") 867 - fid(uint): Functional Identifier - part 2 of the IAI (field automatically set to "11") 868 - month(uint): UTC month 869 - day(uint): UTC day 870 - window1_longitude(decimal): Not sure what this position is for? Center? East West location 871 - window1_latitude(decimal): Not sure what this position is for? Center? North South location 872 - fromhour1(uint): From UTC hour 873 - frommin1(uint): From UTC minute 874 - tohour1(uint): To UTC hour 875 - tomin1(uint): To UTC minute 876 - curdir1(uint): Current direction 877 - curspeed1(udecimal): Current speed 878 - window2_longitude(decimal): Not sure what this position is for? Center? East West location 879 - window2_latitude(decimal): Not sure what this position is for? Center? North South location 880 - fromhour2(uint): From UTC hour 881 - frommin2(uint): From UTC minute 882 - tohour2(uint): To UTC hour 883 - tomin2(uint): To UTC minute 884 - curdir2(uint): Current direction 885 - curspeed2(udecimal): Current speed 886 - window3_longitude(decimal): Not sure what this position is for? Center? East West location 887 - window3_latitude(decimal): Not sure what this position is for? Center? North South location 888 - fromhour3(uint): From UTC hour 889 - frommin3(uint): From UTC minute 890 - tohour3(uint): To UTC hour 891 - tomin3(uint): To UTC minute 892 - curdir3(uint): Current direction 893 - curspeed3(udecimal): Current speed 894 @param params: Dictionary of field names/values. 895 @param out: File like object to write to 896 @rtype: stdout 897 @return: text to out 898 ''' 899 900 if 'std'==format: 901 out.write("imo_tidal_window:\n") 902 if 'MessageID' in params: out.write(" MessageID: "+str(params['MessageID'])+"\n") 903 if 'RepeatIndicator' in params: out.write(" RepeatIndicator: "+str(params['RepeatIndicator'])+"\n") 904 if 'UserID' in params: out.write(" UserID: "+str(params['UserID'])+"\n") 905 if 'SeqNum' in params: out.write(" SeqNum: "+str(params['SeqNum'])+"\n") 906 if 'DestinationID' in params: out.write(" DestinationID: "+str(params['DestinationID'])+"\n") 907 if 'RetransmitFlag' in params: out.write(" RetransmitFlag: "+str(params['RetransmitFlag'])+"\n") 908 if 'Spare' in params: out.write(" Spare: "+str(params['Spare'])+"\n") 909 if 'dac' in params: out.write(" dac: "+str(params['dac'])+"\n") 910 if 'fid' in params: out.write(" fid: "+str(params['fid'])+"\n") 911 if 'month' in params: out.write(" month: "+str(params['month'])+"\n") 912 if 'day' in params: out.write(" day: "+str(params['day'])+"\n") 913 if 'window1_longitude' in params: out.write(" window1_longitude: "+str(params['window1_longitude'])+"\n") 914 if 'window1_latitude' in params: out.write(" window1_latitude: "+str(params['window1_latitude'])+"\n") 915 if 'fromhour1' in params: out.write(" fromhour1: "+str(params['fromhour1'])+"\n") 916 if 'frommin1' in params: out.write(" frommin1: "+str(params['frommin1'])+"\n") 917 if 'tohour1' in params: out.write(" tohour1: "+str(params['tohour1'])+"\n") 918 if 'tomin1' in params: out.write(" tomin1: "+str(params['tomin1'])+"\n") 919 if 'curdir1' in params: out.write(" curdir1: "+str(params['curdir1'])+"\n") 920 if 'curspeed1' in params: out.write(" curspeed1: "+str(params['curspeed1'])+"\n") 921 if 'window2_longitude' in params: out.write(" window2_longitude: "+str(params['window2_longitude'])+"\n") 922 if 'window2_latitude' in params: out.write(" window2_latitude: "+str(params['window2_latitude'])+"\n") 923 if 'fromhour2' in params: out.write(" fromhour2: "+str(params['fromhour2'])+"\n") 924 if 'frommin2' in params: out.write(" frommin2: "+str(params['frommin2'])+"\n") 925 if 'tohour2' in params: out.write(" tohour2: "+str(params['tohour2'])+"\n") 926 if 'tomin2' in params: out.write(" tomin2: "+str(params['tomin2'])+"\n") 927 if 'curdir2' in params: out.write(" curdir2: "+str(params['curdir2'])+"\n") 928 if 'curspeed2' in params: out.write(" curspeed2: "+str(params['curspeed2'])+"\n") 929 if 'window3_longitude' in params: out.write(" window3_longitude: "+str(params['window3_longitude'])+"\n") 930 if 'window3_latitude' in params: out.write(" window3_latitude: "+str(params['window3_latitude'])+"\n") 931 if 'fromhour3' in params: out.write(" fromhour3: "+str(params['fromhour3'])+"\n") 932 if 'frommin3' in params: out.write(" frommin3: "+str(params['frommin3'])+"\n") 933 if 'tohour3' in params: out.write(" tohour3: "+str(params['tohour3'])+"\n") 934 if 'tomin3' in params: out.write(" tomin3: "+str(params['tomin3'])+"\n") 935 if 'curdir3' in params: out.write(" curdir3: "+str(params['curdir3'])+"\n") 936 if 'curspeed3' in params: out.write(" curspeed3: "+str(params['curspeed3'])+"\n") 937 elif 'csv'==format: 938 if None == options.fieldList: 939 options.fieldList = fieldList 940 needComma = False; 941 for field in fieldList: 942 if needComma: out.write(',') 943 needComma = True 944 if field in params: 945 out.write(str(params[field])) 946 # else: leave it empty 947 out.write("\n") 948 elif 'html'==format: 949 printHtml(params,out) 950 elif 'sql'==format: 951 sqlInsertStr(params,out,dbType=dbType) 952 elif 'kml'==format: 953 printKml(params,out) 954 elif 'kml-full'==format: 955 out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") 956 out.write("<kml xmlns=\"http://earth.google.com/kml/2.1\">\n") 957 out.write("<Document>\n") 958 out.write(" <name>imo_tidal_window</name>\n") 959 printKml(params,out) 960 out.write("</Document>\n") 961 out.write("</kml>\n") 962 else: 963 print "ERROR: unknown format:",format 964 assert False 965 966 return # Nothing to return
967 968 RepeatIndicatorEncodeLut = { 969 'default':'0', 970 'do not repeat any more':'3', 971 } #RepeatIndicatorEncodeLut 972 973 RepeatIndicatorDecodeLut = { 974 '0':'default', 975 '3':'do not repeat any more', 976 } # RepeatIndicatorEncodeLut 977 978 RetransmitFlagEncodeLut = { 979 'no retransmission':'0', 980 'restransmitted':'1', 981 } #RetransmitFlagEncodeLut 982 983 RetransmitFlagDecodeLut = { 984 '0':'no retransmission', 985 '1':'restransmitted', 986 } # RetransmitFlagEncodeLut 987 988 ###################################################################### 989 # SQL SUPPORT 990 ###################################################################### 991 992 dbTableName='imo_tidal_window' 993 'Database table name' 994
995 -def sqlCreateStr(outfile=sys.stdout, fields=None, extraFields=None 996 ,addCoastGuardFields=True 997 ,dbType='postgres' 998 ):
999 ''' 1000 Return the SQL CREATE command for this message type 1001 @param outfile: file like object to print to. 1002 @param fields: which fields to put in the create. Defaults to all. 1003 @param extraFields: A sequence of tuples containing (name,sql type) for additional fields 1004 @param addCoastGuardFields: Add the extra fields that come after the NMEA check some from the USCG N-AIS format 1005 @param dbType: Which flavor of database we are using so that the create is tailored ('sqlite' or 'postgres') 1006 @type addCoastGuardFields: bool 1007 @return: sql create string 1008 @rtype: str 1009 1010 @see: sqlCreate 1011 ''' 1012 # FIX: should this sqlCreate be the same as in LaTeX (createFuncName) rather than hard coded? 1013 outfile.write(str(sqlCreate(fields,extraFields,addCoastGuardFields,dbType=dbType)))
1014
1015 -def sqlCreate(fields=None, extraFields=None, addCoastGuardFields=True, dbType='postgres'):
1016 ''' 1017 Return the sqlhelp object to create the table. 1018 1019 @param fields: which fields to put in the create. Defaults to all. 1020 @param extraFields: A sequence of tuples containing (name,sql type) for additional fields 1021 @param addCoastGuardFields: Add the extra fields that come after the NMEA check some from the USCG N-AIS format 1022 @type addCoastGuardFields: bool 1023 @param dbType: Which flavor of database we are using so that the create is tailored ('sqlite' or 'postgres') 1024 @return: An object that can be used to generate a return 1025 @rtype: sqlhelp.create 1026 ''' 1027 if None == fields: fields = fieldList 1028 import sqlhelp 1029 c = sqlhelp.create('imo_tidal_window',dbType=dbType) 1030 c.addPrimaryKey() 1031 if 'MessageID' in fields: c.addInt ('MessageID') 1032 if 'RepeatIndicator' in fields: c.addInt ('RepeatIndicator') 1033 if 'UserID' in fields: c.addInt ('UserID') 1034 if 'SeqNum' in fields: c.addInt ('SeqNum') 1035 if 'DestinationID' in fields: c.addInt ('DestinationID') 1036 if 'RetransmitFlag' in fields: c.addBool('RetransmitFlag') 1037 if 'Spare' in fields: c.addInt ('Spare') 1038 if 'dac' in fields: c.addInt ('dac') 1039 if 'fid' in fields: c.addInt ('fid') 1040 if 'month' in fields: c.addInt ('month') 1041 if 'day' in fields: c.addInt ('day') 1042 if dbType != 'postgres': 1043 if 'window1_longitude' in fields: c.addDecimal('window1_longitude',8,5) 1044 if dbType != 'postgres': 1045 if 'window1_latitude' in fields: c.addDecimal('window1_latitude',8,5) 1046 if 'fromhour1' in fields: c.addInt ('fromhour1') 1047 if 'frommin1' in fields: c.addInt ('frommin1') 1048 if 'tohour1' in fields: c.addInt ('tohour1') 1049 if 'tomin1' in fields: c.addInt ('tomin1') 1050 if 'curdir1' in fields: c.addInt ('curdir1') 1051 if 'curspeed1' in fields: c.addDecimal('curspeed1',3,1) 1052 if dbType != 'postgres': 1053 if 'window2_longitude' in fields: c.addDecimal('window2_longitude',8,5) 1054 if dbType != 'postgres': 1055 if 'window2_latitude' in fields: c.addDecimal('window2_latitude',8,5) 1056 if 'fromhour2' in fields: c.addInt ('fromhour2') 1057 if 'frommin2' in fields: c.addInt ('frommin2') 1058 if 'tohour2' in fields: c.addInt ('tohour2') 1059 if 'tomin2' in fields: c.addInt ('tomin2') 1060 if 'curdir2' in fields: c.addInt ('curdir2') 1061 if 'curspeed2' in fields: c.addDecimal('curspeed2',3,1) 1062 if dbType != 'postgres': 1063 if 'window3_longitude' in fields: c.addDecimal('window3_longitude',8,5) 1064 if dbType != 'postgres': 1065 if 'window3_latitude' in fields: c.addDecimal('window3_latitude',8,5) 1066 if 'fromhour3' in fields: c.addInt ('fromhour3') 1067 if 'frommin3' in fields: c.addInt ('frommin3') 1068 if 'tohour3' in fields: c.addInt ('tohour3') 1069 if 'tomin3' in fields: c.addInt ('tomin3') 1070 if 'curdir3' in fields: c.addInt ('curdir3') 1071 if 'curspeed3' in fields: c.addDecimal('curspeed3',3,1) 1072 1073 if addCoastGuardFields: 1074 # c.addInt('cg_rssi') # Relative signal strength indicator 1075 # c.addInt('cg_d') # dBm receive strength 1076 # c.addInt('cg_T') # Receive timestamp from the AIS equipment 1077 # c.addInt('cg_S') # Slot received in 1078 # c.addVarChar('cg_x',10) # Idonno 1079 c.addVarChar('cg_r',15) # Receiver station ID - should usually be an MMSI, but sometimes is a string 1080 c.addInt('cg_sec') # UTC seconds since the epoch 1081 1082 c.addTimestamp('cg_timestamp') # UTC decoded cg_sec - not actually in the data stream 1083 1084 if dbType == 'postgres': 1085 #--- EPSG 4326 : WGS 84 1086 #INSERT INTO "spatial_ref_sys" ("srid","auth_name","auth_srid","srtext","proj4text") VALUES (4326,'EPSG',4326,'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]','+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs '); 1087 c.addPostGIS('window1','POINT',2,SRID=4326); 1088 #--- EPSG 4326 : WGS 84 1089 #INSERT INTO "spatial_ref_sys" ("srid","auth_name","auth_srid","srtext","proj4text") VALUES (4326,'EPSG',4326,'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]','+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs '); 1090 c.addPostGIS('window2','POINT',2,SRID=4326); 1091 #--- EPSG 4326 : WGS 84 1092 #INSERT INTO "spatial_ref_sys" ("srid","auth_name","auth_srid","srtext","proj4text") VALUES (4326,'EPSG',4326,'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]','+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs '); 1093 c.addPostGIS('window3','POINT',2,SRID=4326); 1094 1095 return c
1096
1097 -def sqlInsertStr(params, outfile=sys.stdout, extraParams=None, dbType='postgres'):
1098 ''' 1099 Return the SQL INSERT command for this message type 1100 @param params: dictionary of values keyed by field name 1101 @param outfile: file like object to print to. 1102 @param extraParams: A sequence of tuples containing (name,sql type) for additional fields 1103 @return: sql create string 1104 @rtype: str 1105 1106 @see: sqlCreate 1107 ''' 1108 outfile.write(str(sqlInsert(params,extraParams,dbType=dbType)))
1109 1110
1111 -def sqlInsert(params,extraParams=None,dbType='postgres'):
1112 ''' 1113 Give the SQL INSERT statement 1114 @param params: dict keyed by field name of values 1115 @param extraParams: any extra fields that you have created beyond the normal ais message fields 1116 @rtype: sqlhelp.insert 1117 @return: insert class instance 1118 @todo: allow optional type checking of params? 1119 @warning: this will take invalid keys happily and do what??? 1120 ''' 1121 import sqlhelp 1122 i = sqlhelp.insert('imo_tidal_window',dbType=dbType) 1123 1124 if dbType=='postgres': 1125 finished = [] 1126 for key in params: 1127 if key in finished: 1128 continue 1129 1130 if key not in toPgFields and key not in fromPgFields: 1131 if type(params[key])==Decimal: i.add(key,float(params[key])) 1132 else: i.add(key,params[key]) 1133 else: 1134 if key in fromPgFields: 1135 val = params[key] 1136 # Had better be a WKT type like POINT(-88.1 30.321) 1137 i.addPostGIS(key,val) 1138 finished.append(key) 1139 else: 1140 # Need to construct the type. 1141 pgName = toPgFields[key] 1142 #valStr='GeomFromText(\''+pgTypes[pgName]+'(' 1143 valStr=pgTypes[pgName]+'(' 1144 vals = [] 1145 for nonPgKey in fromPgFields[pgName]: 1146 vals.append(str(params[nonPgKey])) 1147 finished.append(nonPgKey) 1148 valStr+=' '.join(vals)+')' 1149 i.addPostGIS(pgName,valStr) 1150 else: 1151 for key in params: 1152 if type(params[key])==Decimal: i.add(key,float(params[key])) 1153 else: i.add(key,params[key]) 1154 1155 if None != extraParams: 1156 for key in extraParams: 1157 i.add(key,extraParams[key]) 1158 1159 return i
1160 1161 ###################################################################### 1162 # LATEX SUPPORT 1163 ###################################################################### 1164
1165 -def latexDefinitionTable(outfile=sys.stdout 1166 ):
1167 ''' 1168 Return the LaTeX definition table for this message type 1169 @param outfile: file like object to print to. 1170 @type outfile: file obj 1171 @return: LaTeX table string via the outfile 1172 @rtype: str 1173 1174 ''' 1175 o = outfile 1176 1177 o.write(''' 1178 \\begin{table}%[htb] 1179 \\centering 1180 \\begin{tabular}{|l|c|l|} 1181 \\hline 1182 Parameter & Number of bits & Description 1183 \\\\ \\hline\\hline 1184 MessageID & 6 & AIS message number. Must be 6 \\\\ \hline 1185 RepeatIndicator & 2 & Indicated how many times a message has been repeated \\\\ \hline 1186 UserID & 30 & MMSI number of transmitter broadcasting the message \\\\ \hline 1187 SeqNum & 2 & Sequence number as described in 5.3.1. Assigned to each station \\\\ \hline 1188 DestinationID & 30 & Unique ship identification number (MMSI) \\\\ \hline 1189 RetransmitFlag & 1 & Should be set upon retransmission \\\\ \hline 1190 Spare & 1 & Must be 0 \\\\ \hline 1191 dac & 10 & Designated Area Code - part 1 of the IAI \\\\ \hline 1192 fid & 6 & Functional Identifier - part 2 of the IAI \\\\ \hline 1193 month & 4 & UTC month \\\\ \hline 1194 day & 5 & UTC day \\\\ \hline 1195 window1\_longitude & 28 & Not sure what this position is for? Center? East West location \\\\ \hline 1196 window1\_latitude & 27 & Not sure what this position is for? Center? North South location \\\\ \hline 1197 fromhour1 & 5 & From UTC hour \\\\ \hline 1198 frommin1 & 6 & From UTC minute \\\\ \hline 1199 tohour1 & 5 & To UTC hour \\\\ \hline 1200 tomin1 & 6 & To UTC minute \\\\ \hline 1201 curdir1 & 9 & Current direction \\\\ \hline 1202 curspeed1 & 7 & Current speed \\\\ \hline 1203 window2\_longitude & 28 & Not sure what this position is for? Center? East West location \\\\ \hline 1204 window2\_latitude & 27 & Not sure what this position is for? Center? North South location \\\\ \hline 1205 fromhour2 & 5 & From UTC hour \\\\ \hline 1206 frommin2 & 6 & From UTC minute \\\\ \hline 1207 tohour2 & 5 & To UTC hour \\\\ \hline 1208 tomin2 & 6 & To UTC minute \\\\ \hline 1209 curdir2 & 9 & Current direction \\\\ \hline 1210 curspeed2 & 7 & Current speed \\\\ \hline 1211 window3\_longitude & 28 & Not sure what this position is for? Center? East West location \\\\ \hline 1212 window3\_latitude & 27 & Not sure what this position is for? Center? North South location \\\\ \hline 1213 fromhour3 & 5 & From UTC hour \\\\ \hline 1214 frommin3 & 6 & From UTC minute \\\\ \hline 1215 tohour3 & 5 & To UTC hour \\\\ \hline 1216 tomin3 & 6 & To UTC minute \\\\ \hline 1217 curdir3 & 9 & Current direction \\\\ \hline 1218 curspeed3 & 7 & Current speed\\\\ \\hline \\hline 1219 Total bits & 376 & Appears to take 2 slots with 48 pad bits to fill the last slot \\\\ \\hline 1220 \\end{tabular} 1221 \\caption{AIS message number 6: IMO fairway closed. Specified in SN\\Circ.236 Annex 2, page 5, Application 3. Also defined in IALA Guidelines on AIS, Vol 1, Part 1, Ed. 1.3. Guildeline No 1028. This message should be used to inform vessels about tidal windows which allow a vessel the safe passage of a fairway. The message includes predictions of current speed and current direction. In this example, three points of tidal information are given. Attributes of message: addressed, shore station transmitting, acknowledgement required. } 1222 \\label{tab:imo_tidal_window} 1223 \\end{table} 1224 ''')
1225 1226 ###################################################################### 1227 # Text Definition 1228 ###################################################################### 1229
1230 -def textDefinitionTable(outfile=sys.stdout 1231 ,delim='\t' 1232 ):
1233 ''' 1234 Return the text definition table for this message type 1235 @param outfile: file like object to print to. 1236 @type outfile: file obj 1237 @return: text table string via the outfile 1238 @rtype: str 1239 1240 ''' 1241 o = outfile 1242 o.write('''Parameter'''+delim+'Number of bits'''+delim+'''Description 1243 MessageID'''+delim+'''6'''+delim+'''AIS message number. Must be 6 1244 RepeatIndicator'''+delim+'''2'''+delim+'''Indicated how many times a message has been repeated 1245 UserID'''+delim+'''30'''+delim+'''MMSI number of transmitter broadcasting the message 1246 SeqNum'''+delim+'''2'''+delim+'''Sequence number as described in 5.3.1. Assigned to each station 1247 DestinationID'''+delim+'''30'''+delim+'''Unique ship identification number (MMSI) 1248 RetransmitFlag'''+delim+'''1'''+delim+'''Should be set upon retransmission 1249 Spare'''+delim+'''1'''+delim+'''Must be 0 1250 dac'''+delim+'''10'''+delim+'''Designated Area Code - part 1 of the IAI 1251 fid'''+delim+'''6'''+delim+'''Functional Identifier - part 2 of the IAI 1252 month'''+delim+'''4'''+delim+'''UTC month 1253 day'''+delim+'''5'''+delim+'''UTC day 1254 window1_longitude'''+delim+'''28'''+delim+'''Not sure what this position is for? Center? East West location 1255 window1_latitude'''+delim+'''27'''+delim+'''Not sure what this position is for? Center? North South location 1256 fromhour1'''+delim+'''5'''+delim+'''From UTC hour 1257 frommin1'''+delim+'''6'''+delim+'''From UTC minute 1258 tohour1'''+delim+'''5'''+delim+'''To UTC hour 1259 tomin1'''+delim+'''6'''+delim+'''To UTC minute 1260 curdir1'''+delim+'''9'''+delim+'''Current direction 1261 curspeed1'''+delim+'''7'''+delim+'''Current speed 1262 window2_longitude'''+delim+'''28'''+delim+'''Not sure what this position is for? Center? East West location 1263 window2_latitude'''+delim+'''27'''+delim+'''Not sure what this position is for? Center? North South location 1264 fromhour2'''+delim+'''5'''+delim+'''From UTC hour 1265 frommin2'''+delim+'''6'''+delim+'''From UTC minute 1266 tohour2'''+delim+'''5'''+delim+'''To UTC hour 1267 tomin2'''+delim+'''6'''+delim+'''To UTC minute 1268 curdir2'''+delim+'''9'''+delim+'''Current direction 1269 curspeed2'''+delim+'''7'''+delim+'''Current speed 1270 window3_longitude'''+delim+'''28'''+delim+'''Not sure what this position is for? Center? East West location 1271 window3_latitude'''+delim+'''27'''+delim+'''Not sure what this position is for? Center? North South location 1272 fromhour3'''+delim+'''5'''+delim+'''From UTC hour 1273 frommin3'''+delim+'''6'''+delim+'''From UTC minute 1274 tohour3'''+delim+'''5'''+delim+'''To UTC hour 1275 tomin3'''+delim+'''6'''+delim+'''To UTC minute 1276 curdir3'''+delim+'''9'''+delim+'''Current direction 1277 curspeed3'''+delim+'''7'''+delim+'''Current speed 1278 Total bits'''+delim+'''376'''+delim+'''Appears to take 2 slots with 48 pad bits to fill the last slot''')
1279 1280 1281 ###################################################################### 1282 # UNIT TESTING 1283 ###################################################################### 1284 import unittest
1285 -def testParams():
1286 '''Return a params file base on the testvalue tags. 1287 @rtype: dict 1288 @return: params based on testvalue tags 1289 ''' 1290 params = {} 1291 params['MessageID'] = 6 1292 params['RepeatIndicator'] = 1 1293 params['UserID'] = 1193046 1294 params['SeqNum'] = 3 1295 params['DestinationID'] = 1193047 1296 params['RetransmitFlag'] = True 1297 params['Spare'] = 0 1298 params['dac'] = 1 1299 params['fid'] = 11 1300 params['month'] = 2 1301 params['day'] = 1 1302 params['window1_longitude'] = Decimal('-122.16328055555556') 1303 params['window1_latitude'] = Decimal('37.424458333333334') 1304 params['fromhour1'] = 1 1305 params['frommin1'] = 21 1306 params['tohour1'] = 23 1307 params['tomin1'] = 24 1308 params['curdir1'] = 300 1309 params['curspeed1'] = Decimal('12.1') 1310 params['window2_longitude'] = Decimal('-122.16328055555556') 1311 params['window2_latitude'] = Decimal('37.424458333333334') 1312 params['fromhour2'] = 1 1313 params['frommin2'] = 21 1314 params['tohour2'] = 23 1315 params['tomin2'] = 24 1316 params['curdir2'] = 300 1317 params['curspeed2'] = Decimal('12.1') 1318 params['window3_longitude'] = Decimal('-122.16328055555556') 1319 params['window3_latitude'] = Decimal('37.424458333333334') 1320 params['fromhour3'] = 1 1321 params['frommin3'] = 21 1322 params['tohour3'] = 23 1323 params['tomin3'] = 24 1324 params['curdir3'] = 300 1325 params['curspeed3'] = Decimal('12.1') 1326 1327 return params
1328
1329 -class Testimo_tidal_window(unittest.TestCase):
1330 '''Use testvalue tag text from each type to build test case the imo_tidal_window message'''
1331 - def testEncodeDecode(self):
1332 1333 params = testParams() 1334 bits = encode(params) 1335 r = decode(bits) 1336 1337 # Check that each parameter came through ok. 1338 self.failUnlessEqual(r['MessageID'],params['MessageID']) 1339 self.failUnlessEqual(r['RepeatIndicator'],params['RepeatIndicator']) 1340 self.failUnlessEqual(r['UserID'],params['UserID']) 1341 self.failUnlessEqual(r['SeqNum'],params['SeqNum']) 1342 self.failUnlessEqual(r['DestinationID'],params['DestinationID']) 1343 self.failUnlessEqual(r['RetransmitFlag'],params['RetransmitFlag']) 1344 self.failUnlessEqual(r['Spare'],params['Spare']) 1345 self.failUnlessEqual(r['dac'],params['dac']) 1346 self.failUnlessEqual(r['fid'],params['fid']) 1347 self.failUnlessEqual(r['month'],params['month']) 1348 self.failUnlessEqual(r['day'],params['day']) 1349 self.failUnlessAlmostEqual(r['window1_longitude'],params['window1_longitude'],5) 1350 self.failUnlessAlmostEqual(r['window1_latitude'],params['window1_latitude'],5) 1351 self.failUnlessEqual(r['fromhour1'],params['fromhour1']) 1352 self.failUnlessEqual(r['frommin1'],params['frommin1']) 1353 self.failUnlessEqual(r['tohour1'],params['tohour1']) 1354 self.failUnlessEqual(r['tomin1'],params['tomin1']) 1355 self.failUnlessEqual(r['curdir1'],params['curdir1']) 1356 self.failUnlessAlmostEqual(r['curspeed1'],params['curspeed1'],1) 1357 self.failUnlessAlmostEqual(r['window2_longitude'],params['window2_longitude'],5) 1358 self.failUnlessAlmostEqual(r['window2_latitude'],params['window2_latitude'],5) 1359 self.failUnlessEqual(r['fromhour2'],params['fromhour2']) 1360 self.failUnlessEqual(r['frommin2'],params['frommin2']) 1361 self.failUnlessEqual(r['tohour2'],params['tohour2']) 1362 self.failUnlessEqual(r['tomin2'],params['tomin2']) 1363 self.failUnlessEqual(r['curdir2'],params['curdir2']) 1364 self.failUnlessAlmostEqual(r['curspeed2'],params['curspeed2'],1) 1365 self.failUnlessAlmostEqual(r['window3_longitude'],params['window3_longitude'],5) 1366 self.failUnlessAlmostEqual(r['window3_latitude'],params['window3_latitude'],5) 1367 self.failUnlessEqual(r['fromhour3'],params['fromhour3']) 1368 self.failUnlessEqual(r['frommin3'],params['frommin3']) 1369 self.failUnlessEqual(r['tohour3'],params['tohour3']) 1370 self.failUnlessEqual(r['tomin3'],params['tomin3']) 1371 self.failUnlessEqual(r['curdir3'],params['curdir3']) 1372 self.failUnlessAlmostEqual(r['curspeed3'],params['curspeed3'],1)
1373
1374 -def addMsgOptions(parser):
1375 parser.add_option('-d','--decode',dest='doDecode',default=False,action='store_true', 1376 help='decode a "imo_tidal_window" AIS message') 1377 parser.add_option('-e','--encode',dest='doEncode',default=False,action='store_true', 1378 help='encode a "imo_tidal_window" AIS message') 1379 parser.add_option('--RepeatIndicator-field', dest='RepeatIndicatorField',default=0,metavar='uint',type='int' 1380 ,help='Field parameter value [default: %default]') 1381 parser.add_option('--UserID-field', dest='UserIDField',metavar='uint',type='int' 1382 ,help='Field parameter value [default: %default]') 1383 parser.add_option('--SeqNum-field', dest='SeqNumField',metavar='uint',type='int' 1384 ,help='Field parameter value [default: %default]') 1385 parser.add_option('--DestinationID-field', dest='DestinationIDField',metavar='uint',type='int' 1386 ,help='Field parameter value [default: %default]') 1387 parser.add_option('--RetransmitFlag-field', dest='RetransmitFlagField',metavar='bool',type='int' 1388 ,help='Field parameter value [default: %default]') 1389 parser.add_option('--month-field', dest='monthField',default=0,metavar='uint',type='int' 1390 ,help='Field parameter value [default: %default]') 1391 parser.add_option('--day-field', dest='dayField',default=0,metavar='uint',type='int' 1392 ,help='Field parameter value [default: %default]') 1393 parser.add_option('--window1_longitude-field', dest='window1_longitudeField',default=Decimal('181'),metavar='decimal',type='string' 1394 ,help='Field parameter value [default: %default]') 1395 parser.add_option('--window1_latitude-field', dest='window1_latitudeField',default=Decimal('91'),metavar='decimal',type='string' 1396 ,help='Field parameter value [default: %default]') 1397 parser.add_option('--fromhour1-field', dest='fromhour1Field',default=24,metavar='uint',type='int' 1398 ,help='Field parameter value [default: %default]') 1399 parser.add_option('--frommin1-field', dest='frommin1Field',default=60,metavar='uint',type='int' 1400 ,help='Field parameter value [default: %default]') 1401 parser.add_option('--tohour1-field', dest='tohour1Field',default=24,metavar='uint',type='int' 1402 ,help='Field parameter value [default: %default]') 1403 parser.add_option('--tomin1-field', dest='tomin1Field',default=60,metavar='uint',type='int' 1404 ,help='Field parameter value [default: %default]') 1405 parser.add_option('--curdir1-field', dest='curdir1Field',default=360,metavar='uint',type='int' 1406 ,help='Field parameter value [default: %default]') 1407 parser.add_option('--curspeed1-field', dest='curspeed1Field',default=Decimal('12.7'),metavar='udecimal',type='string' 1408 ,help='Field parameter value [default: %default]') 1409 parser.add_option('--window2_longitude-field', dest='window2_longitudeField',default=Decimal('181'),metavar='decimal',type='string' 1410 ,help='Field parameter value [default: %default]') 1411 parser.add_option('--window2_latitude-field', dest='window2_latitudeField',default=Decimal('91'),metavar='decimal',type='string' 1412 ,help='Field parameter value [default: %default]') 1413 parser.add_option('--fromhour2-field', dest='fromhour2Field',default=24,metavar='uint',type='int' 1414 ,help='Field parameter value [default: %default]') 1415 parser.add_option('--frommin2-field', dest='frommin2Field',default=60,metavar='uint',type='int' 1416 ,help='Field parameter value [default: %default]') 1417 parser.add_option('--tohour2-field', dest='tohour2Field',default=24,metavar='uint',type='int' 1418 ,help='Field parameter value [default: %default]') 1419 parser.add_option('--tomin2-field', dest='tomin2Field',default=60,metavar='uint',type='int' 1420 ,help='Field parameter value [default: %default]') 1421 parser.add_option('--curdir2-field', dest='curdir2Field',default=360,metavar='uint',type='int' 1422 ,help='Field parameter value [default: %default]') 1423 parser.add_option('--curspeed2-field', dest='curspeed2Field',default=Decimal('12.7'),metavar='udecimal',type='string' 1424 ,help='Field parameter value [default: %default]') 1425 parser.add_option('--window3_longitude-field', dest='window3_longitudeField',default=Decimal('181'),metavar='decimal',type='string' 1426 ,help='Field parameter value [default: %default]') 1427 parser.add_option('--window3_latitude-field', dest='window3_latitudeField',default=Decimal('91'),metavar='decimal',type='string' 1428 ,help='Field parameter value [default: %default]') 1429 parser.add_option('--fromhour3-field', dest='fromhour3Field',default=24,metavar='uint',type='int' 1430 ,help='Field parameter value [default: %default]') 1431 parser.add_option('--frommin3-field', dest='frommin3Field',default=60,metavar='uint',type='int' 1432 ,help='Field parameter value [default: %default]') 1433 parser.add_option('--tohour3-field', dest='tohour3Field',default=24,metavar='uint',type='int' 1434 ,help='Field parameter value [default: %default]') 1435 parser.add_option('--tomin3-field', dest='tomin3Field',default=60,metavar='uint',type='int' 1436 ,help='Field parameter value [default: %default]') 1437 parser.add_option('--curdir3-field', dest='curdir3Field',default=360,metavar='uint',type='int' 1438 ,help='Field parameter value [default: %default]') 1439 parser.add_option('--curspeed3-field', dest='curspeed3Field',default=Decimal('12.7'),metavar='udecimal',type='string' 1440 ,help='Field parameter value [default: %default]')
1441 1442 ############################################################ 1443 if __name__=='__main__': 1444 1445 from optparse import OptionParser 1446 parser = OptionParser(usage="%prog [options]", 1447 version="%prog "+__version__) 1448 1449 parser.add_option('--doc-test',dest='doctest',default=False,action='store_true', 1450 help='run the documentation tests') 1451 parser.add_option('--unit-test',dest='unittest',default=False,action='store_true', 1452 help='run the unit tests') 1453 parser.add_option('-v','--verbose',dest='verbose',default=False,action='store_true', 1454 help='Make the test output verbose') 1455 1456 # FIX: remove nmea from binary messages. No way to build the whole packet? 1457 # FIX: or build the surrounding msg 8 for a broadcast? 1458 typeChoices = ('binary','nmeapayload','nmea') # FIX: what about a USCG type message? 1459 parser.add_option('-t','--type',choices=typeChoices,type='choice',dest='ioType' 1460 ,default='nmeapayload' 1461 ,help='What kind of string to write for encoding ('+', '.join(typeChoices)+') [default: %default]') 1462 1463 1464 outputChoices = ('std','html','csv','sql' , 'kml','kml-full') 1465 parser.add_option('-T','--output-type',choices=outputChoices,type='choice',dest='outputType' 1466 ,default='std' 1467 ,help='What kind of string to output ('+', '.join(outputChoices)+') [default: %default]') 1468 1469 parser.add_option('-o','--output',dest='outputFileName',default=None, 1470 help='Name of the python file to write [default: stdout]') 1471 1472 parser.add_option('-f','--fields',dest='fieldList',default=None, action='append', 1473 choices=fieldList, 1474 help='Which fields to include in the output. Currently only for csv output [default: all]') 1475 1476 parser.add_option('-p','--print-csv-field-list',dest='printCsvfieldList',default=False,action='store_true', 1477 help='Print the field name for csv') 1478 1479 parser.add_option('-c','--sql-create',dest='sqlCreate',default=False,action='store_true', 1480 help='Print out an sql create command for the table.') 1481 1482 parser.add_option('--latex-table',dest='latexDefinitionTable',default=False,action='store_true', 1483 help='Print a LaTeX table of the type') 1484 1485 parser.add_option('--text-table',dest='textDefinitionTable',default=False,action='store_true', 1486 help='Print delimited table of the type (for Word table importing)') 1487 parser.add_option('--delimt-text-table',dest='delimTextDefinitionTable',default='\t' 1488 ,help='Delimiter for text table [default: \'%default\'](for Word table importing)') 1489 1490 1491 dbChoices = ('sqlite','postgres') 1492 parser.add_option('-D','--db-type',dest='dbType',default='postgres' 1493 ,choices=dbChoices,type='choice' 1494 ,help='What kind of database ('+', '.join(dbChoices)+') [default: %default]') 1495 1496 addMsgOptions(parser) 1497 1498 (options,args) = parser.parse_args() 1499 success=True 1500 1501 if options.doctest: 1502 import os; print os.path.basename(sys.argv[0]), 'doctests ...', 1503 sys.argv= [sys.argv[0]] 1504 if options.verbose: sys.argv.append('-v') 1505 import doctest 1506 numfail,numtests=doctest.testmod() 1507 if numfail==0: print 'ok' 1508 else: 1509 print 'FAILED' 1510 success=False 1511 1512 if not success: sys.exit('Something Failed') 1513 del success # Hide success from epydoc 1514 1515 if options.unittest: 1516 sys.argv = [sys.argv[0]] 1517 if options.verbose: sys.argv.append('-v') 1518 unittest.main() 1519 1520 outfile = sys.stdout 1521 if None!=options.outputFileName: 1522 outfile = file(options.outputFileName,'w') 1523 1524 1525 if options.doEncode: 1526 # First make sure all non required options are specified 1527 if None==options.RepeatIndicatorField: parser.error("missing value for RepeatIndicatorField") 1528 if None==options.UserIDField: parser.error("missing value for UserIDField") 1529 if None==options.SeqNumField: parser.error("missing value for SeqNumField") 1530 if None==options.DestinationIDField: parser.error("missing value for DestinationIDField") 1531 if None==options.RetransmitFlagField: parser.error("missing value for RetransmitFlagField") 1532 if None==options.monthField: parser.error("missing value for monthField") 1533 if None==options.dayField: parser.error("missing value for dayField") 1534 if None==options.window1_longitudeField: parser.error("missing value for window1_longitudeField") 1535 if None==options.window1_latitudeField: parser.error("missing value for window1_latitudeField") 1536 if None==options.fromhour1Field: parser.error("missing value for fromhour1Field") 1537 if None==options.frommin1Field: parser.error("missing value for frommin1Field") 1538 if None==options.tohour1Field: parser.error("missing value for tohour1Field") 1539 if None==options.tomin1Field: parser.error("missing value for tomin1Field") 1540 if None==options.curdir1Field: parser.error("missing value for curdir1Field") 1541 if None==options.curspeed1Field: parser.error("missing value for curspeed1Field") 1542 if None==options.window2_longitudeField: parser.error("missing value for window2_longitudeField") 1543 if None==options.window2_latitudeField: parser.error("missing value for window2_latitudeField") 1544 if None==options.fromhour2Field: parser.error("missing value for fromhour2Field") 1545 if None==options.frommin2Field: parser.error("missing value for frommin2Field") 1546 if None==options.tohour2Field: parser.error("missing value for tohour2Field") 1547 if None==options.tomin2Field: parser.error("missing value for tomin2Field") 1548 if None==options.curdir2Field: parser.error("missing value for curdir2Field") 1549 if None==options.curspeed2Field: parser.error("missing value for curspeed2Field") 1550 if None==options.window3_longitudeField: parser.error("missing value for window3_longitudeField") 1551 if None==options.window3_latitudeField: parser.error("missing value for window3_latitudeField") 1552 if None==options.fromhour3Field: parser.error("missing value for fromhour3Field") 1553 if None==options.frommin3Field: parser.error("missing value for frommin3Field") 1554 if None==options.tohour3Field: parser.error("missing value for tohour3Field") 1555 if None==options.tomin3Field: parser.error("missing value for tomin3Field") 1556 if None==options.curdir3Field: parser.error("missing value for curdir3Field") 1557 if None==options.curspeed3Field: parser.error("missing value for curspeed3Field") 1558 msgDict={ 1559 'MessageID': '6', 1560 'RepeatIndicator': options.RepeatIndicatorField, 1561 'UserID': options.UserIDField, 1562 'SeqNum': options.SeqNumField, 1563 'DestinationID': options.DestinationIDField, 1564 'RetransmitFlag': options.RetransmitFlagField, 1565 'Spare': '0', 1566 'dac': '1', 1567 'fid': '11', 1568 'month': options.monthField, 1569 'day': options.dayField, 1570 'window1_longitude': options.window1_longitudeField, 1571 'window1_latitude': options.window1_latitudeField, 1572 'fromhour1': options.fromhour1Field, 1573 'frommin1': options.frommin1Field, 1574 'tohour1': options.tohour1Field, 1575 'tomin1': options.tomin1Field, 1576 'curdir1': options.curdir1Field, 1577 'curspeed1': options.curspeed1Field, 1578 'window2_longitude': options.window2_longitudeField, 1579 'window2_latitude': options.window2_latitudeField, 1580 'fromhour2': options.fromhour2Field, 1581 'frommin2': options.frommin2Field, 1582 'tohour2': options.tohour2Field, 1583 'tomin2': options.tomin2Field, 1584 'curdir2': options.curdir2Field, 1585 'curspeed2': options.curspeed2Field, 1586 'window3_longitude': options.window3_longitudeField, 1587 'window3_latitude': options.window3_latitudeField, 1588 'fromhour3': options.fromhour3Field, 1589 'frommin3': options.frommin3Field, 1590 'tohour3': options.tohour3Field, 1591 'tomin3': options.tomin3Field, 1592 'curdir3': options.curdir3Field, 1593 'curspeed3': options.curspeed3Field, 1594 } 1595 1596 bits = encode(msgDict) 1597 if 'binary'==options.ioType: print str(bits) 1598 elif 'nmeapayload'==options.ioType: 1599 # FIX: figure out if this might be necessary at compile time 1600 print "bitLen",len(bits) 1601 bitLen=len(bits) 1602 if bitLen%6!=0: 1603 bits = bits + BitVector(size=(6 - (bitLen%6))) # Pad out to multiple of 6 1604 print "result:",binary.bitvectoais6(bits)[0] 1605 1606 1607 # FIX: Do not emit this option for the binary message payloads. Does not make sense. 1608 elif 'nmea'==options.ioType: sys.exit("FIX: need to implement this capability") 1609 else: sys.exit('ERROR: unknown ioType. Help!') 1610 1611 1612 if options.sqlCreate: 1613 sqlCreateStr(outfile,options.fieldList,dbType=options.dbType) 1614 1615 if options.latexDefinitionTable: 1616 latexDefinitionTable(outfile) 1617 1618 # For conversion to word tables 1619 if options.textDefinitionTable: 1620 textDefinitionTable(outfile,options.delimTextDefinitionTable) 1621 1622 if options.printCsvfieldList: 1623 # Make a csv separated list of fields that will be displayed for csv 1624 if None == options.fieldList: options.fieldList = fieldList 1625 import StringIO 1626 buf = StringIO.StringIO() 1627 for field in options.fieldList: 1628 buf.write(field+',') 1629 result = buf.getvalue() 1630 if result[-1] == ',': print result[:-1] 1631 else: print result 1632 1633 if options.doDecode: 1634 if len(args)==0: args = sys.stdin 1635 for msg in args: 1636 bv = None 1637 1638 if msg[0] in ('$','!') and msg[3:6] in ('VDM','VDO'): 1639 # Found nmea 1640 # FIX: do checksum 1641 bv = binary.ais6tobitvec(msg.split(',')[5]) 1642 else: # either binary or nmeapayload... expect mostly nmeapayloads 1643 # assumes that an all 0 and 1 string can not be a nmeapayload 1644 binaryMsg=True 1645 for c in msg: 1646 if c not in ('0','1'): 1647 binaryMsg=False 1648 break 1649 if binaryMsg: 1650 bv = BitVector(bitstring=msg) 1651 else: # nmeapayload 1652 bv = binary.ais6tobitvec(msg) 1653 1654 printFields(decode(bv) 1655 ,out=outfile 1656 ,format=options.outputType 1657 ,fieldList=options.fieldList 1658 ,dbType=options.dbType 1659 ) 1660