AIS数据-渔船的货船的区分(Distinction between the cargo ships of fishing boats)

本篇博客我们研究如何对一个区域的船舶进行区分。水域的航迹点分为两类:船舶搁浅点和船舶移动点。在确定研究水域中船舶搁浅点和运动点的速度阈值时,发现当航行速度在0〜1 kn范围内时,船舶航迹呈现出最大数量的分散点,并且没有连续的航迹点。因此,这些散落物被判断为搁置点。如果过滤器速度值范围为0‑1.1 kn,则会有连续的轨迹点,表明当前1.1 kn不是最佳速度阈值。因此,最佳速度阈值设置为1 kn,以区分搁置点和移动点。

具体的验证过程可以参考文献《RESEARCH ON SHIP TRAJECTORY EXTRACTION BASED ON MULTI-ATTRIBUTE DBSCAN OPTIMISATION ALGORITHM》

为此编写了分割程序,算法的思路是利用船舶整条轨迹AIS数据中对地航速(SOG)的均值和速度阈值vth(vth=1.1kn)对比,若船舶编号为 i 的轨迹其速度均值 vi > 1.1kn,则把船舶 i 判断为货船;若船舶编号为 的轨迹其速度均值 vj ≤ 1.1kn,则把船舶 j 判断为渔船。

△我们需要对一个区域的船舶进行划分,这会涉及到海量的AIS的数据,保存AIS数据的方式是利用.xlsx 进行保存的,而保存AIS数据的.xlsx文件不止一个,如图1所示。

AIS数据-渔船的货船的区分(Distinction between the cargo ships of fishing boats)_第1张图片

图1 保存的AIS数据

如果手动地一个个执行AIS数据文件,那么效率会大大降低。现在需要利用计算机依次执行目标文件中的AIS数据文件,再划分完成后也要依次的输出货船的AIS数据文件。恰好Python中,有一个glob 包,可以实现了" 以读方式打开文件,批量读取.xlsx文件 ",函数名及应用如下:

import glob

"""-----以读方式打开文件——批量读取xlsx-----"""
file_path = r'text_files'                                  # 文件夹位置
file = glob.glob(os.path.join(file_path, "*.xlsx"))        # 文件列表

 file中保存了 'text_files' 文件夹下所有".xlsx"文件的名称,以列表进行保存,如图2所示。

AIS数据-渔船的货船的区分(Distinction between the cargo ships of fishing boats)_第2张图片

 图2 列表 file

下面就是对整体的工程编写代码:

1. 导入用到的包:

# -*- coding: utf-8 -*-
"""
         File Name :      渔船的货船的区分
         Description :    Bistinction between the cargo ships of fishing boats
         Author :         张尺
         date :           2022/05/30
"""
from   __future__ import division
from   math       import sqrt, pow
import matplotlib.pyplot as plt
import pandas            as pd
import os
import glob

2. 编写函数Distinguish_between_fishing_boats_and_cargo_ships(),目的是计算一天船舶轨迹的平均速度:

def Distinguish_between_fishing_boats_and_cargo_ships(ais_data_list):
    """ --------计算这条船舶的平均速度-------- """
    sum_speed = 0
    for index, point in enumerate(ais_data_list):
        sum_speed = sum_speed + point[4]
    ave_speed = sum_speed / len(ais_data_list)
    return ave_speed

3. 编写主程序,实现一个文件内所有AIS数据的划分,并依次画出划分完成后渔船的轨迹图:

if __name__ == '__main__':
    fig = plt.figure()                                         # 画图准备
    """-----以读方式打开文件——批量读取xlsx-----"""
    file_path = r'text_files'                                  # 文件夹位置
    file = glob.glob(os.path.join(file_path, "*.xlsx"))        # 文件列表
    file.sort()                                                # 文件列表按名称排序
    print(file)
    for  file_i in range(len(file)):
            """----依次读取文件----"""
            Reading_file_path = file[file_i]
            Save_file_path =  Reading_file_path
            """----实现字符串相减功能----"""
            for i in Save_file_path:
                if i in 'text_files\sort_Mexican船舶:).xlsx':
                    Save_file_path = Save_file_path.replace(i,"")
            """----实现捕获文件编号和捕获船舶数目----"""
            sign = 0
            file_num = ''
            ais_miss_num = ' '
            for i in Save_file_path:
                if i == '(':                # 分割标志
                    sign = 1
                    continue
                if sign == 0:               # 文件号
                   file_num = file_num + i
                if sign == 1:               # 船舶数目
                   ais_miss_num = ais_miss_num + i

            Save_file_path = "Shift_Mexican" + file_num + ".xlsx"
            print("保存文件:%s,船舶数目:%s,读取文件路径:%s"%(Save_file_path,ais_miss_num,Reading_file_path))

            AIS_MMIS = []                      # 储存各个船舶的MMSI号
            AIS_MMIS_NUM = int(ais_miss_num)   # MISS号的个数,手动输入
            AIS_MMIS_NUM_LIST = []             # MISS号每个船舶,对应的AIS数据个数
            ship = pd.read_excel(Reading_file_path)
            mmsi =  ship['MMSI']
            time =  ship['BaseDateTime']
            lat =   ship['LAT']
            lon =   ship['LON']
            sog =   ship['SOG']
            cog =   ship['COG']
            heading = ship['Heading']

            # print(shipdata.index)     # 获取行的索引名称
            # print(shipdata.columns)   # 获取列的索引名称
            Temporary_variable_miss = mmsi[0]
            AIS_MMIS.append(mmsi[0])    # 先赋值第一个船舶的MMSI号
            all_ships = list()          # 创建货船的数据的AIS_MMIS_NUM个列表
            for i in range(AIS_MMIS_NUM):
                all_ships.append([])
            """ ---统计各个MMSI号的AIS数据个数,这里要求数据必须是对齐的--- """
            i = 0
            j = 1
            while i < len(lon):
                if mmsi[i] == Temporary_variable_miss:
                    j = j + 1
                    Temporary_variable_miss = mmsi[i]
                else:
                    AIS_MMIS_NUM_LIST.append(j)
                    AIS_MMIS.append(mmsi[i])
                    j = 1
                    Temporary_variable_miss = mmsi[i]
                i = i + 1
            AIS_MMIS_NUM_LIST.append(j)
            AIS_MMIS_NUM_LIST[0] = AIS_MMIS_NUM_LIST[0] - 1
            """ ---不同MMSI号对应着不同的AIS数据个数,创建这个列表--- """
            i = 0
            j = 0
            while i < AIS_MMIS_NUM:
                for j in range(AIS_MMIS_NUM_LIST[i]):
                    all_ships[i].append([])
                i = i + 1
            """ ---往 all_ships 赋值--- """
            i = 0
            j = 0
            k = 0
            for i in  range(AIS_MMIS_NUM):
                for j in range(AIS_MMIS_NUM_LIST[i]):
                    all_ships[i][j].append(mmsi[k])
                    all_ships[i][j].append(time[k])
                    all_ships[i][j].append(lat[k])
                    all_ships[i][j].append(lon[k])
                    all_ships[i][j].append(sog[k])
                    all_ships[i][j].append(cog[k])
                    all_ships[i][j].append(heading[k])
                    k = k + 1
                i = i + 1
            """ ----创建货船的数据列表---- """
            cargo_ships = list()     # 创建货船的数据列表
            fishing_ships = list()   # 创建渔船的数据列表

            ''' ----利用船舶的速度去判断---- '''
            for i in range(AIS_MMIS_NUM):
                judge_value = Distinguish_between_fishing_boats_and_cargo_ships(all_ships[i])
                if  judge_value > 1.1:
                    cargo_ships.append(all_ships[i])
                else:
                    fishing_ships.append(all_ships[i])
            '''---- 储存一下货船的MMSI号 ----'''
            cargo_ships_mmsi = []
            for cargo_data in cargo_ships:
                 cargo_ships_mmsi.append(cargo_ships[0][0])
            '''---- 储存一下渔船的MMSI号 ----'''
            fishing_ships_mmsi = []
            for fishing_data in fishing_ships:
                fishing_ships_mmsi.append(fishing_ships[0][0])

            print("渔船个数:%s" % len(fishing_ships_mmsi))
            print("货船个数:%s" % len(cargo_ships_mmsi))

            '''---- 储存渔船到 excel 中 ----'''
            # for i in fishing_ships_mmsi:
            #     ship.drop(ship[(ship.MMSI == i)].index, inplace=True)
            # ship.to_excel(Save_file_path)
            '''---- 储存货船到 excel 中 ----'''
            # for i in cargo_ships_mmsi:
            #     ship.drop(ship[(ship.MMSI == i)].index, inplace=True)
            # ship.to_excel(Save_file_path)

            """ ----------画图、显示出来---------- """
            for i in range(len(cargo_ships)):
                show_original_line_x = []
                show_original_line_y = []
                for show_point in cargo_ships[i]:
                    show_original_line_x.append(show_point[3])
                    show_original_line_y.append(show_point[2])

                plt.clf() # 用于画多个图时, 清空画面

                ax1 = fig.add_subplot(111)  # 111,指的就是将这块画布分为1×1,然后1对应的就是1号区
                plt.plot(show_original_line_x, show_original_line_y, color='green',linestyle='--')
                plt.scatter(show_original_line_x, show_original_line_y, color='green')
                # plt.title("ship_ships")
                plt.title("cargo_ships")
                plt.sca(ax1)

                plt.pause(1)  # 显示秒数

4. 示例,分离的渔船轨迹图,如图3所示:

AIS数据-渔船的货船的区分(Distinction between the cargo ships of fishing boats)_第3张图片

  (a) 示例1

AIS数据-渔船的货船的区分(Distinction between the cargo ships of fishing boats)_第4张图片

  (b) 示例2

AIS数据-渔船的货船的区分(Distinction between the cargo ships of fishing boats)_第5张图片

  (c) 示例3 

图 3 渔船轨迹图

5. 示例,分离的货船轨迹图,如图4所示:

AIS数据-渔船的货船的区分(Distinction between the cargo ships of fishing boats)_第6张图片

  (a) 示例1 

AIS数据-渔船的货船的区分(Distinction between the cargo ships of fishing boats)_第7张图片

  (b) 示例2  

AIS数据-渔船的货船的区分(Distinction between the cargo ships of fishing boats)_第8张图片

  (c) 示例3   

图 4 货船轨迹图

参考文献:

[1] RESEARCH ON SHIP TRAJECTORY EXTRACTION BASED ON MULTI-ATTRIBUTE DBSCAN OPTIMISATION ALGORITHM

完整工程(数据集+Python),在我的博客“资源”界面下,需要下载~

欢迎留言,欢迎指正~
 

 

 

你可能感兴趣的:(python,AIS,船舶自动识别系统,开发语言,python)