예제 #1
0
def decode(bv, validate=False):
    '''Unpack a sls_wind message.

    Fields in params:
      - time_month(uint): Time tag of measurement  month 1..12
      - time_day(uint): Time tag of measurement  day of the month 1..31
      - time_hour(uint): Time tag of measurement  UTC hours 0..23
      - time_min(uint): Time tag of measurement  minutes
      - stationid(aisstr6): Character identifier of the station
      - pos_longitude(decimal): Location of measurement  East West location
      - pos_latitude(decimal): Location of measurement  North South location
      - flow(uint): Water flow
      - reserved(uint): Reserved bits for future use (field automatically set to "0")
    @type bv: BitVector
    @param bv: Bits defining a message
    @param validate: Set to true to cause checking to occur.  Runs slower.  FIX: not implemented.
    @rtype: dict
    @return: params
    '''

    #Would be nice to check the bit count here..
    #if validate:
    #    assert (len(bv)==FIX: SOME NUMBER)
    r = {}
    r['time_month']=int(bv[0:4])
    r['time_day']=int(bv[4:9])
    r['time_hour']=int(bv[9:14])
    r['time_min']=int(bv[14:20])
    r['stationid']=aisstring.decode(bv[20:62])
    r['pos_longitude']=Decimal(binary.signedIntFromBV(bv[62:87]))/Decimal('60000')
    r['pos_latitude']=Decimal(binary.signedIntFromBV(bv[87:111]))/Decimal('60000')
    r['flow']=int(bv[111:121])
    r['reserved']=0
    return r
예제 #2
0
def decode(bv, validate=False):
    '''Unpack a gnss_correction message.

    Fields in params:
      - MessageID(uint): AIS message number.  Must be 17 (field automatically set to "17")
      - RepeatIndicator(uint): Indicated how many times a message has been repeated
      - UserID(uint): Base station identification number (MMSI)
      - Spare(uint): Reserved for definition by a regional authority. (field automatically set to "0")
      - x(decimal): East West location
      - y(decimal): North South location
      - Spare2(uint): Reserved for definition by a regional authority. (field automatically set to "0")
      - BinaryData(binary): GNSS Differential correction data
    @type bv: BitVector
    @param bv: Bits defining a message
    @param validate: Set to true to cause checking to occur.  Runs slower.  FIX: not implemented.
    @rtype: dict
    @return: params
    '''

    #Would be nice to check the bit count here..
    #if validate:
    #    assert (len(bv)==FIX: SOME NUMBER)
    r = {}
    r['MessageID'] = 17
    r['RepeatIndicator'] = int(bv[6:8])
    r['UserID'] = int(bv[8:38])
    r['Spare'] = 0
    r['x'] = Decimal(binary.signedIntFromBV(bv[40:58])) / Decimal('600')
    r['y'] = Decimal(binary.signedIntFromBV(bv[58:75])) / Decimal('600')
    r['Spare2'] = 0
    r['BinaryData'] = bv[80:]
    return r
예제 #3
0
def decode(bv, validate=False):
    '''Unpack a gnss_correction message.

    Fields in params:
      - MessageID(uint): AIS message number.  Must be 17 (field automatically set to "17")
      - RepeatIndicator(uint): Indicated how many times a message has been repeated
      - UserID(uint): Base station identification number (MMSI)
      - Spare(uint): Reserved for definition by a regional authority. (field automatically set to "0")
      - x(decimal): East West location
      - y(decimal): North South location
      - Spare2(uint): Reserved for definition by a regional authority. (field automatically set to "0")
      - BinaryData(binary): GNSS Differential correction data
    @type bv: BitVector
    @param bv: Bits defining a message
    @param validate: Set to true to cause checking to occur.  Runs slower.  FIX: not implemented.
    @rtype: dict
    @return: params
    '''

    #Would be nice to check the bit count here..
    #if validate:
    #    assert (len(bv)==FIX: SOME NUMBER)
    r = {}
    r['MessageID']=17
    r['RepeatIndicator']=int(bv[6:8])
    r['UserID']=int(bv[8:38])
    r['Spare']=0
    r['x']=Decimal(binary.signedIntFromBV(bv[40:58]))/Decimal('600')
    r['y']=Decimal(binary.signedIntFromBV(bv[58:75]))/Decimal('600')
    r['Spare2']=0
    r['BinaryData']=bv[80:]
    return r
예제 #4
0
def decode(bv, validate=False):
    '''Unpack a sls_weatherreport message.

    Fields in params:
      - time_month(uint): Time tag of measurement  month 1..12
      - time_day(uint): Time tag of measurement  day of the month 1..31
      - time_hour(uint): Time tag of measurement  UTC hours 0..23
      - time_min(uint): Time tag of measurement  minutes
      - stationid(aisstr6): Character identifier of the station
      - pos_longitude(decimal): Location of measurement  East West location
      - pos_latitude(decimal): Location of measurement  North South location
      - speed(udecimal): Average wind speed
      - gust(udecimal): Wind gust
      - direction(uint): Wind direction
      - atmpressure(udecimal): Atmospheric pressure
      - airtemp(decimal): Air temperature
      - dewpoint(decimal): Dew Point
      - visibility(udecimal): Visibility
      - watertemp(decimal): Water Temperature
      - reserved(uint): Reserved bits for future use (field automatically set to "0")
    @type bv: BitVector
    @param bv: Bits defining a message
    @param validate: Set to true to cause checking to occur.  Runs slower.  FIX: not implemented.
    @rtype: dict
    @return: params
    '''

    #Would be nice to check the bit count here..
    #if validate:
    #    assert (len(bv)==FIX: SOME NUMBER)
    r = {}
    r['time_month'] = int(bv[0:4])
    r['time_day'] = int(bv[4:9])
    r['time_hour'] = int(bv[9:14])
    r['time_min'] = int(bv[14:20])
    r['stationid'] = aisstring.decode(bv[20:62])
    r['pos_longitude'] = Decimal(binary.signedIntFromBV(
        bv[62:87])) / Decimal('60000')
    r['pos_latitude'] = Decimal(binary.signedIntFromBV(
        bv[87:111])) / Decimal('60000')
    r['speed'] = Decimal(int(bv[111:121])) / Decimal('10')
    r['gust'] = Decimal(int(bv[121:131])) / Decimal('10')
    r['direction'] = int(bv[131:140])
    r['atmpressure'] = Decimal(int(bv[140:154])) / Decimal('10')
    r['airtemp'] = Decimal(binary.signedIntFromBV(bv[154:164])) / Decimal('10')
    r['dewpoint'] = Decimal(binary.signedIntFromBV(
        bv[164:174])) / Decimal('10')
    r['visibility'] = Decimal(int(bv[174:182])) / Decimal('10')
    r['watertemp'] = Decimal(binary.signedIntFromBV(
        bv[182:192])) / Decimal('10')
    r['reserved'] = 0
    return r
예제 #5
0
def decode(bv, validate=False):
    '''Unpack a bsreport message.

    Fields in params:
      - MessageID(uint): AIS message number.  Must be 4 (field automatically set to "11")
      - RepeatIndicator(uint): Indicated how many times a message has been repeated
      - UserID(uint): Unique ship identification number (MMSI)
      - Time_year(uint): Current time stamp  year 1-9999
      - Time_month(uint): Current time stamp  month 1..12
      - Time_day(uint): Current time stamp  day of the month 1..31
      - Time_hour(uint): Current time stamp  UTC hours 0..23
      - Time_min(uint): Current time stamp  minutes
      - Time_sec(uint): Current time stamp  seconds
      - PositionAccuracy(uint): Accuracy of positioning fixes
      - Position_longitude(decimal): Location of base station  East West location
      - Position_latitude(decimal): Location of base station  North South location
      - fixtype(uint): Method used for positioning
      - Spare(uint): Not used.  Should be set to zero. (field automatically set to "0")
      - RAIM(bool): Receiver autonomous integrity monitoring flag
      - state_syncstate(uint): Communications State - SOTDMA  Sycronization state
      - state_slottimeout(uint): Communications State - SOTDMA  Frames remaining until a new slot is selected
      - state_slotoffset(uint): Communications State - SOTDMA  In what slot will the next transmission occur. BROKEN
    @type bv: BitVector
    @param bv: Bits defining a message
    @param validate: Set to true to cause checking to occur.  Runs slower.  FIX: not implemented.
    @rtype: dict
    @return: params
    '''

    #Would be nice to check the bit count here..
    #if validate:
    #    assert (len(bv)==FIX: SOME NUMBER)
    r = {}
    r['MessageID']=11
    r['RepeatIndicator']=int(bv[6:8])
    r['UserID']=int(bv[8:38])
    r['Time_year']=int(bv[38:52])
    r['Time_month']=int(bv[52:56])
    r['Time_day']=int(bv[56:61])
    r['Time_hour']=int(bv[61:66])
    r['Time_min']=int(bv[66:72])
    r['Time_sec']=int(bv[72:78])
    r['PositionAccuracy']=int(bv[78:79])
    r['Position_longitude']=Decimal(binary.signedIntFromBV(bv[79:107]))/Decimal('600000')
    r['Position_latitude']=Decimal(binary.signedIntFromBV(bv[107:134]))/Decimal('600000')
    r['fixtype']=int(bv[134:138])
    r['Spare']=0
    r['RAIM']=bool(int(bv[148:149]))
    r['state_syncstate']=int(bv[149:151])
    r['state_slottimeout']=int(bv[151:154])
    r['state_slotoffset']=int(bv[154:168])
    return r
예제 #6
0
def decode(bv, validate=False):
    '''Unpack a whalenotice message.

    Fields in params:
      - MessageID(uint): AIS message number.  Must be 8 (field automatically set to "8")
      - RepeatIndicator(uint): Indicated how many times a message has been repeated
      - UserID(uint): Unique ship identification number (MMSI)
      - Spare(uint): Reserved for definition by a regional authority. (field automatically set to "0")
      - dac(uint): Designated Area Code - 366 for the United States (field automatically set to "366")
      - fid(uint): Functional IDentifier - 63 for the Whale Notice (field automatically set to "63")
      - efid(uint): Extended Functional IDentifier.  1 for the Whale Notice (dac+fid+efid defines the exact message type) (field automatically set to "1")
      - month(uint): Time of most recent whale detection.  UTC month 1..12
      - day(uint): Time of most recent whale detection.  UTC day of the month 1..31
      - hour(uint): Time of most recent whale detection.  UTC hours 0..23
      - min(uint): Time of most recent whale detection.  UTC minutes
      - sec(uint): Time of most recent whale detection.  UTC seconds
      - stationid(aisstr6): Identifier of the station that detected the whale.  (e.g. which buoy)
      - longitude(decimal): Center of the detection zone.  East West location
      - latitude(decimal): Center of the detection zone.  North South location
      - timetoexpire(uint): Seconds from the detection time until the notice expires
      - radius(uint): Distance from center of detection zone (lat/lon above)
    @type bv: BitVector
    @param bv: Bits defining a message
    @param validate: Set to true to cause checking to occur.  Runs slower.  FIX: not implemented.
    @rtype: dict
    @return: params
    '''

    #Would be nice to check the bit count here..
    #if validate:
    #    assert (len(bv)==FIX: SOME NUMBER)
    r = {}
    r['MessageID'] = 8
    r['RepeatIndicator'] = int(bv[6:8])
    r['UserID'] = int(bv[8:38])
    r['Spare'] = 0
    r['dac'] = 366
    r['fid'] = 63
    r['efid'] = 1
    r['month'] = int(bv[68:72])
    r['day'] = int(bv[72:77])
    r['hour'] = int(bv[77:82])
    r['min'] = int(bv[82:88])
    r['sec'] = int(bv[88:94])
    r['stationid'] = aisstring.decode(bv[94:136])
    r['longitude'] = Decimal(binary.signedIntFromBV(
        bv[136:164])) / Decimal('600000')
    r['latitude'] = Decimal(binary.signedIntFromBV(
        bv[164:191])) / Decimal('600000')
    r['timetoexpire'] = int(bv[191:207])
    r['radius'] = int(bv[207:223])
    return r
예제 #7
0
def filter_file(infile, outfile, polygonWKT, verbose=False):
    '''
    For messages 1,2, and 3, see if the message is within the bounding box and send it to outfile if it is.

    Polygon should look something like this... 'POLYGON ((-1.0 50.5, -0.5 51.2, 0.3 50.9, -1 50.5))'

    param polygon: bounding region for the query
    type polygon: WKT polygon string
    '''

    poly = Geometry.fromWKT(polygonWKT)
    bbox = poly.envelope()
    minx = bbox.minx  # for speed, throw out points as soon as possible
    maxx = bbox.maxx
    miny = bbox.miny
    maxy = bbox.maxy

    if verbose:
        print 'minLon maxLon minLat maxLat filename'
        print minx, maxx, miny, maxy

    count = 0
    linenum = 0
    for line in infile:
        linenum += 1
        if linenum % 1000 == 0:
            sys.stderr.write('line ' + str(linenum) + ' -- count=' +
                             str(count) + '\n')
        # Trick: Only handle the first 19 characters since that contains the lon/lat
        txt = line.split(',')[5][:25]
        #print txt
        bv = binary.ais6tobitvec(txt)  #line[5][:19]

        # Try to throw out points as soon as possible.  Use float rather than decimal.  faster??  Maybe not
        #lon = ais_msg_1.decodelongitude(bv)
        lon = binary.signedIntFromBV(bv[61:89]) / 600000.0
        if lon < minx or lon > maxx: continue
        #print 'close1:',lon
        #lat = ais_msg_1.decodelatitude(bv)
        lat = binary.signedIntFromBV(bv[89:116]) / 600000.0
        if lat < miny or lat > maxy: continue

        #print 'close2: POINT ('+str(lon)+' '+str(lat)+')'

        point = Geometry.fromWKT('POINT (' + str(lon) + ' ' + str(lat) + ')')
        inside = point.within(poly)
        if 1 == inside:
            outfile.write(line)
            count += 1

    return count
예제 #8
0
def decode(bv, validate=False):
    '''Unpack a ChanMngmt message.

    Fields in params:
      - MessageID(uint): AIS message number.  Must be 22 (field automatically set to "22")
      - RepeatIndicator(uint): Indicated how many times a message has been repeated
      - UserID(uint): Unique ship identification number (MMSI)
      - Spare(uint): Not used.  Should be set to zero. (field automatically set to "0")
      - ChanA(uint): Channel number from ITU-R M.1084 Annex 4
      - ChanB(uint): Channel number from ITU-R M.1084 Annex 4
      - TxRxMode(uint): FIX: find the description
      - power(uint): FIX: put in a description
      - corner1_lon(decimal): north-east corner of area for assignment  longitude of corner
      - corner1_lat(decimal): north-east corner of area for assignment  latitude of corner
      - corner2_lon(decimal): south-west corner of area for assignment  longitude of corner
      - corner2_lat(decimal): south-west corner of area for assignment  latitude of corner
      - IndicatorType(uint): FIX: put in a description
      - ChanABandwidth(uint): FIX: put in a description
      - ChanBBandwidth(uint): FIX: put in a description
      - TransZoneSize(uint): FIX: put in a description
      - Spare2(uint): Not used.  Should be set to zero. (field automatically set to "0")
    @type bv: BitVector
    @param bv: Bits defining a message
    @param validate: Set to true to cause checking to occur.  Runs slower.  FIX: not implemented.
    @rtype: dict
    @return: params
    '''

    #Would be nice to check the bit count here..
    #if validate:
    #    assert (len(bv)==FIX: SOME NUMBER)
    r = {}
    r['MessageID']=22
    r['RepeatIndicator']=int(bv[6:8])
    r['UserID']=int(bv[8:38])
    r['Spare']=0
    r['ChanA']=int(bv[40:52])
    r['ChanB']=int(bv[52:64])
    r['TxRxMode']=int(bv[64:68])
    r['power']=int(bv[68:69])
    r['corner1_lon']=Decimal(binary.signedIntFromBV(bv[69:87]))/Decimal('600')
    r['corner1_lat']=Decimal(binary.signedIntFromBV(bv[87:104]))/Decimal('600')
    r['corner2_lon']=Decimal(binary.signedIntFromBV(bv[104:122]))/Decimal('600')
    r['corner2_lat']=Decimal(binary.signedIntFromBV(bv[122:139]))/Decimal('600')
    r['IndicatorType']=int(bv[139:140])
    r['ChanABandwidth']=int(bv[140:141])
    r['ChanBBandwidth']=int(bv[141:142])
    r['TransZoneSize']=int(bv[142:145])
    r['Spare2']=0
    return r
예제 #9
0
def decode(bv, validate=False):
    '''Unpack a whalenotice message.

    Fields in params:
      - MessageID(uint): AIS message number.  Must be 8 (field automatically set to "8")
      - RepeatIndicator(uint): Indicated how many times a message has been repeated
      - UserID(uint): Unique ship identification number (MMSI)
      - Spare(uint): Reserved for definition by a regional authority. (field automatically set to "0")
      - dac(uint): Designated Area Code - 366 for the United States (field automatically set to "366")
      - fid(uint): Functional IDentifier - 63 for the Whale Notice (field automatically set to "63")
      - efid(uint): Extended Functional IDentifier.  1 for the Whale Notice (dac+fid+efid defines the exact message type) (field automatically set to "1")
      - month(uint): Time of most recent whale detection.  UTC month 1..12
      - day(uint): Time of most recent whale detection.  UTC day of the month 1..31
      - hour(uint): Time of most recent whale detection.  UTC hours 0..23
      - min(uint): Time of most recent whale detection.  UTC minutes
      - sec(uint): Time of most recent whale detection.  UTC seconds
      - stationid(aisstr6): Identifier of the station that detected the whale.  (e.g. which buoy)
      - longitude(decimal): Center of the detection zone.  East West location
      - latitude(decimal): Center of the detection zone.  North South location
      - timetoexpire(uint): Seconds from the detection time until the notice expires
      - radius(uint): Distance from center of detection zone (lat/lon above)
    @type bv: BitVector
    @param bv: Bits defining a message
    @param validate: Set to true to cause checking to occur.  Runs slower.  FIX: not implemented.
    @rtype: dict
    @return: params
    '''

    #Would be nice to check the bit count here..
    #if validate:
    #    assert (len(bv)==FIX: SOME NUMBER)
    r = {}
    r['MessageID']=8
    r['RepeatIndicator']=int(bv[6:8])
    r['UserID']=int(bv[8:38])
    r['Spare']=0
    r['dac']=366
    r['fid']=63
    r['efid']=1
    r['month']=int(bv[68:72])
    r['day']=int(bv[72:77])
    r['hour']=int(bv[77:82])
    r['min']=int(bv[82:88])
    r['sec']=int(bv[88:94])
    r['stationid']=aisstring.decode(bv[94:136])
    r['longitude']=Decimal(binary.signedIntFromBV(bv[136:164]))/Decimal('600000')
    r['latitude']=Decimal(binary.signedIntFromBV(bv[164:191]))/Decimal('600000')
    r['timetoexpire']=int(bv[191:207])
    r['radius']=int(bv[207:223])
    return r
예제 #10
0
def decode(bv, validate=False):
    """Unpack a bsreport message.

    Fields in params:
      - MessageID(uint): AIS message number.  Must be 4 (field automatically set to "4")
      - RepeatIndicator(uint): Indicated how many times a message has been repeated
      - UserID(uint): Unique ship identification number (MMSI)
      - Time_year(uint): Current time stamp  year 1-9999
      - Time_month(uint): Current time stamp  month 1..12
      - Time_day(uint): Current time stamp  day of the month 1..31
      - Time_hour(uint): Current time stamp  UTC hours 0..23
      - Time_min(uint): Current time stamp  minutes
      - Time_sec(uint): Current time stamp  seconds
      - PositionAccuracy(uint): Accuracy of positioning fixes
      - Position_longitude(decimal): Location of base station  East West location
      - Position_latitude(decimal): Location of base station  North South location
      - fixtype(uint): Method used for positioning
      - Spare(uint): Not used.  Should be set to zero. (field automatically set to "0")
      - RAIM(bool): Receiver autonomous integrity monitoring flag
      - state_syncstate(uint): Communications State - SOTDMA  Sycronization state
      - state_slottimeout(uint): Communications State - SOTDMA  Frames remaining until a new slot is selected
      - state_slotoffset(uint): Communications State - SOTDMA  In what slot will the next transmission occur. BROKEN
    @type bv: BitVector
    @param bv: Bits defining a message
    @param validate: Set to true to cause checking to occur.  Runs slower.  FIX: not implemented.
    @rtype: dict
    @return: params
    """

    r = {}
    r['MessageID'] = 4
    r['RepeatIndicator'] = int(bv[6:8])
    r['UserID'] = int(bv[8:38])
    r['Time_year'] = int(bv[38:52])
    r['Time_month'] = int(bv[52:56])
    r['Time_day'] = int(bv[56:61])
    r['Time_hour'] = int(bv[61:66])
    r['Time_min'] = int(bv[66:72])
    r['Time_sec'] = int(bv[72:78])
    r['PositionAccuracy'] = int(bv[78:79])
    r['Position_longitude'] = Decimal(binary.signedIntFromBV(
        bv[79:107])) / Decimal('600000')
    r['Position_latitude'] = Decimal(binary.signedIntFromBV(
        bv[107:134])) / Decimal('600000')
    r['fixtype'] = int(bv[134:138])
    r['Spare'] = 0
    r['RAIM'] = bool(int(bv[148:149]))
    r.update(commstate.sotdma_parse_bits(bv[-19:]))
    return r
예제 #11
0
def decode(bv, validate=False):
    '''Unpack a sls_weatherreport message.

    Fields in params:
      - time_month(uint): Time tag of measurement  month 1..12
      - time_day(uint): Time tag of measurement  day of the month 1..31
      - time_hour(uint): Time tag of measurement  UTC hours 0..23
      - time_min(uint): Time tag of measurement  minutes
      - stationid(aisstr6): Character identifier of the station
      - pos_longitude(decimal): Location of measurement  East West location
      - pos_latitude(decimal): Location of measurement  North South location
      - speed(udecimal): Average wind speed
      - gust(udecimal): Wind gust
      - direction(uint): Wind direction
      - atmpressure(udecimal): Atmospheric pressure
      - airtemp(decimal): Air temperature
      - dewpoint(decimal): Dew Point
      - visibility(udecimal): Visibility
      - watertemp(decimal): Water Temperature
      - reserved(uint): Reserved bits for future use (field automatically set to "0")
    @type bv: BitVector
    @param bv: Bits defining a message
    @param validate: Set to true to cause checking to occur.  Runs slower.  FIX: not implemented.
    @rtype: dict
    @return: params
    '''

    #Would be nice to check the bit count here..
    #if validate:
    #    assert (len(bv)==FIX: SOME NUMBER)
    r = {}
    r['time_month']=int(bv[0:4])
    r['time_day']=int(bv[4:9])
    r['time_hour']=int(bv[9:14])
    r['time_min']=int(bv[14:20])
    r['stationid']=aisstring.decode(bv[20:62])
    r['pos_longitude']=Decimal(binary.signedIntFromBV(bv[62:87]))/Decimal('60000')
    r['pos_latitude']=Decimal(binary.signedIntFromBV(bv[87:111]))/Decimal('60000')
    r['speed']=Decimal(int(bv[111:121]))/Decimal('10')
    r['gust']=Decimal(int(bv[121:131]))/Decimal('10')
    r['direction']=int(bv[131:140])
    r['atmpressure']=Decimal(int(bv[140:154]))/Decimal('10')
    r['airtemp']=Decimal(binary.signedIntFromBV(bv[154:164]))/Decimal('10')
    r['dewpoint']=Decimal(binary.signedIntFromBV(bv[164:174]))/Decimal('10')
    r['visibility']=Decimal(int(bv[174:182]))/Decimal('10')
    r['watertemp']=Decimal(binary.signedIntFromBV(bv[182:192]))/Decimal('10')
    r['reserved']=0
    return r
예제 #12
0
def decode(bv, validate=False):
    '''Unpack a whalenotice message.

    Fields in params:
      - MessageID(uint): AIS message number.  Must be 8 (field automatically set to "8")
      - RepeatIndicator(uint): Indicated how many times a message has been repeated
      - UserID(uint): Unique ship identification number (MMSI)
      - Spare(uint): Reserved for definition by a regional authority. (field automatically set to "0")
      - dac(uint): Designated Area Code - 366 for the United States (field automatically set to "366")
      - fid(uint): Functional IDentifier - 63 for the Whale Notice (field automatically set to "63")
      - day(uint): Time of most recent whale detection.  UTC day of the month 1..31
      - hour(uint): Time of most recent whale detection.  UTC hours 0..23
      - min(uint): Time of most recent whale detection.  UTC minutes
      - stationid(uint): Identifier of the station that recorded the whale.  Usually a number.
      - longitude(decimal): Center of the detection zone.  East West location
      - latitude(decimal): Center of the detection zone.  North South location
      - timetoexpire(uint): Minutes from the detection time until the notice expires
      - radius(uint): Distance from center of detection zone (lat/lon above)
    @type bv: BitVector
    @param bv: Bits defining a message
    @param validate: Set to true to cause checking to occur.  Runs slower.  FIX: not implemented.
    @rtype: dict
    @return: params
    '''

    #Would be nice to check the bit count here..
    #if validate:
    #    assert (len(bv)==FIX: SOME NUMBER)
    r = {}
    r['MessageID'] = 8
    r['RepeatIndicator'] = int(bv[6:8])
    r['UserID'] = int(bv[8:38])
    r['Spare'] = 0
    r['dac'] = 366
    r['fid'] = 63
    r['day'] = int(bv[56:61])
    r['hour'] = int(bv[61:66])
    r['min'] = int(bv[66:72])
    r['stationid'] = int(bv[72:80])
    r['longitude'] = Decimal(binary.signedIntFromBV(
        bv[80:108])) / Decimal('600000')
    r['latitude'] = Decimal(binary.signedIntFromBV(
        bv[108:135])) / Decimal('600000')
    r['timetoexpire'] = int(bv[135:151])
    r['radius'] = int(bv[151:167])
    return r
예제 #13
0
def decode(bv, validate=False):
    '''Unpack a timed_circular_notice message.

    Fields in params:
      - MessageID(uint): AIS message number.  Must be 8 (field automatically set to "8")
      - RepeatIndicator(uint): Indicated how many times a message has been repeated
      - UserID(uint): Unique ship identification number (MMSI)
      - Spare(uint): Reserved for definition by a regional authority. (field automatically set to "0")
      - dac(uint): Designated Area Code - 366 for the United States (field automatically set to "366")
      - fid(uint): Functional IDentifier - 63 (field automatically set to "63")
      - month(uint): Start time of most recent notice  UTC month
      - day(uint): Start time of most recent notice  UTC day of the month 1..31
      - hour(uint): Start time of most recent notice  UTC hours 0..23
      - min(uint): Start time of most recent notice  UTC minutes
      - longitude(decimal): Center of the area/zone  East West location
      - latitude(decimal): Center of the area/zone  North South location
      - timetoexpire(uint): Minutes from the start time until the notice expires.  Max is aprox 23 days
      - radius(udecimal): Distance from center of detection zone (lat/lon above).  Distance in increments of 10 meters
      - areatype(uint): What does this circular area represent
    @type bv: BitVector
    @param bv: Bits defining a message
    @param validate: Set to true to cause checking to occur.  Runs slower.  FIX: not implemented.
    @rtype: dict
    @return: params
    '''

    #Would be nice to check the bit count here..
    #if validate:
    #    assert (len(bv)==FIX: SOME NUMBER)
    r = {}
    r['MessageID']=8
    r['RepeatIndicator']=int(bv[6:8])
    r['UserID']=int(bv[8:38])
    r['Spare']=0
    r['dac']=366
    r['fid']=63
    r['month']=int(bv[56:60])
    r['day']=int(bv[60:65])
    r['hour']=int(bv[65:70])
    r['min']=int(bv[70:76])
    r['longitude']=Decimal(binary.signedIntFromBV(bv[76:104]))/Decimal('600000')
    r['latitude']=Decimal(binary.signedIntFromBV(bv[104:131]))/Decimal('600000')
    r['timetoexpire']=int(bv[131:146])
    r['radius']=Decimal(int(bv[146:160]))/Decimal('0.1')
    r['areatype']=int(bv[160:168])
    return r
예제 #14
0
def decode(bv, validate=False):
    '''Unpack a whalenotice message.

    Fields in params:
      - MessageID(uint): AIS message number.  Must be 8 (field automatically set to "8")
      - RepeatIndicator(uint): Indicated how many times a message has been repeated
      - UserID(uint): Unique ship identification number (MMSI)
      - Spare(uint): Reserved for definition by a regional authority. (field automatically set to "0")
      - dac(uint): Designated Area Code - 366 for the United States (field automatically set to "366")
      - fid(uint): Functional IDentifier - 63 for the Whale Notice (field automatically set to "63")
      - day(uint): Time of most recent whale detection.  UTC day of the month 1..31
      - hour(uint): Time of most recent whale detection.  UTC hours 0..23
      - min(uint): Time of most recent whale detection.  UTC minutes
      - stationid(uint): Identifier of the station that recorded the whale.  Usually a number.
      - longitude(decimal): Center of the detection zone.  East West location
      - latitude(decimal): Center of the detection zone.  North South location
      - timetoexpire(uint): Minutes from the detection time until the notice expires
      - radius(uint): Distance from center of detection zone (lat/lon above)
    @type bv: BitVector
    @param bv: Bits defining a message
    @param validate: Set to true to cause checking to occur.  Runs slower.  FIX: not implemented.
    @rtype: dict
    @return: params
    '''

    #Would be nice to check the bit count here..
    #if validate:
    #    assert (len(bv)==FIX: SOME NUMBER)
    r = {}
    r['MessageID']=8
    r['RepeatIndicator']=int(bv[6:8])
    r['UserID']=int(bv[8:38])
    r['Spare']=0
    r['dac']=366
    r['fid']=63
    r['day']=int(bv[56:61])
    r['hour']=int(bv[61:66])
    r['min']=int(bv[66:72])
    r['stationid']=int(bv[72:80])
    r['longitude']=Decimal(binary.signedIntFromBV(bv[80:108]))/Decimal('600000')
    r['latitude']=Decimal(binary.signedIntFromBV(bv[108:135]))/Decimal('600000')
    r['timetoexpire']=int(bv[135:151])
    r['radius']=int(bv[151:167])
    return r
예제 #15
0
def decode(bv, validate=False):
    r = {}
    r['MessageID']=int(bv[:6])
    r['RepeatIndicator']=int(bv[6:8])
    r['UserID']=int(bv[8:38])
    r['NavigationStatus']=int(bv[38:42])
    r['ROT']=binary.signedIntFromBV(bv[42:50])
    r['SOG']=Decimal(int(bv[50:60]))/Decimal('10')
    r['PositionAccuracy']=int(bv[60:61])
    r['longitude']=Decimal(binary.signedIntFromBV(bv[61:89]))/Decimal('600000')
    r['latitude']=Decimal(binary.signedIntFromBV(bv[89:116]))/Decimal('600000')
    r['COG']=Decimal(int(bv[116:128]))/Decimal('10')
    r['TrueHeading']=int(bv[128:137])
    r['TimeStamp']=int(bv[137:143])
    r['RegionalReserved']=0
    r['Spare']=0
    r['RAIM']=bool(int(bv[148:149]))
    r.update(commstate.sotdma_parse_bits(bv[-19:]))
    return r
예제 #16
0
def decode(bv, validate=False):
    r = {}
    r['MessageID'] = int(bv[:6])
    r['RepeatIndicator'] = int(bv[6:8])
    r['UserID'] = int(bv[8:38])
    r['NavigationStatus'] = int(bv[38:42])
    r['ROT'] = binary.signedIntFromBV(bv[42:50])
    r['SOG'] = Decimal(int(bv[50:60])) / Decimal('10')
    r['PositionAccuracy'] = int(bv[60:61])
    r['longitude'] = Decimal(binary.signedIntFromBV(
        bv[61:89])) / Decimal('600000')
    r['latitude'] = Decimal(binary.signedIntFromBV(
        bv[89:116])) / Decimal('600000')
    r['COG'] = Decimal(int(bv[116:128])) / Decimal('10')
    r['TrueHeading'] = int(bv[128:137])
    r['TimeStamp'] = int(bv[137:143])
    r['RegionalReserved'] = 0
    r['Spare'] = 0
    r['RAIM'] = bool(int(bv[148:149]))
    r.update(commstate.sotdma_parse_bits(bv[-19:]))
    return r
예제 #17
0
def decode(bv, validate=False):
    '''Unpack a alltypesmsg message.

    Fields in params:
      - dac(uint): Designated Area Code (field automatically set to "366")
      - reqDecimal(decimal): required decimal value... FIX: scale or no? (field automatically set to "122")
      - unavail_uint(uint): Unavailable unsigned integer
      - anUInt(uint): NO unavailable unsigned integer
      - anInt(int): NO unavailable signed integer
      - aBool(bool): Simple bool
      - aStr(aisstr6): An ais string of 5 characters
      - anUDecimal(udecimal): An unsigned decimal.  Allow smaller numbers
      - aDecimal(decimal): A decimal
      - aFloat(float): An IEEE floating point number
    @type bv: BitVector
    @param bv: Bits defining a message
    @param validate: Set to true to cause checking to occur.  Runs slower.  FIX: not implemented.
    @rtype: dict
    @return: params
    '''

    #Would be nice to check the bit count here..
    #if validate:
    #    assert (len(bv)==FIX: SOME NUMBER)
    r = {}
    r['dac']=366
    r['reqDecimal']=122/Decimal('1')
    r['unavail_uint']=int(bv[24:26])
    r['anUInt']=int(bv[26:28])
    r['anInt']=binary.signedIntFromBV(bv[28:31])
    r['aBool']=bool(int(bv[31:32]))
    r['aStr']=aisstring.decode(bv[32:62])
    r['anUDecimal']=Decimal(int(bv[62:78]))/Decimal('10')
    r['aDecimal']=Decimal(binary.signedIntFromBV(bv[78:94]))/Decimal('10')
    r['aFloat']=binary.bitvec2float(bv[94:126])
    return r
예제 #18
0
def decode(bv, validate=False):
    '''Unpack a alltypesmsg message.

    Fields in params:
      - dac(uint): Designated Area Code (field automatically set to "366")
      - reqDecimal(decimal): required decimal value... FIX: scale or no? (field automatically set to "122")
      - unavail_uint(uint): Unavailable unsigned integer
      - anUInt(uint): NO unavailable unsigned integer
      - anInt(int): NO unavailable signed integer
      - aBool(bool): Simple bool
      - aStr(aisstr6): An ais string of 5 characters
      - anUDecimal(udecimal): An unsigned decimal.  Allow smaller numbers
      - aDecimal(decimal): A decimal
      - aFloat(float): An IEEE floating point number
    @type bv: BitVector
    @param bv: Bits defining a message
    @param validate: Set to true to cause checking to occur.  Runs slower.  FIX: not implemented.
    @rtype: dict
    @return: params
    '''

    #Would be nice to check the bit count here..
    #if validate:
    #    assert (len(bv)==FIX: SOME NUMBER)
    r = {}
    r['dac'] = 366
    r['reqDecimal'] = 122 / Decimal('1')
    r['unavail_uint'] = int(bv[24:26])
    r['anUInt'] = int(bv[26:28])
    r['anInt'] = binary.signedIntFromBV(bv[28:31])
    r['aBool'] = bool(int(bv[31:32]))
    r['aStr'] = aisstring.decode(bv[32:62])
    r['anUDecimal'] = Decimal(int(bv[62:78])) / Decimal('10')
    r['aDecimal'] = Decimal(binary.signedIntFromBV(bv[78:94])) / Decimal('10')
    r['aFloat'] = binary.bitvec2float(bv[94:126])
    return r
예제 #19
0
def decode(bv, validate=False):
    """Unpack a waterlevel message.

    Fields in params:
      - MessageID(uint): AIS message number.  Must be 8 (field automatically set to "8")
      - RepeatIndicator(uint): Indicated how many times a message has been repeated
      - UserID(uint): Unique ship identification number (MMSI)
      - Spare(uint): Reserved for definition by a regional authority. (field automatically set to "0")
      - dac(uint): Designated Area Code (field automatically set to "366")
      - fid(uint): Functional Identifier (field automatically set to "63")
      - month(uint): Time the measurement represents  month 1..12
      - day(uint): Time the measurement represents  day of the month 1..31
      - hour(uint): Time the measurement represents  UTC hours 0..23
      - min(uint): Time the measurement represents  minutes
      - stationid(aisstr6): Character identifier of the station.  Usually a number.
      - waterlevel(int): Water level in centimeters
      - datum(uint): What reference datum applies to the value
      - sigma(uint): Standard deviation of 1 second samples used to compute the water level height.  FIX: is this the correct description of sigma?
      - source(uint): How the water level was derived
    @type bv: BitVector
    @param bv: Bits defining a message
    @param validate: Set to true to cause checking to occur.  Runs slower.  FIX: not implemented.
    @rtype: dict
    @return: params
    """

    # Would be nice to check the bit count here..
    # if validate:
    #    assert (len(bv)==FIX: SOME NUMBER)
    r = {}
    r["MessageID"] = 8
    r["RepeatIndicator"] = int(bv[6:8])
    r["UserID"] = int(bv[8:38])
    r["Spare"] = 0
    r["dac"] = 366
    r["fid"] = 63
    r["month"] = int(bv[56:60])
    r["day"] = int(bv[60:65])
    r["hour"] = int(bv[65:70])
    r["min"] = int(bv[70:76])
    r["stationid"] = aisstring.decode(bv[76:118])
    r["waterlevel"] = binary.signedIntFromBV(bv[118:134])
    r["datum"] = int(bv[134:139])
    r["sigma"] = int(bv[139:146])
    r["source"] = int(bv[146:149])
    return r
예제 #20
0
def decode(bv, validate=False):
    '''Unpack a waterlevel message.

    Fields in params:
      - MessageID(uint): AIS message number.  Must be 8 (field automatically set to "8")
      - RepeatIndicator(uint): Indicated how many times a message has been repeated
      - UserID(uint): Unique ship identification number (MMSI)
      - Spare(uint): Reserved for definition by a regional authority. (field automatically set to "0")
      - dac(uint): Designated Area Code (field automatically set to "366")
      - fid(uint): Functional Identifier (field automatically set to "63")
      - month(uint): Time the measurement represents  month 1..12
      - day(uint): Time the measurement represents  day of the month 1..31
      - hour(uint): Time the measurement represents  UTC hours 0..23
      - min(uint): Time the measurement represents  minutes
      - stationid(aisstr6): Character identifier of the station.  Usually a number.
      - waterlevel(int): Water level in centimeters
      - datum(uint): What reference datum applies to the value
      - sigma(uint): Standard deviation of 1 second samples used to compute the water level height.  FIX: is this the correct description of sigma?
      - source(uint): How the water level was derived
    @type bv: BitVector
    @param bv: Bits defining a message
    @param validate: Set to true to cause checking to occur.  Runs slower.  FIX: not implemented.
    @rtype: dict
    @return: params
    '''

    #Would be nice to check the bit count here..
    #if validate:
    #    assert (len(bv)==FIX: SOME NUMBER)
    r = {}
    r['MessageID'] = 8
    r['RepeatIndicator'] = int(bv[6:8])
    r['UserID'] = int(bv[8:38])
    r['Spare'] = 0
    r['dac'] = 366
    r['fid'] = 63
    r['month'] = int(bv[56:60])
    r['day'] = int(bv[60:65])
    r['hour'] = int(bv[65:70])
    r['min'] = int(bv[70:76])
    r['stationid'] = aisstring.decode(bv[76:118])
    r['waterlevel'] = binary.signedIntFromBV(bv[118:134])
    r['datum'] = int(bv[134:139])
    r['sigma'] = int(bv[139:146])
    r['source'] = int(bv[146:149])
    return r
예제 #21
0
def decodewatertemp(bv, validate=False):
    return Decimal(binary.signedIntFromBV(bv[182:192])) / Decimal('10')
예제 #22
0
def decodePosition_longitude(bv, validate=False):
    return Decimal(binary.signedIntFromBV(bv[79:107]))/Decimal('600000')
예제 #23
0
def decodepos_latitude(bv, validate=False):
    return Decimal(binary.signedIntFromBV(bv[87:111]))/Decimal('60000')
예제 #24
0
def decodeanInt(bv, validate=False):
    return binary.signedIntFromBV(bv[28:31])
예제 #25
0
def decodedewpoint(bv, validate=False):
    return Decimal(binary.signedIntFromBV(bv[164:174]))/Decimal('10')
예제 #26
0
def decodelatitude(bv, validate=False):
    return Decimal(binary.signedIntFromBV(bv[104:131]))/Decimal('600000')
예제 #27
0
def int_dec(bv):
    '''@rtype: int'''
    return int(binary.signedIntFromBV(bv))
예제 #28
0
def decodecorner2_lat(bv, validate=False):
    return Decimal(binary.signedIntFromBV(bv[122:139]))/Decimal('600')
예제 #29
0
def float_dec(bv):
    '''@rtype: float'''
    return float(binary.signedIntFromBV(bv))
예제 #30
0
def decodecorner1_lat(bv, validate=False):
    return Decimal(binary.signedIntFromBV(bv[87:104]))/Decimal('600')
예제 #31
0
def decodecorner2_lon(bv, validate=False):
    return Decimal(binary.signedIntFromBV(bv[104:122]))/Decimal('600')
예제 #32
0
def decodey(bv, validate=False):
    return Decimal(binary.signedIntFromBV(bv[58:75])) / Decimal('600')
예제 #33
0
def decodeaDecimal(bv, validate=False):
    return Decimal(binary.signedIntFromBV(bv[78:94]))/Decimal('10')
예제 #34
0
def decodePosition_latitude(bv, validate=False):
    return Decimal(binary.signedIntFromBV(bv[107:134]))/Decimal('600000')
예제 #35
0
def float_dec(bv):
    '''@rtype: float'''
    return float(binary.signedIntFromBV(bv))
예제 #36
0
def int_dec(bv):
    '''@rtype: int'''
    return int(binary.signedIntFromBV(bv))
예제 #37
0
def decodelongitude(bv, validate=False):
    return Decimal(binary.signedIntFromBV(bv[76:104]))/Decimal('600000')
예제 #38
0
def decimal_dec(bv):
    '''@rtype: Decimal'''
    return Decimal(binary.signedIntFromBV(bv))
예제 #39
0
def decimal_dec(bv):
    '''@rtype: Decimal'''
    return Decimal(binary.signedIntFromBV(bv))
예제 #40
0
def decodewaterlevel(bv, validate=False):
    return binary.signedIntFromBV(bv[112:128])
예제 #41
0
def decodewatertemp(bv, validate=False):
    return Decimal(binary.signedIntFromBV(bv[182:192]))/Decimal('10')
예제 #42
0
def decodex(bv, validate=False):
    return Decimal(binary.signedIntFromBV(bv[40:58])) / Decimal('600')
예제 #43
0
def decodeaDecimal(bv, validate=False):
    return Decimal(binary.signedIntFromBV(bv[78:94])) / Decimal('10')
예제 #44
0
def decodepos_longitude(bv, validate=False):
    return Decimal(binary.signedIntFromBV(bv[62:87]))/Decimal('60000')
예제 #45
0
def decodeanInt(bv, validate=False):
    return binary.signedIntFromBV(bv[28:31])
예제 #46
0
def build_dist_database(database_filename, log_files, verbose=False):

    cx = sqlite3.connect(database_filename)

    print 'WARNING: not saving the station name'
    cx.execute('''
    CREATE TABLE IF NOT EXISTS distance (
       -- Save space, no key
       -- ts INTEGER, -- Save more space
       julian_day INTEGER,
       -- x REAL,
       -- y REAL,
       dist_km REAL
       --,
       --station VARCHAR(15)
       );
    ''')

    cu = cx.cursor()

    counts = {'nogps': 0}

    for filename in log_files:
        if verbose:
            print 'file:',filename
            sys.stdout.flush()
        for line_num, line in enumerate(file(filename)):
            if 'AIVDM,1,1' not in line: continue
            match = uscg_ais_nmea_regex.search(line).groupdict()
            message_id = match['body'][0] # First letter is the message type
            if message_id not in ('1','2','3'): continue

            if len(match['body']) != 28: # 6 bits per character
                raise AisErrorBadNumBits('expected 168, got %d' % len(match['body']) / 6)

            bits = binary.ais6tobitvec(match['body'][:20]) # Don't need any of the other bits, so do not waste time

            x = binary.signedIntFromBV(bits[61:89]) / 600000.
            y = binary.signedIntFromBV(bits[89:116]) / 600000.

            if x > 180 or y > 90:
                counts['nogps'] += 1
                continue

            station = match['station']

            julian_day = int(datetime.datetime.utcfromtimestamp(int(match['timeStamp'])).strftime('%j'))

            d_km =  dist_utm_km( (x,y), station_locations[station] )
            #cu.execute('INSERT INTO distance VALUES (:julian_day, :x, :y, :dist_km, :station)',
                       #{'julian_day': julian_day, 'x':x, 'y':y, 'dist_km': d_km, 'station':station} )
            #cu.execute('INSERT INTO distance VALUES (:julian_day, :x, :y, :dist_km)',
            #           {'julian_day': julian_day, 'x':x, 'y':y, 'dist_km': d_km, } )
            cu.execute('INSERT INTO distance VALUES (:julian_day, :dist_km)',
                       {'julian_day': julian_day, 'dist_km': d_km, } )
            if line_num % 10000 == 9999:
                cx.commit()


        cx.commit()

    if False:
        print 'Creating indexes'
        try:
            cx.execute('CREATE INDEX idx_dist_day ON distance(julian_day);')
            cx.execute('CREATE INDEX idx_dist_dist ON distance(dist_km);')
            #cx.execute('CREATE INDEX idx_dist_station ON distance(station);')
            cx.commit()
        except sqlite3.OperationalError:
            print 'Appears indexes were already created'

    return cx, counts
예제 #47
0
def build_dist_database(database_filename, log_files, verbose=False):

    cx = sqlite3.connect(database_filename)

    print 'WARNING: not saving the station name'
    cx.execute('''
    CREATE TABLE IF NOT EXISTS distance (
       -- Save space, no key
       -- ts INTEGER, -- Save more space
       julian_day INTEGER,
       -- x REAL,
       -- y REAL,
       dist_km REAL
       --,
       --station VARCHAR(15)
       );
    ''')

    cu = cx.cursor()

    counts = {'nogps': 0}

    for filename in log_files:
        if verbose:
            print 'file:', filename
            sys.stdout.flush()
        for line_num, line in enumerate(file(filename)):
            if 'AIVDM,1,1' not in line: continue
            match = uscg_ais_nmea_regex.search(line).groupdict()
            message_id = match['body'][0]  # First letter is the message type
            if message_id not in ('1', '2', '3'): continue

            if len(match['body']) != 28:  # 6 bits per character
                raise AisErrorBadNumBits('expected 168, got %d' %
                                         len(match['body']) / 6)

            bits = binary.ais6tobitvec(
                match['body'][:20]
            )  # Don't need any of the other bits, so do not waste time

            x = binary.signedIntFromBV(bits[61:89]) / 600000.
            y = binary.signedIntFromBV(bits[89:116]) / 600000.

            if x > 180 or y > 90:
                counts['nogps'] += 1
                continue

            station = match['station']

            julian_day = int(
                datetime.datetime.utcfromtimestamp(int(
                    match['timeStamp'])).strftime('%j'))

            d_km = dist_utm_km((x, y), station_locations[station])
            #cu.execute('INSERT INTO distance VALUES (:julian_day, :x, :y, :dist_km, :station)',
            #{'julian_day': julian_day, 'x':x, 'y':y, 'dist_km': d_km, 'station':station} )
            #cu.execute('INSERT INTO distance VALUES (:julian_day, :x, :y, :dist_km)',
            #           {'julian_day': julian_day, 'x':x, 'y':y, 'dist_km': d_km, } )
            cu.execute('INSERT INTO distance VALUES (:julian_day, :dist_km)', {
                'julian_day': julian_day,
                'dist_km': d_km,
            })
            if line_num % 10000 == 9999:
                cx.commit()

        cx.commit()

    if False:
        print 'Creating indexes'
        try:
            cx.execute('CREATE INDEX idx_dist_day ON distance(julian_day);')
            cx.execute('CREATE INDEX idx_dist_dist ON distance(dist_km);')
            #cx.execute('CREATE INDEX idx_dist_station ON distance(station);')
            cx.commit()
        except sqlite3.OperationalError:
            print 'Appears indexes were already created'

    return cx, counts
예제 #48
0
def decodecorner1_lon(bv, validate=False):
    return Decimal(binary.signedIntFromBV(bv[69:87]))/Decimal('600')