def get_ship_count(source_path, source_table, target_db, ship_table, ship_rol_list, ): db = CommonDB(target_db) sql = "INSERT INTO {} SELECT DISTINCT MMSI, Vessel_type_sub FROM {}".format(ship_table, source_table) db.import_data_from_path(source_path, ship_table, ship_rol_list, sql, ) db.run_sql("SELECT COUNT(DISTINCT MMSI) FROM {}".format(ship_table)) original_ship = db.db_cursor.next()[0] print("original_ship:" + str(original_ship)) db.run_sql("SELECT COUNT(DISTINCT MMSI) FROM {} WHERE Vessel_type = 'Crude Oil Tanker'".format( ship_table)) tanker_ship = db.db_cursor.next()[0] print("tanker_ship:" + str(tanker_ship))
class AISService(object): def __init__(self, db_name=''): self.ais_db = CommonDB(db_name) self.ais_point = None def import_data_from_path( self, source_path, source_table, target_table, rol_list, create_table=True, filter_query="WHERE Vessel_type_sub='Crude Oil Tanker'"): sql = "INSERT INTO {} SELECT * FROM {} {} GROUP BY MMSI, ts_pos_utc".format( target_table, source_table, filter_query) self.ais_db.import_data_from_path(source_path, target_table, rol_list, sql, create_table) # region 数据清洗 def clean_dirty_data(self, table_name, speed_threshold=None, draft_threshold=None): self.clean_mmsi_error_data(table_name) self.clean_lack_error_data(table_name) if speed_threshold is not None: self.clean_speed_error_data(table_name, speed_threshold) if draft_threshold is not None: self.clean_draft_error_data(table_name, draft_threshold) # 剔除掉mmsi错误的数据 def clean_mmsi_error_data(self, table_name): self.ais_db.delete_data(table_name, ["MMSI > 999999999", "MMSI < 100000000"], Const.OR_CONNECT_WORD) # 剔除掉属性缺失的数据 def clean_lack_error_data(self, table_name): filter_list = [ "speed is null", "draft is null", "longitude is null", "latitude is null", "mmsi is null", "utc is null" ] self.ais_db.delete_data(table_name, filter_list, Const.OR_CONNECT_WORD) # 删除掉速度异常的数据 def clean_speed_error_data(self, table_name, speed_threshold): self.ais_db.delete_data( table_name, ["speed < 0", "speed > {}".format(speed_threshold)], Const.OR_CONNECT_WORD) # 删除掉吃水异常的数据 def clean_draft_error_data(self, table_name, draft_threshold): self.ais_db.delete_data( table_name, ["draft <= 0", "draft > {}".format(draft_threshold)], Const.OR_CONNECT_WORD) # endregion # region 数据获取 def start_fetch_data_transaction(self, source_table): self.ais_db.run_sql( "SELECT mmsi, mark, imo, vessel_name, vessel_type, length, width, country, longitude, " "latitude, draft, speed, utc FROM {} ORDER BY mmsi, mark, utc". format(source_table)) row = self.ais_db.db_cursor.next() self.ais_point = AISPoint(row[0], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12], row[1]) return self.ais_point def start_fetch_original_data_transaction(self, source_table): self.ais_db.run_sql( "SELECT mmsi, imo, vessel_name, vessel_type_sub, length, width, flag_country, longitude, " "latitude, draft, speed, utc FROM {} ORDER BY mmsi, utc ".format( source_table)) row = self.ais_db.db_cursor.next() self.ais_point = AISPoint(row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11]) return self.ais_point def has_next_ais_ship(self): return self.ais_point is not None # endregion # region form trajectory def form_trajectory(self, draft_dict, static_info_writer, line_index, port_service, port_search_distance_threshold, outliers_distance_threshold, outliers_speed_threshold): # init is_line_head = True before_ship = self.ais_point ais_points = [] load_state = draft_dict.fetch_draft_state(before_ship.draft) outliers_count = 0 for row in self.ais_db.db_cursor: after_ship = AISPoint(row[0], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12], row[1]) if is_line_head: before_ship, after_ship = self.line_head_outliers_detection( before_ship, after_ship, outliers_distance_threshold, outliers_speed_threshold) is_line_head = False if len(ais_points) == 0 or ais_points[-1] != before_ship: ais_points.append(before_ship) if after_ship.is_same_ship(before_ship): # 判断是否异常点 if AISService.is_outliers(after_ship, before_ship, outliers_distance_threshold, outliers_speed_threshold): outliers_count += 1 continue if draft_dict.fetch_draft_state( after_ship.draft) != load_state: print(after_ship) if len(ais_points) > 1: AISService.export_trajectory_to_csv( ais_points, load_state, port_service, port_search_distance_threshold, static_info_writer, line_index) line_index += 1 load_state = draft_dict.fetch_draft_state(after_ship.draft) self.ais_point = after_ship ais_points = [] else: AISService.export_trajectory_to_csv( ais_points, load_state, port_service, port_search_distance_threshold, static_info_writer, line_index) self.ais_point = after_ship return line_index + 1, outliers_count before_ship = after_ship AISService.export_trajectory_to_csv(ais_points, load_state, port_service, port_search_distance_threshold, static_info_writer, line_index) self.ais_point = None return line_index + 1, outliers_count def skip_useless_trajectory(self): for row in self.ais_db.db_cursor: after_ship = AISPoint(row[0], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12], row[1]) if not after_ship.is_same_ship(self.ais_point): self.ais_point = after_ship return self.ais_point = None return # endregion def close(self): self.ais_db.close_db() @staticmethod def export_trajectory_to_csv(ais_points, load_state, port_service, distance_threshold, csv_writer, line_index): if len(ais_points) == 0: return first_point = ais_points[0] source_port, source_distance = port_service.get_nearest_port( arcpy.PointGeometry( arcpy.Point(first_point.longitude, first_point.latitude)), distance_threshold) last_point = ais_points[-1] target_port, target_distance = port_service.get_nearest_port( arcpy.PointGeometry( arcpy.Point(last_point.longitude, last_point.latitude)), distance_threshold) Utils.export_to_csv(ais_points, csv_writer, [ source_port.name, source_distance, target_port.name, target_distance, load_state, line_index ]) def line_head_outliers_detection(self, before_ship, after_ship, outliers_distance_threshold, outliers_speed_threshold): if not AISService.is_outliers(after_ship, before_ship, outliers_distance_threshold, outliers_speed_threshold): return before_ship, after_ship row = next(self.ais_db.db_cursor) middle_ship = after_ship after_ship = AISPoint(row[0], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12], row[1]) if AISService.is_outliers(middle_ship, after_ship, outliers_distance_threshold, outliers_speed_threshold): return before_ship, after_ship else: return middle_ship, after_ship def same_mmsi_identify(self, csv_writer, speed_threshold, distance_threshold, point_percent): ship_point = 1 before_ship = self.ais_point sequentially = [[before_ship]] for row in self.ais_db.db_cursor: after_ship = AISPoint(row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11]) if after_ship.is_same_ship(before_ship): self.sequentially_identify(after_ship, sequentially, speed_threshold, distance_threshold) ship_point += 1 else: self.export_final_sequentially(sequentially, csv_writer, point_percent * ship_point) self.ais_point = after_ship return before_ship = after_ship self.export_final_sequentially(sequentially, csv_writer, point_percent * ship_point) self.ais_point = None return @staticmethod def is_outliers(after_ship, before_ship, outliers_distance_threshold, outliers_speed_threshold): average_speed = after_ship.get_average_speed_between( before_ship, outliers_distance_threshold) return average_speed > outliers_speed_threshold @staticmethod def sequentially_identify(ship_point, sequentially, speed_threshold, distance_threshold): for i in range(len(sequentially)): speed = ship_point.get_average_speed_between( sequentially[i][-1], distance_threshold) if speed < speed_threshold: sequentially[i].append(ship_point) return sequentially.append([ship_point]) return @staticmethod def export_final_sequentially(sequentially, csv_writer, point_threshold): for i in range(len(sequentially)): if len(sequentially[i]) < point_threshold: continue for ship_point in sequentially[i]: ship_point.set_mark(i) csv_writer.writerow(ship_point.export_to_csv())