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

Source Code for Module ais.whalenotice2

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