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: 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          '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 dbTableName='whalenotice' 932 'Database table name' 933
934 -def sqlCreateStr(outfile=sys.stdout, fields=None, extraFields=None 935 ,addCoastGuardFields=True 936 ,dbType='postgres' 937 ):
938 ''' 939 Return the SQL CREATE command for this message type 940 @param outfile: file like object to print to. 941 @param fields: which fields to put in the create. Defaults to all. 942 @param extraFields: A sequence of tuples containing (name,sql type) for additional fields 943 @param addCoastGuardFields: Add the extra fields that come after the NMEA check some from the USCG N-AIS format 944 @param dbType: Which flavor of database we are using so that the create is tailored ('sqlite' or 'postgres') 945 @type addCoastGuardFields: bool 946 @return: sql create string 947 @rtype: str 948 949 @see: sqlCreate 950 ''' 951 # FIX: should this sqlCreate be the same as in LaTeX (createFuncName) rather than hard coded? 952 outfile.write(str(sqlCreate(fields,extraFields,addCoastGuardFields,dbType=dbType)))
953
954 -def sqlCreate(fields=None, extraFields=None, addCoastGuardFields=True, dbType='postgres'):
955 ''' 956 Return the sqlhelp object to create the table. 957 958 @param fields: which fields to put in the create. Defaults to all. 959 @param extraFields: A sequence of tuples containing (name,sql type) for additional fields 960 @param addCoastGuardFields: Add the extra fields that come after the NMEA check some from the USCG N-AIS format 961 @type addCoastGuardFields: bool 962 @param dbType: Which flavor of database we are using so that the create is tailored ('sqlite' or 'postgres') 963 @return: An object that can be used to generate a return 964 @rtype: sqlhelp.create 965 ''' 966 if None == fields: fields = fieldList 967 import sqlhelp 968 c = sqlhelp.create('whalenotice',dbType=dbType) 969 c.addPrimaryKey() 970 if 'MessageID' in fields: c.addInt ('MessageID') 971 if 'RepeatIndicator' in fields: c.addInt ('RepeatIndicator') 972 if 'UserID' in fields: c.addInt ('UserID') 973 if 'Spare' in fields: c.addInt ('Spare') 974 if 'dac' in fields: c.addInt ('dac') 975 if 'fid' in fields: c.addInt ('fid') 976 if 'efid' in fields: c.addInt ('efid') 977 if 'numreports' in fields: c.addInt ('numreports') 978 if 'stationid1' in fields: c.addInt ('stationid1') 979 if 'time1_day' in fields: c.addInt ('time1_day') 980 if 'time1_hour' in fields: c.addInt ('time1_hour') 981 if 'time1_min' in fields: c.addInt ('time1_min') 982 if dbType != 'postgres': 983 if 'center1_longitude' in fields: c.addDecimal('center1_longitude',8,5) 984 if dbType != 'postgres': 985 if 'center1_latitude' in fields: c.addDecimal('center1_latitude',8,5) 986 if 'timetoexpire1' in fields: c.addInt ('timetoexpire1') 987 if 'radius1' in fields: c.addInt ('radius1') 988 if 'stationid2' in fields: c.addInt ('stationid2') 989 if 'time2_day' in fields: c.addInt ('time2_day') 990 if 'time2_hour' in fields: c.addInt ('time2_hour') 991 if 'time2_min' in fields: c.addInt ('time2_min') 992 if dbType != 'postgres': 993 if 'center2_longitude' in fields: c.addDecimal('center2_longitude',8,5) 994 if dbType != 'postgres': 995 if 'center2_latitude' in fields: c.addDecimal('center2_latitude',8,5) 996 if 'timetoexpire2' in fields: c.addInt ('timetoexpire2') 997 if 'radius2' in fields: c.addInt ('radius2') 998 if 'stationid3' in fields: c.addInt ('stationid3') 999 if 'time3_day' in fields: c.addInt ('time3_day') 1000 if 'time3_hour' in fields: c.addInt ('time3_hour') 1001 if 'time3_min' in fields: c.addInt ('time3_min') 1002 if dbType != 'postgres': 1003 if 'center3_longitude' in fields: c.addDecimal('center3_longitude',8,5) 1004 if dbType != 'postgres': 1005 if 'center3_latitude' in fields: c.addDecimal('center3_latitude',8,5) 1006 if 'timetoexpire3' in fields: c.addInt ('timetoexpire3') 1007 if 'radius3' in fields: c.addInt ('radius3') 1008 if 'Spare2' in fields: c.addInt ('Spare2') 1009 1010 if addCoastGuardFields: 1011 # c.addInt('cg_rssi') # Relative signal strength indicator 1012 # c.addInt('cg_d') # dBm receive strength 1013 # c.addInt('cg_T') # Receive timestamp from the AIS equipment 1014 # c.addInt('cg_S') # Slot received in 1015 # c.addVarChar('cg_x',10) # Idonno 1016 c.addVarChar('cg_r',15) # Receiver station ID - should usually be an MMSI, but sometimes is a string 1017 c.addInt('cg_sec') # UTC seconds since the epoch 1018 1019 c.addTimestamp('cg_timestamp') # UTC decoded cg_sec - not actually in the data stream 1020 1021 if dbType == 'postgres': 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('center1','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('center2','POINT',2,SRID=4326); 1028 #--- EPSG 4326 : WGS 84 1029 #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 '); 1030 c.addPostGIS('center3','POINT',2,SRID=4326); 1031 1032 return c
1033
1034 -def sqlInsertStr(params, outfile=sys.stdout, extraParams=None, dbType='postgres'):
1035 ''' 1036 Return the SQL INSERT command for this message type 1037 @param params: dictionary of values keyed by field name 1038 @param outfile: file like object to print to. 1039 @param extraParams: A sequence of tuples containing (name,sql type) for additional fields 1040 @return: sql create string 1041 @rtype: str 1042 1043 @see: sqlCreate 1044 ''' 1045 outfile.write(str(sqlInsert(params,extraParams,dbType=dbType)))
1046 1047
1048 -def sqlInsert(params,extraParams=None,dbType='postgres'):
1049 ''' 1050 Give the SQL INSERT statement 1051 @param params: dict keyed by field name of values 1052 @param extraParams: any extra fields that you have created beyond the normal ais message fields 1053 @rtype: sqlhelp.insert 1054 @return: insert class instance 1055 @todo: allow optional type checking of params? 1056 @warning: this will take invalid keys happily and do what??? 1057 ''' 1058 import sqlhelp 1059 i = sqlhelp.insert('whalenotice',dbType=dbType) 1060 1061 if dbType=='postgres': 1062 finished = [] 1063 for key in params: 1064 if key in finished: 1065 continue 1066 1067 if key not in toPgFields and key not in fromPgFields: 1068 if type(params[key])==Decimal: i.add(key,float(params[key])) 1069 else: i.add(key,params[key]) 1070 else: 1071 if key in fromPgFields: 1072 val = params[key] 1073 # Had better be a WKT type like POINT(-88.1 30.321) 1074 i.addPostGIS(key,val) 1075 finished.append(key) 1076 else: 1077 # Need to construct the type. 1078 pgName = toPgFields[key] 1079 #valStr='GeomFromText(\''+pgTypes[pgName]+'(' 1080 valStr=pgTypes[pgName]+'(' 1081 vals = [] 1082 for nonPgKey in fromPgFields[pgName]: 1083 vals.append(str(params[nonPgKey])) 1084 finished.append(nonPgKey) 1085 valStr+=' '.join(vals)+')' 1086 i.addPostGIS(pgName,valStr) 1087 else: 1088 for key in params: 1089 if type(params[key])==Decimal: i.add(key,float(params[key])) 1090 else: i.add(key,params[key]) 1091 1092 if None != extraParams: 1093 for key in extraParams: 1094 i.add(key,extraParams[key]) 1095 1096 return i
1097 1098 ###################################################################### 1099 # LATEX SUPPORT 1100 ###################################################################### 1101
1102 -def latexDefinitionTable(outfile=sys.stdout 1103 ):
1104 ''' 1105 Return the LaTeX definition table for this message type 1106 @param outfile: file like object to print to. 1107 @type outfile: file obj 1108 @return: LaTeX table string via the outfile 1109 @rtype: str 1110 1111 ''' 1112 o = outfile 1113 1114 o.write(''' 1115 \\begin{table}%[htb] 1116 \\centering 1117 \\begin{tabular}{|l|c|l|} 1118 \\hline 1119 Parameter & Number of bits & Description 1120 \\\\ \\hline\\hline 1121 MessageID & 6 & AIS message number. Must be 8 \\\\ \hline 1122 RepeatIndicator & 2 & Indicated how many times a message has been repeated \\\\ \hline 1123 UserID & 30 & Unique ship identification number (MMSI) \\\\ \hline 1124 Spare & 2 & Reserved for definition by a regional authority. \\\\ \hline 1125 dac & 10 & Designated Area Code - 366 for the United States \\\\ \hline 1126 fid & 6 & Functional IDentifier - 63 for the Whale Notice \\\\ \hline 1127 efid & 12 & Extended Functional IDentifier. 1 for the Whale Notice (dac+fid+efid defines the exact message type) \\\\ \hline 1128 numreports & 2 & Number of detection reports filled out in this message \\\\ \hline 1129 stationid1 & 8 & Identifier of the station that recorded the whale. Usually a number. \\\\ \hline 1130 time1\_day & 5 & Time of most recent whale detection. UTC day of the month 1..31 \\\\ \hline 1131 time1\_hour & 5 & Time of most recent whale detection. UTC hours 0..23 \\\\ \hline 1132 time1\_min & 6 & Time of most recent whale detection. UTC minutes \\\\ \hline 1133 center1\_longitude & 28 & Center of the detection zone. East West location \\\\ \hline 1134 center1\_latitude & 27 & Center of the detection zone. North South location \\\\ \hline 1135 timetoexpire1 & 16 & Seconds from the detection time until the notice expires \\\\ \hline 1136 radius1 & 16 & Distance from center of detection zone (lat/lon above) \\\\ \hline 1137 stationid2 & 8 & Identifier of the station that recorded the whale. Usually a number. \\\\ \hline 1138 time2\_day & 5 & Time of most recent whale detection. UTC day of the month 1..31 \\\\ \hline 1139 time2\_hour & 5 & Time of most recent whale detection. UTC hours 0..23 \\\\ \hline 1140 time2\_min & 6 & Time of most recent whale detection. UTC minutes \\\\ \hline 1141 center2\_longitude & 28 & Center of the detection zone. East West location \\\\ \hline 1142 center2\_latitude & 27 & Center of the detection zone. North South location \\\\ \hline 1143 timetoexpire2 & 16 & Seconds from the detection time until the notice expires \\\\ \hline 1144 radius2 & 16 & Distance from center of detection zone (lat/lon above) \\\\ \hline 1145 stationid3 & 8 & Identifier of the station that recorded the whale. Usually a number. \\\\ \hline 1146 time3\_day & 5 & Time of most recent whale detection. UTC day of the month 1..31 \\\\ \hline 1147 time3\_hour & 5 & Time of most recent whale detection. UTC hours 0..23 \\\\ \hline 1148 time3\_min & 6 & Time of most recent whale detection. UTC minutes \\\\ \hline 1149 center3\_longitude & 28 & Center of the detection zone. East West location \\\\ \hline 1150 center3\_latitude & 27 & Center of the detection zone. North South location \\\\ \hline 1151 timetoexpire3 & 16 & Seconds from the detection time until the notice expires \\\\ \hline 1152 radius3 & 16 & Distance from center of detection zone (lat/lon above) \\\\ \hline 1153 Spare2 & 21 & Not used. Should be set to zero.\\\\ \\hline \\hline 1154 Total bits & 424 & Appears to take 2 slots \\\\ \\hline 1155 \\end{tabular} 1156 \\caption{AIS message number 8: Endangered whale notification binary message} 1157 \\label{tab:whalenotice} 1158 \\end{table} 1159 ''')
1160 1161 ###################################################################### 1162 # Text Definition 1163 ###################################################################### 1164
1165 -def textDefinitionTable(outfile=sys.stdout 1166 ,delim='\t' 1167 ):
1168 ''' 1169 Return the text definition table for this message type 1170 @param outfile: file like object to print to. 1171 @type outfile: file obj 1172 @return: text table string via the outfile 1173 @rtype: str 1174 1175 ''' 1176 o = outfile 1177 o.write('''Parameter'''+delim+'Number of bits'''+delim+'''Description 1178 MessageID'''+delim+'''6'''+delim+'''AIS message number. Must be 8 1179 RepeatIndicator'''+delim+'''2'''+delim+'''Indicated how many times a message has been repeated 1180 UserID'''+delim+'''30'''+delim+'''Unique ship identification number (MMSI) 1181 Spare'''+delim+'''2'''+delim+'''Reserved for definition by a regional authority. 1182 dac'''+delim+'''10'''+delim+'''Designated Area Code - 366 for the United States 1183 fid'''+delim+'''6'''+delim+'''Functional IDentifier - 63 for the Whale Notice 1184 efid'''+delim+'''12'''+delim+'''Extended Functional IDentifier. 1 for the Whale Notice (dac+fid+efid defines the exact message type) 1185 numreports'''+delim+'''2'''+delim+'''Number of detection reports filled out in this message 1186 stationid1'''+delim+'''8'''+delim+'''Identifier of the station that recorded the whale. Usually a number. 1187 time1_day'''+delim+'''5'''+delim+'''Time of most recent whale detection. UTC day of the month 1..31 1188 time1_hour'''+delim+'''5'''+delim+'''Time of most recent whale detection. UTC hours 0..23 1189 time1_min'''+delim+'''6'''+delim+'''Time of most recent whale detection. UTC minutes 1190 center1_longitude'''+delim+'''28'''+delim+'''Center of the detection zone. East West location 1191 center1_latitude'''+delim+'''27'''+delim+'''Center of the detection zone. North South location 1192 timetoexpire1'''+delim+'''16'''+delim+'''Seconds from the detection time until the notice expires 1193 radius1'''+delim+'''16'''+delim+'''Distance from center of detection zone (lat/lon above) 1194 stationid2'''+delim+'''8'''+delim+'''Identifier of the station that recorded the whale. Usually a number. 1195 time2_day'''+delim+'''5'''+delim+'''Time of most recent whale detection. UTC day of the month 1..31 1196 time2_hour'''+delim+'''5'''+delim+'''Time of most recent whale detection. UTC hours 0..23 1197 time2_min'''+delim+'''6'''+delim+'''Time of most recent whale detection. UTC minutes 1198 center2_longitude'''+delim+'''28'''+delim+'''Center of the detection zone. East West location 1199 center2_latitude'''+delim+'''27'''+delim+'''Center of the detection zone. North South location 1200 timetoexpire2'''+delim+'''16'''+delim+'''Seconds from the detection time until the notice expires 1201 radius2'''+delim+'''16'''+delim+'''Distance from center of detection zone (lat/lon above) 1202 stationid3'''+delim+'''8'''+delim+'''Identifier of the station that recorded the whale. Usually a number. 1203 time3_day'''+delim+'''5'''+delim+'''Time of most recent whale detection. UTC day of the month 1..31 1204 time3_hour'''+delim+'''5'''+delim+'''Time of most recent whale detection. UTC hours 0..23 1205 time3_min'''+delim+'''6'''+delim+'''Time of most recent whale detection. UTC minutes 1206 center3_longitude'''+delim+'''28'''+delim+'''Center of the detection zone. East West location 1207 center3_latitude'''+delim+'''27'''+delim+'''Center of the detection zone. North South location 1208 timetoexpire3'''+delim+'''16'''+delim+'''Seconds from the detection time until the notice expires 1209 radius3'''+delim+'''16'''+delim+'''Distance from center of detection zone (lat/lon above) 1210 Spare2'''+delim+'''21'''+delim+'''Not used. Should be set to zero. 1211 Total bits'''+delim+'''424'''+delim+'''Appears to take 2 slots''')
1212 1213 1214 ###################################################################### 1215 # UNIT TESTING 1216 ###################################################################### 1217 import unittest
1218 -def testParams():
1219 '''Return a params file base on the testvalue tags. 1220 @rtype: dict 1221 @return: params based on testvalue tags 1222 ''' 1223 params = {} 1224 params['MessageID'] = 8 1225 params['RepeatIndicator'] = 1 1226 params['UserID'] = 1193046 1227 params['Spare'] = 0 1228 params['dac'] = 366 1229 params['fid'] = 63 1230 params['efid'] = 1 1231 params['numreports'] = 3 1232 params['stationid1'] = 76 1233 params['time1_day'] = 28 1234 params['time1_hour'] = 23 1235 params['time1_min'] = 45 1236 params['center1_longitude'] = Decimal('-122.16328055555556') 1237 params['center1_latitude'] = Decimal('37.424458333333334') 1238 params['timetoexpire1'] = 1 1239 params['radius1'] = 5000 1240 params['stationid2'] = 76 1241 params['time2_day'] = 28 1242 params['time2_hour'] = 23 1243 params['time2_min'] = 45 1244 params['center2_longitude'] = Decimal('-122.16328055555556') 1245 params['center2_latitude'] = Decimal('37.424458333333334') 1246 params['timetoexpire2'] = 1 1247 params['radius2'] = 5000 1248 params['stationid3'] = 76 1249 params['time3_day'] = 28 1250 params['time3_hour'] = 23 1251 params['time3_min'] = 45 1252 params['center3_longitude'] = Decimal('-122.16328055555556') 1253 params['center3_latitude'] = Decimal('37.424458333333334') 1254 params['timetoexpire3'] = 1 1255 params['radius3'] = 5000 1256 params['Spare2'] = 0 1257 1258 return params
1259
1260 -class Testwhalenotice(unittest.TestCase):
1261 '''Use testvalue tag text from each type to build test case the whalenotice message'''
1262 - def testEncodeDecode(self):
1263 1264 params = testParams() 1265 bits = encode(params) 1266 r = decode(bits) 1267 1268 # Check that each parameter came through ok. 1269 self.failUnlessEqual(r['MessageID'],params['MessageID']) 1270 self.failUnlessEqual(r['RepeatIndicator'],params['RepeatIndicator']) 1271 self.failUnlessEqual(r['UserID'],params['UserID']) 1272 self.failUnlessEqual(r['Spare'],params['Spare']) 1273 self.failUnlessEqual(r['dac'],params['dac']) 1274 self.failUnlessEqual(r['fid'],params['fid']) 1275 self.failUnlessEqual(r['efid'],params['efid']) 1276 self.failUnlessEqual(r['numreports'],params['numreports']) 1277 self.failUnlessEqual(r['stationid1'],params['stationid1']) 1278 self.failUnlessEqual(r['time1_day'],params['time1_day']) 1279 self.failUnlessEqual(r['time1_hour'],params['time1_hour']) 1280 self.failUnlessEqual(r['time1_min'],params['time1_min']) 1281 self.failUnlessAlmostEqual(r['center1_longitude'],params['center1_longitude'],5) 1282 self.failUnlessAlmostEqual(r['center1_latitude'],params['center1_latitude'],5) 1283 self.failUnlessEqual(r['timetoexpire1'],params['timetoexpire1']) 1284 self.failUnlessEqual(r['radius1'],params['radius1']) 1285 self.failUnlessEqual(r['stationid2'],params['stationid2']) 1286 self.failUnlessEqual(r['time2_day'],params['time2_day']) 1287 self.failUnlessEqual(r['time2_hour'],params['time2_hour']) 1288 self.failUnlessEqual(r['time2_min'],params['time2_min']) 1289 self.failUnlessAlmostEqual(r['center2_longitude'],params['center2_longitude'],5) 1290 self.failUnlessAlmostEqual(r['center2_latitude'],params['center2_latitude'],5) 1291 self.failUnlessEqual(r['timetoexpire2'],params['timetoexpire2']) 1292 self.failUnlessEqual(r['radius2'],params['radius2']) 1293 self.failUnlessEqual(r['stationid3'],params['stationid3']) 1294 self.failUnlessEqual(r['time3_day'],params['time3_day']) 1295 self.failUnlessEqual(r['time3_hour'],params['time3_hour']) 1296 self.failUnlessEqual(r['time3_min'],params['time3_min']) 1297 self.failUnlessAlmostEqual(r['center3_longitude'],params['center3_longitude'],5) 1298 self.failUnlessAlmostEqual(r['center3_latitude'],params['center3_latitude'],5) 1299 self.failUnlessEqual(r['timetoexpire3'],params['timetoexpire3']) 1300 self.failUnlessEqual(r['radius3'],params['radius3']) 1301 self.failUnlessEqual(r['Spare2'],params['Spare2'])
1302
1303 -def addMsgOptions(parser):
1304 parser.add_option('-d','--decode',dest='doDecode',default=False,action='store_true', 1305 help='decode a "whalenotice" AIS message') 1306 parser.add_option('-e','--encode',dest='doEncode',default=False,action='store_true', 1307 help='encode a "whalenotice" AIS message') 1308 parser.add_option('--RepeatIndicator-field', dest='RepeatIndicatorField',default=0,metavar='uint',type='int' 1309 ,help='Field parameter value [default: %default]') 1310 parser.add_option('--UserID-field', dest='UserIDField',metavar='uint',type='int' 1311 ,help='Field parameter value [default: %default]') 1312 parser.add_option('--numreports-field', dest='numreportsField',default=0,metavar='uint',type='int' 1313 ,help='Field parameter value [default: %default]') 1314 parser.add_option('--stationid1-field', dest='stationid1Field',default=0,metavar='uint',type='int' 1315 ,help='Field parameter value [default: %default]') 1316 parser.add_option('--time1_day-field', dest='time1_dayField',metavar='uint',type='int' 1317 ,help='Field parameter value [default: %default]') 1318 parser.add_option('--time1_hour-field', dest='time1_hourField',metavar='uint',type='int' 1319 ,help='Field parameter value [default: %default]') 1320 parser.add_option('--time1_min-field', dest='time1_minField',metavar='uint',type='int' 1321 ,help='Field parameter value [default: %default]') 1322 parser.add_option('--center1_longitude-field', dest='center1_longitudeField',default=Decimal('181'),metavar='decimal',type='string' 1323 ,help='Field parameter value [default: %default]') 1324 parser.add_option('--center1_latitude-field', dest='center1_latitudeField',default=Decimal('91'),metavar='decimal',type='string' 1325 ,help='Field parameter value [default: %default]') 1326 parser.add_option('--timetoexpire1-field', dest='timetoexpire1Field',default=65535,metavar='uint',type='int' 1327 ,help='Field parameter value [default: %default]') 1328 parser.add_option('--radius1-field', dest='radius1Field',default=65534,metavar='uint',type='int' 1329 ,help='Field parameter value [default: %default]') 1330 parser.add_option('--stationid2-field', dest='stationid2Field',default=0,metavar='uint',type='int' 1331 ,help='Field parameter value [default: %default]') 1332 parser.add_option('--time2_day-field', dest='time2_dayField',metavar='uint',type='int' 1333 ,help='Field parameter value [default: %default]') 1334 parser.add_option('--time2_hour-field', dest='time2_hourField',metavar='uint',type='int' 1335 ,help='Field parameter value [default: %default]') 1336 parser.add_option('--time2_min-field', dest='time2_minField',metavar='uint',type='int' 1337 ,help='Field parameter value [default: %default]') 1338 parser.add_option('--center2_longitude-field', dest='center2_longitudeField',default=Decimal('181'),metavar='decimal',type='string' 1339 ,help='Field parameter value [default: %default]') 1340 parser.add_option('--center2_latitude-field', dest='center2_latitudeField',default=Decimal('91'),metavar='decimal',type='string' 1341 ,help='Field parameter value [default: %default]') 1342 parser.add_option('--timetoexpire2-field', dest='timetoexpire2Field',default=65535,metavar='uint',type='int' 1343 ,help='Field parameter value [default: %default]') 1344 parser.add_option('--radius2-field', dest='radius2Field',default=65534,metavar='uint',type='int' 1345 ,help='Field parameter value [default: %default]') 1346 parser.add_option('--stationid3-field', dest='stationid3Field',default=0,metavar='uint',type='int' 1347 ,help='Field parameter value [default: %default]') 1348 parser.add_option('--time3_day-field', dest='time3_dayField',metavar='uint',type='int' 1349 ,help='Field parameter value [default: %default]') 1350 parser.add_option('--time3_hour-field', dest='time3_hourField',metavar='uint',type='int' 1351 ,help='Field parameter value [default: %default]') 1352 parser.add_option('--time3_min-field', dest='time3_minField',metavar='uint',type='int' 1353 ,help='Field parameter value [default: %default]') 1354 parser.add_option('--center3_longitude-field', dest='center3_longitudeField',default=Decimal('181'),metavar='decimal',type='string' 1355 ,help='Field parameter value [default: %default]') 1356 parser.add_option('--center3_latitude-field', dest='center3_latitudeField',default=Decimal('91'),metavar='decimal',type='string' 1357 ,help='Field parameter value [default: %default]') 1358 parser.add_option('--timetoexpire3-field', dest='timetoexpire3Field',default=65535,metavar='uint',type='int' 1359 ,help='Field parameter value [default: %default]') 1360 parser.add_option('--radius3-field', dest='radius3Field',default=65534,metavar='uint',type='int' 1361 ,help='Field parameter value [default: %default]')
1362 1363 ############################################################ 1364 if __name__=='__main__': 1365 1366 from optparse import OptionParser 1367 parser = OptionParser(usage="%prog [options]", 1368 version="%prog "+__version__) 1369 1370 parser.add_option('--doc-test',dest='doctest',default=False,action='store_true', 1371 help='run the documentation tests') 1372 parser.add_option('--unit-test',dest='unittest',default=False,action='store_true', 1373 help='run the unit tests') 1374 parser.add_option('-v','--verbose',dest='verbose',default=False,action='store_true', 1375 help='Make the test output verbose') 1376 1377 # FIX: remove nmea from binary messages. No way to build the whole packet? 1378 # FIX: or build the surrounding msg 8 for a broadcast? 1379 typeChoices = ('binary','nmeapayload','nmea') # FIX: what about a USCG type message? 1380 parser.add_option('-t','--type',choices=typeChoices,type='choice',dest='ioType' 1381 ,default='nmeapayload' 1382 ,help='What kind of string to write for encoding ('+', '.join(typeChoices)+') [default: %default]') 1383 1384 1385 outputChoices = ('std','html','csv','sql' , 'kml','kml-full') 1386 parser.add_option('-T','--output-type',choices=outputChoices,type='choice',dest='outputType' 1387 ,default='std' 1388 ,help='What kind of string to output ('+', '.join(outputChoices)+') [default: %default]') 1389 1390 parser.add_option('-o','--output',dest='outputFileName',default=None, 1391 help='Name of the python file to write [default: stdout]') 1392 1393 parser.add_option('-f','--fields',dest='fieldList',default=None, action='append', 1394 choices=fieldList, 1395 help='Which fields to include in the output. Currently only for csv output [default: all]') 1396 1397 parser.add_option('-p','--print-csv-field-list',dest='printCsvfieldList',default=False,action='store_true', 1398 help='Print the field name for csv') 1399 1400 parser.add_option('-c','--sql-create',dest='sqlCreate',default=False,action='store_true', 1401 help='Print out an sql create command for the table.') 1402 1403 parser.add_option('--latex-table',dest='latexDefinitionTable',default=False,action='store_true', 1404 help='Print a LaTeX table of the type') 1405 1406 parser.add_option('--text-table',dest='textDefinitionTable',default=False,action='store_true', 1407 help='Print delimited table of the type (for Word table importing)') 1408 parser.add_option('--delimt-text-table',dest='delimTextDefinitionTable',default='\t' 1409 ,help='Delimiter for text table [default: \'%default\'](for Word table importing)') 1410 1411 1412 dbChoices = ('sqlite','postgres') 1413 parser.add_option('-D','--db-type',dest='dbType',default='postgres' 1414 ,choices=dbChoices,type='choice' 1415 ,help='What kind of database ('+', '.join(dbChoices)+') [default: %default]') 1416 1417 addMsgOptions(parser) 1418 1419 (options,args) = parser.parse_args() 1420 success=True 1421 1422 if options.doctest: 1423 import os; print os.path.basename(sys.argv[0]), 'doctests ...', 1424 sys.argv= [sys.argv[0]] 1425 if options.verbose: sys.argv.append('-v') 1426 import doctest 1427 numfail,numtests=doctest.testmod() 1428 if numfail==0: print 'ok' 1429 else: 1430 print 'FAILED' 1431 success=False 1432 1433 if not success: sys.exit('Something Failed') 1434 del success # Hide success from epydoc 1435 1436 if options.unittest: 1437 sys.argv = [sys.argv[0]] 1438 if options.verbose: sys.argv.append('-v') 1439 unittest.main() 1440 1441 outfile = sys.stdout 1442 if None!=options.outputFileName: 1443 outfile = file(options.outputFileName,'w') 1444 1445 1446 if options.doEncode: 1447 # First make sure all non required options are specified 1448 if None==options.RepeatIndicatorField: parser.error("missing value for RepeatIndicatorField") 1449 if None==options.UserIDField: parser.error("missing value for UserIDField") 1450 if None==options.numreportsField: parser.error("missing value for numreportsField") 1451 if None==options.stationid1Field: parser.error("missing value for stationid1Field") 1452 if None==options.time1_dayField: parser.error("missing value for time1_dayField") 1453 if None==options.time1_hourField: parser.error("missing value for time1_hourField") 1454 if None==options.time1_minField: parser.error("missing value for time1_minField") 1455 if None==options.center1_longitudeField: parser.error("missing value for center1_longitudeField") 1456 if None==options.center1_latitudeField: parser.error("missing value for center1_latitudeField") 1457 if None==options.timetoexpire1Field: parser.error("missing value for timetoexpire1Field") 1458 if None==options.radius1Field: parser.error("missing value for radius1Field") 1459 if None==options.stationid2Field: parser.error("missing value for stationid2Field") 1460 if None==options.time2_dayField: parser.error("missing value for time2_dayField") 1461 if None==options.time2_hourField: parser.error("missing value for time2_hourField") 1462 if None==options.time2_minField: parser.error("missing value for time2_minField") 1463 if None==options.center2_longitudeField: parser.error("missing value for center2_longitudeField") 1464 if None==options.center2_latitudeField: parser.error("missing value for center2_latitudeField") 1465 if None==options.timetoexpire2Field: parser.error("missing value for timetoexpire2Field") 1466 if None==options.radius2Field: parser.error("missing value for radius2Field") 1467 if None==options.stationid3Field: parser.error("missing value for stationid3Field") 1468 if None==options.time3_dayField: parser.error("missing value for time3_dayField") 1469 if None==options.time3_hourField: parser.error("missing value for time3_hourField") 1470 if None==options.time3_minField: parser.error("missing value for time3_minField") 1471 if None==options.center3_longitudeField: parser.error("missing value for center3_longitudeField") 1472 if None==options.center3_latitudeField: parser.error("missing value for center3_latitudeField") 1473 if None==options.timetoexpire3Field: parser.error("missing value for timetoexpire3Field") 1474 if None==options.radius3Field: parser.error("missing value for radius3Field") 1475 msgDict={ 1476 'MessageID': '8', 1477 'RepeatIndicator': options.RepeatIndicatorField, 1478 'UserID': options.UserIDField, 1479 'Spare': '0', 1480 'dac': '366', 1481 'fid': '63', 1482 'efid': '1', 1483 'numreports': options.numreportsField, 1484 'stationid1': options.stationid1Field, 1485 'time1_day': options.time1_dayField, 1486 'time1_hour': options.time1_hourField, 1487 'time1_min': options.time1_minField, 1488 'center1_longitude': options.center1_longitudeField, 1489 'center1_latitude': options.center1_latitudeField, 1490 'timetoexpire1': options.timetoexpire1Field, 1491 'radius1': options.radius1Field, 1492 'stationid2': options.stationid2Field, 1493 'time2_day': options.time2_dayField, 1494 'time2_hour': options.time2_hourField, 1495 'time2_min': options.time2_minField, 1496 'center2_longitude': options.center2_longitudeField, 1497 'center2_latitude': options.center2_latitudeField, 1498 'timetoexpire2': options.timetoexpire2Field, 1499 'radius2': options.radius2Field, 1500 'stationid3': options.stationid3Field, 1501 'time3_day': options.time3_dayField, 1502 'time3_hour': options.time3_hourField, 1503 'time3_min': options.time3_minField, 1504 'center3_longitude': options.center3_longitudeField, 1505 'center3_latitude': options.center3_latitudeField, 1506 'timetoexpire3': options.timetoexpire3Field, 1507 'radius3': options.radius3Field, 1508 'Spare2': '0', 1509 } 1510 1511 bits = encode(msgDict) 1512 if 'binary'==options.ioType: print str(bits) 1513 elif 'nmeapayload'==options.ioType: 1514 # FIX: figure out if this might be necessary at compile time 1515 print "bitLen",len(bits) 1516 bitLen=len(bits) 1517 if bitLen%6!=0: 1518 bits = bits + BitVector(size=(6 - (bitLen%6))) # Pad out to multiple of 6 1519 print "result:",binary.bitvectoais6(bits)[0] 1520 1521 1522 # FIX: Do not emit this option for the binary message payloads. Does not make sense. 1523 elif 'nmea'==options.ioType: sys.exit("FIX: need to implement this capability") 1524 else: sys.exit('ERROR: unknown ioType. Help!') 1525 1526 1527 if options.sqlCreate: 1528 sqlCreateStr(outfile,options.fieldList,dbType=options.dbType) 1529 1530 if options.latexDefinitionTable: 1531 latexDefinitionTable(outfile) 1532 1533 # For conversion to word tables 1534 if options.textDefinitionTable: 1535 textDefinitionTable(outfile,options.delimTextDefinitionTable) 1536 1537 if options.printCsvfieldList: 1538 # Make a csv separated list of fields that will be displayed for csv 1539 if None == options.fieldList: options.fieldList = fieldList 1540 import StringIO 1541 buf = StringIO.StringIO() 1542 for field in options.fieldList: 1543 buf.write(field+',') 1544 result = buf.getvalue() 1545 if result[-1] == ',': print result[:-1] 1546 else: print result 1547 1548 if options.doDecode: 1549 if len(args)==0: args = sys.stdin 1550 for msg in args: 1551 bv = None 1552 1553 if msg[0] in ('$','!') and msg[3:6] in ('VDM','VDO'): 1554 # Found nmea 1555 # FIX: do checksum 1556 bv = binary.ais6tobitvec(msg.split(',')[5]) 1557 else: # either binary or nmeapayload... expect mostly nmeapayloads 1558 # assumes that an all 0 and 1 string can not be a nmeapayload 1559 binaryMsg=True 1560 for c in msg: 1561 if c not in ('0','1'): 1562 binaryMsg=False 1563 break 1564 if binaryMsg: 1565 bv = BitVector(bitstring=msg) 1566 else: # nmeapayload 1567 bv = binary.ais6tobitvec(msg) 1568 1569 printFields(decode(bv) 1570 ,out=outfile 1571 ,format=options.outputType 1572 ,fieldList=options.fieldList 1573 ,dbType=options.dbType 1574 ) 1575