利用串口解析AIS接收機數據

串口:
串行接口簡稱串口,也稱串行通信接口或串行通訊接口(通常指COM接口),是採用串行通信方式的擴展接口。串行接口 (Serial Interface) 是指數據一位一位地順序傳送,其特點是通信線路簡單,只要一對傳輸線就可以實現雙向通信(可以直接利用電話線作爲傳輸線),從而大大降低了成本,特別適用於遠距離通信,但傳送速度較慢。

AIS接收機
船舶自動識別系統,是指一種應用於船和岸、船和船之間的海事安全與通信的新型助航系統。常由VHF通信機、GPS定位儀和與船載顯示器及傳感器等相連接的通信控制器組成,能自動交換船位、航速、航向、船名、呼號等重要信息。裝在船上的AIS在向外發送這些信息的同時,同樣接收VHF覆蓋範圍內其他船舶的信息,從而實現了自動應答。此外,作爲一種開放式數據傳輸系統,它可與雷達、ARPA、ECDIS、VTS等終端設備和INTERNET實現連接,構成海上交管和監視網絡,是不用雷達探測也能獲得交通信息的有效手段,可以有效減少船舶碰撞事故。

java實現串口通信:
基於java語言實現 對AIS接收機的數據解析,java代碼:

package com.yang.serialport.manager;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.TooManyListenersException;

import com.yang.serialport.utils.ArrayUtils;
import com.yang.serialport.utils.ShowUtils;

import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;

/**
 * 串口管理
 * 
 * @author SMF
 */
@SuppressWarnings("all")
public class SerialPortManager {

	/**
	 * 查找所有可用端口
	 * 
	 * @return 可用端口名稱列表
	 */
	public static final ArrayList<String> findPorts() {
		// 獲得當前所有可用串口
		Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers();
		ArrayList<String> portNameList = new ArrayList<String>();
		// 將可用串口名添加到List並返回該List
		while (portList.hasMoreElements()) {
			String portName = portList.nextElement().getName();
			portNameList.add(portName);
		}
		return portNameList;
	}

	/**
	 * 打開串口
	 * 
	 * @param portName
	 *            端口名稱
	 * @param baudrate
	 *            波特率
	 * @return 串口對象
	 * @throws PortInUseException
	 *             串口已被佔用
	 */
	public static final SerialPort openPort(String portName, int baudrate) throws PortInUseException {
		try {
			// 通過端口名識別端口
			CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
			// 打開端口,並給端口名字和一個timeout(打開操作的超時時間)
			CommPort commPort = portIdentifier.open(portName, 2000);
			// 判斷是不是串口
			if (commPort instanceof SerialPort) {
				SerialPort serialPort = (SerialPort) commPort;
				try {
					// 設置一下串口的波特率等參數
					// 數據位:8
					// 停止位:1
					// 校驗位:None
					serialPort.setSerialPortParams(baudrate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
							SerialPort.PARITY_NONE);
				} catch (UnsupportedCommOperationException e) {
					e.printStackTrace();
				}
				return serialPort;
			}
		} catch (NoSuchPortException e1) {
			e1.printStackTrace();
		}
		return null;
	}

	/**
	 * 關閉串口
	 * 
	 * @param serialport
	 *            待關閉的串口對象
	 */
	public static void closePort(SerialPort serialPort) {
		if (serialPort != null) {
			serialPort.close();
		}
	}

	/**
	 * 往串口發送數據
	 * 
	 * @param serialPort
	 *            串口對象
	 * @param order
	 *            待發送數據
	 */
	public static void sendToPort(SerialPort serialPort, byte[] order) {
		OutputStream out = null;
		try {
			out = serialPort.getOutputStream();
			out.write(order);
			out.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null) {
					out.close();
					out = null;
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	

	/**
	 * 從串口讀取數據
	 * 
	 * @param serialPort
	 *            當前已建立連接的SerialPort對象
	 * @return 讀取到的數據
	 */
	public static byte[] readFromPort(SerialPort serialPort) {
		InputStream in = null;
		byte[] bytes = {};
		try {
			in = serialPort.getInputStream();
			// 緩衝區大小爲一個字節
			byte[] readBuffer = new byte[1];
			int bytesNum = in.read(readBuffer);
			while (bytesNum > 0) {
				bytes = ArrayUtils.concat(bytes, readBuffer);
				bytesNum = in.read(readBuffer);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (in != null) {
					in.close();
					in = null;
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return bytes;
	}

	/**
	 * 添加監聽器
	 * 
	 * @param port
	 *            串口對象
	 * @param listener
	 *            串口存在有效數據監聽
	 */
	public static void addListener(SerialPort serialPort, DataAvailableListener listener) {
		try {
			// 給串口添加監聽器
			serialPort.addEventListener(new SerialPortListener(listener));
			// 設置當有數據到達時喚醒監聽接收線程
			serialPort.notifyOnDataAvailable(true);
			// 設置當通信中斷時喚醒中斷線程
			serialPort.notifyOnBreakInterrupt(true);
		} catch (TooManyListenersException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 串口監聽
	 */
	public static class SerialPortListener implements SerialPortEventListener {

		private DataAvailableListener mDataAvailableListener;

		public SerialPortListener(DataAvailableListener mDataAvailableListener) {
			this.mDataAvailableListener = mDataAvailableListener;
		}

		public void serialEvent(SerialPortEvent serialPortEvent) {
			switch (serialPortEvent.getEventType()) {
			case SerialPortEvent.DATA_AVAILABLE: // 1.串口存在有效數據
				if (mDataAvailableListener != null) {
					mDataAvailableListener.dataAvailable();
				}
				break;

			case SerialPortEvent.OUTPUT_BUFFER_EMPTY: // 2.輸出緩衝區已清空
				break;

			case SerialPortEvent.CTS: // 3.清除待發送數據
				break;

			case SerialPortEvent.DSR: // 4.待發送數據準備好了
				break;

			case SerialPortEvent.RI: // 5.振鈴指示
				break;

			case SerialPortEvent.CD: // 6.載波檢測
				break;

			case SerialPortEvent.OE: // 7.溢位(溢出)錯誤
				break;

			case SerialPortEvent.PE: // 8.奇偶校驗錯誤
				break;

			case SerialPortEvent.FE: // 9.幀錯誤
				break;

			case SerialPortEvent.BI: // 10.通訊中斷
				ShowUtils.errorMessage("與串口設備通訊中斷");
				break;

			default:
				break;
			}
		}
	}

	/**
	 * 串口存在有效數據監聽
	 */
	public interface DataAvailableListener {
		/**
		 * 串口存在有效數據
		 */
		void dataAvailable();
	}
}

界面 代碼:

package com.yang.serialport.ui;

import java.awt.Color;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

import com.nms.ais.AIS_Analyse;
import com.yang.serialport.manager.SerialPortManager;
import com.yang.serialport.utils.ByteUtils;
import com.yang.serialport.utils.ShowUtils;
import com.yang.serialport.utils.SqlSessionFactoryInit;

import gnu.io.PortInUseException;
import gnu.io.SerialPort;

/**
 * 主界面
 * 
 * @author SMF
 */
@SuppressWarnings("all")
public class MainFrame extends JFrame {

	// 程序界面寬度
	public final int WIDTH = 1000;
	// 程序界面高度
	public final int HEIGHT = 390;

	// 數據顯示區
	private JTextArea mDataView = new JTextArea();
	private JScrollPane mScrollDataView = new JScrollPane(mDataView);

	//有效數據顯示區域
	public static  JTextArea mDataValiableView = new JTextArea();
	public static JScrollPane mScrollDataViewValiable = new JScrollPane(mDataValiableView);
	// 串口設置面板
	private JPanel mSerialPortPanel = new JPanel();
	private JLabel mSerialPortLabel = new JLabel("串口");
	private JLabel mBaudrateLabel = new JLabel("波特率");
	private JComboBox mCommChoice = new JComboBox();
	private JComboBox mBaudrateChoice = new JComboBox();
	private ButtonGroup mDataChoice = new ButtonGroup();
	private JRadioButton mDataASCIIChoice = new JRadioButton("ASCII", true);
	private JRadioButton mDataHexChoice = new JRadioButton("Hex");

	// 操作面板
	private JPanel mOperatePanel = new JPanel();
	private JTextArea mDataInput = new JTextArea();
	private JButton mSerialPortOperate = new JButton("打開串口");
	private JButton mSendData = new JButton("發送數據");

	// 串口列表
	private List<String> mCommList = null;
	// 串口對象
	private SerialPort mSerialport;

	public MainFrame() {
		try{
		SqlSessionFactoryInit.creatSqlSessionFactory();
		initView();
		initComponents();
		actionListener();
		initData();
		}catch(Exception e){
			e.printStackTrace();
		}
	}

	/**
	 * 初始化窗口
	 */
	private void initView() {
		// 關閉程序
		setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
		// 禁止窗口最大化
		setResizable(false);

		// 設置程序窗口居中顯示
		Point p = GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint();
		setBounds(p.x - WIDTH / 2, p.y - HEIGHT / 2, WIDTH, HEIGHT);
		this.setLayout(null);

		setTitle("串口通信");
	}

	/**
	 * 初始化控件
	 */
	private void initComponents() {
		// 數據顯示
		mDataView.setFocusable(false);
		mScrollDataView.setBounds(10, 10, 505, 200);
		add(mScrollDataView);
		
		// 數據顯示
		mDataValiableView.setFocusable(false);
		mScrollDataViewValiable.setBounds(520, 10, 400, 200);
		add(mScrollDataViewValiable);
		
		
		// 串口設置
		mSerialPortPanel.setBorder(BorderFactory.createTitledBorder("串口設置"));
		mSerialPortPanel.setBounds(10, 220, 170, 130);
		mSerialPortPanel.setLayout(null);
		add(mSerialPortPanel);

		mSerialPortLabel.setForeground(Color.gray);
		mSerialPortLabel.setBounds(10, 25, 40, 20);
		mSerialPortPanel.add(mSerialPortLabel);

		mCommChoice.setFocusable(false);
		mCommChoice.setBounds(60, 25, 100, 20);
		mSerialPortPanel.add(mCommChoice);

		mBaudrateLabel.setForeground(Color.gray);
		mBaudrateLabel.setBounds(10, 60, 40, 20);
		mSerialPortPanel.add(mBaudrateLabel);

		mBaudrateChoice.setFocusable(false);
		mBaudrateChoice.setBounds(60, 60, 100, 20);
		mSerialPortPanel.add(mBaudrateChoice);

		mDataASCIIChoice.setBounds(20, 95, 55, 20);
		mDataHexChoice.setBounds(95, 95, 55, 20);
		mDataChoice.add(mDataASCIIChoice);
		mDataChoice.add(mDataHexChoice);
		mSerialPortPanel.add(mDataASCIIChoice);
		mSerialPortPanel.add(mDataHexChoice);

		// 操作
		mOperatePanel.setBorder(BorderFactory.createTitledBorder("操作"));
		mOperatePanel.setBounds(200, 220, 315, 130);
		mOperatePanel.setLayout(null);
		add(mOperatePanel);

		mDataInput.setBounds(25, 25, 265, 50);
		mDataInput.setLineWrap(true);
		mDataInput.setWrapStyleWord(true);
		mOperatePanel.add(mDataInput);

		mSerialPortOperate.setFocusable(false);
		mSerialPortOperate.setBounds(45, 95, 90, 20);
		mOperatePanel.add(mSerialPortOperate);

		mSendData.setFocusable(false);
		mSendData.setBounds(180, 95, 90, 20);
		mOperatePanel.add(mSendData);
	}

	/**
	 * 初始化數據
	 */
	private void initData() {
		mCommList = SerialPortManager.findPorts();
		// 檢查是否有可用串口,有則加入選項中
		if (mCommList == null || mCommList.size() < 1) {
			ShowUtils.warningMessage("沒有搜索到有效串口!");
		} else {
			for (String s : mCommList) {
				mCommChoice.addItem(s);
			}
		}

		mBaudrateChoice.addItem("9600");
		mBaudrateChoice.addItem("19200");
		mBaudrateChoice.addItem("38400");
		mBaudrateChoice.addItem("57600");
		mBaudrateChoice.addItem("115200");
	}

	/**
	 * 按鈕監聽事件
	 */
	private void actionListener() {
		// 串口
		mCommChoice.addPopupMenuListener(new PopupMenuListener() {

			@Override
			public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
				mCommList = SerialPortManager.findPorts();
				// 檢查是否有可用串口,有則加入選項中
				if (mCommList == null || mCommList.size() < 1) {
					ShowUtils.warningMessage("沒有搜索到有效串口!");
				} else {
					int index = mCommChoice.getSelectedIndex();
					mCommChoice.removeAllItems();
					for (String s : mCommList) {
						mCommChoice.addItem(s);
					}
					mCommChoice.setSelectedIndex(index);
				}
			}

			@Override
			public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
				// NO OP
			}

			@Override
			public void popupMenuCanceled(PopupMenuEvent e) {
				// NO OP
			}
		});

		// 打開|關閉串口
		mSerialPortOperate.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				if ("打開串口".equals(mSerialPortOperate.getText()) && mSerialport == null) {
					openSerialPort(e);
				} else {
					closeSerialPort(e);
				}
			}
		});

		// 發送數據
		mSendData.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				sendData(e);
			}
		});
	}

	/**
	 * 打開串口
	 * 
	 * @param evt
	 *            點擊事件
	 */
	private void openSerialPort(java.awt.event.ActionEvent evt) {
		// 獲取串口名稱
		String commName = (String) mCommChoice.getSelectedItem();
		// 獲取波特率,默認爲9600
		int baudrate = 9600;
		String bps = (String) mBaudrateChoice.getSelectedItem();
		baudrate = Integer.parseInt(bps);

		// 檢查串口名稱是否獲取正確
		if (commName == null || commName.equals("")) {
			ShowUtils.warningMessage("沒有搜索到有效串口!");
		} else {
			try {
				mSerialport = SerialPortManager.openPort(commName, baudrate);
				if (mSerialport != null) {
					mDataView.setText("串口已打開" + "\r\n");
					mSerialPortOperate.setText("關閉串口");
				}
			} catch (PortInUseException e) {
				ShowUtils.warningMessage("串口已被佔用!");
			}
		}

		// 添加串口監聽
		SerialPortManager.addListener(mSerialport, new SerialPortManager.DataAvailableListener() {

			@Override
			public void dataAvailable() {
				byte[] data = null;
				try {
					if (mSerialport == null) {
						ShowUtils.errorMessage("串口對象爲空,監聽失敗!");
						System.out.print("串口對象爲空,監聽失敗!");
					} else {
						// 讀取串口數據
						data = SerialPortManager.readFromPort(mSerialport);
						//System.out.println(data.toString());
						// 以字符串的形式接收數據
						if (mDataASCIIChoice.isSelected()) {
							mDataView.append(new String(data) + "\r\n");							
							AIS_Analyse.comport1_DataReceived(new String(data));
							//System.out.println(new String(data) + "\r\n");
						}

						// 以十六進制的形式接收數據
						if (mDataHexChoice.isSelected()) {
							mDataView.append(ByteUtils.byteArrayToHexString(data) + "\r\n");
							///System.out.println(ByteUtils.byteArrayToHexString(data));
						}
					}
				} catch (Exception e) {
					ShowUtils.errorMessage(e.toString());
					e.printStackTrace();
					// 發生讀取錯誤時顯示錯誤信息後退出系統
					System.exit(0);
				}
			}
		});
	}

	/**
	 * 關閉串口
	 * 
	 * @param evt
	 *            點擊事件
	 */
	private void closeSerialPort(java.awt.event.ActionEvent evt) {
		SerialPortManager.closePort(mSerialport);
		mDataView.setText("串口已關閉" + "\r\n");
		mSerialPortOperate.setText("打開串口");
		mSerialport = null;
	}

	/**
	 * 發送數據
	 * 
	 * @param evt
	 *            點擊事件
	 */
	private void sendData(java.awt.event.ActionEvent evt) {
		// 待發送數據
		String data = mDataInput.getText().toString();

		if (mSerialport == null) {
			ShowUtils.warningMessage("請先打開串口!");
			return;
		}

		if ("".equals(data) || data == null) {
			ShowUtils.warningMessage("請輸入要發送的數據!");
			return;
		}

		// 以字符串的形式發送數據
		if (mDataASCIIChoice.isSelected()) {
			SerialPortManager.sendToPort(mSerialport, data.getBytes());
		}

		// 以十六進制的形式發送數據
		if (mDataHexChoice.isSelected()) {
			SerialPortManager.sendToPort(mSerialport, ByteUtils.hexStr2Byte(data));
		}
	}

	public static void main(String args[]) {
		java.awt.EventQueue.invokeLater(new Runnable() {
			public void run() {
				new MainFrame().setVisible(true);
			}
		});
	}
}

AIS數據解析 此處較爲複雜:

package com.nms.ais;

import java.util.ArrayList;
import java.util.List;

import com.nms.dao.config.BoatMapper;
import com.nms.model.config.Boat;
import com.nms.service.config.BoatHistoryService;
import com.nms.service.config.BoatService;
import com.yang.serialport.manager.SerialPortManager;
import com.yang.serialport.ui.MainFrame;
import com.yang.serialport.utils.AISLog;
import com.yang.serialport.utils.MiscUtil;
import com.yang.serialport.utils.Msg;
import com.yang.serialport.utils.SqlSessionFactoryInit;

import gnu.io.SerialPort;
/**
 * @author smf
 * @description ais數據解析
 * */
public class AIS_Analyse {
	public String AIS_msg = null; // 觸發一次串口事件接收到的AIS數據

	public static int i = 0;

	public int j = 0;
	public int k = 0;
	/**單一語句長度*/
	public static int data_length = 0; // 單一語句長度
	/**語句字符位置*/
	public int chars_count = 0; // 語句字符位置
	/**完整的一條AIS語句*/
	public static char[] SingleDataBuffer = new char[82]; // 完整的一條AIS語句
	/**一條AIS語句的解封裝結果*/
	public static char[] sum_binary = new char[372]; // 一條AIS語句的解封裝結果
	/**單一語句字符數*/
	public static int data_count; // 單一語句字符數
	/** AIS語句接收窗口顯示的AIS語句計數*/
	public static int newline_count = 0; // AIS語句接收窗口顯示的AIS語句計數
	/**事件順序(語句排列順序)標識*/
	public static int event_count = 0; // 事件順序(語句排列順序)標識
	/**用戶船(查詢目標)識別碼*/
	public String TargetMMSI = null; // 用戶船(查詢目標)識別碼
	/**用戶船(查詢目標)查詢結果標識*/
	public static int MMSI_enable = 0; // 用戶船(查詢目標)查詢結果標識
	/**語句類型識別碼*/
	public static int defi_m = 0; // 語句類型識別碼
	/**當前AIS信息包含的經度*/
	public static double RecentLongitude; // 當前AIS信息包含的經度
	public static double RecentLatitude; // 當前AIS信息包含的緯度
	public static double RecentCourse; // 當前AIS信息包含的航向信息

	public static double ShipLongitude; // 用戶船經度
	public static double ShipLatitude; // 用戶船緯度
	public static double BaseLongitude; // 基站經度
	public static double BaseLatitude; // 基站緯度
	public static BoatMapper boatMapper = SqlSessionFactoryInit.getContext().getBean(BoatMapper.class);
	public static BoatService boatService = SqlSessionFactoryInit.getContext().getBean(BoatService.class);
	public static BoatHistoryService boatHistoryService = SqlSessionFactoryInit.getContext().getBean(BoatHistoryService.class);
	public double PI = Math.PI; // 3.14159265358979323846
	public double R = 6371.393; // 地球半徑
	public double Distance; // 兩點間距離
	/**天線轉向的目的位置*/
	public String DestinationAngle = null; // 天線轉向的目的位置

	public static int basechange; // 基站切換指令標識
	public static int count_enable; // 指向角度計算控制指令標識 : 1.計算開始; 0.計算關閉
	public static int angle_send; // 指向角度發送指令標識 : 1.發送開始; 0.發送關閉

	// public bool bOpenPort; //1.串口2關閉; 0.串口2打開
	public Boolean bCountDistanceAUTO; // 指向角計算使能信號: 1.計算開始; 0.計算關閉
	public Boolean bChangeBase; // 基站選擇使能信號: 1.選擇船載移動基站; 0.選擇岸基基站
	public Boolean bAngleSendAUTO; // 目的位置自動發送使能型號: 1.發送開始; 0.發送關閉
	private static List<String> _buff = new ArrayList<String>();
	private static Boolean _recstatu = false; // 是否處於一個正在接收數據包的狀態
	/**數據域起始位*/
	public static int data_start; // 數據域起始位
	/**數據域終止位*/
	public static int data_end; // 數據域終止位
	/** 語句類型識別碼*/
	public static int sen_f; // 語句類型識別碼

	public static void Data_analyze_m123(String AISMessage ) // 消息1、2、3數據解析
	{
		int i=0;
		Boat boat = new Boat();

		AISMessage += "\r\n\r\n";
		AISMessage += "解析後的數據如下:\r\n\r\n";

		// 二進制數據向有效數據轉換

		char data_tr_bin; // 二進制數據中間變量初始化
		int data_tr_valid = 0; // 有效數據中間變量初始化
		int count_s = 0; // 數據位起始值
		int count_e = 0; // 數據位終止值
		int digit_num; // 數據位數

		// 提取消息識別碼

		int message_identifier; // 消息識別碼

		digit_num = 6; // 消息識別碼的位數爲6位
		count_e = count_s + digit_num - 1; // 計算數據終止位

		for (i = count_s; i <= count_e; i++) {
			data_tr_bin = sum_binary[i];
			data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));
		}

		message_identifier = data_tr_valid;

		switch (message_identifier) {
		case 1: {
			AISMessage += "消息識別碼:  ";
			AISMessage += String.valueOf(message_identifier);
			AISMessage += "  即 消息類型爲“定時的船位報告(A類船載移動設備)”。\r\n";

			break;
		}

		case 2: {
			AISMessage += "消息識別碼:  ";
			AISMessage += String.valueOf(message_identifier);
			AISMessage += "  即 消息類型爲“定時的船位報告(A類船載移動設備)”。\r\n";

			break;
		}

		case 3: {
			AISMessage += "消息識別碼:  ";
			AISMessage += String.valueOf(message_identifier);
			AISMessage += "  即 消息類型爲“特別船位報告,對詢問的回覆(A類船載移動設備)”。\r\n";

			break;
		}

		}

		count_s = count_e + 1; // 提取完畢後,重置數據位起始值

		// END(提取消息識別碼)

		// 提取轉發指示符

		int transpond_indicate; // 轉發指示符

		digit_num = 2; // 轉發指示符的位數爲2位
		count_e = count_s + digit_num - 1; // 計算數據終止位
		data_tr_valid = 0;
		for (i = count_s; i <= count_e; i++) {
			data_tr_bin = sum_binary[i];
			data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));
		}

		transpond_indicate = data_tr_valid;

		AISMessage += "轉發指示符:  ";

		AISMessage += String.valueOf(transpond_indicate);
		AISMessage += "  即 該條消息被轉發的次數爲:";
		AISMessage += String.valueOf(transpond_indicate);
		AISMessage += "  次。\r\n";

		count_s = count_e + 1; // 提取完畢後,重置數據位起始值

		// END(提取轉發指示符)

		// 提取用戶識別碼,即MMSI碼

		int MMSI; // 用戶識別碼

		digit_num = 30; // 用戶識別碼,即MMSI碼的位數爲30位
		count_e = count_s + digit_num - 1; // 計算數據終止位
		data_tr_valid = 0;
		for (i = count_s; i <= count_e; i++) {
			data_tr_bin = sum_binary[i];
			data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));
		}

		MMSI = data_tr_valid;

		AISMessage += "用戶識別碼(即MMSI碼):  ";
		AISMessage += String.valueOf(MMSI);
		AISMessage += "\r\n";

		//String MMSI_OUT = String.valueOf(MMSI); // 提取當前信息的MMSI碼,用於船舶識別

		count_s = count_e + 1; // 提取完畢後,重置數據位起始值

		// END(提取用戶識別碼,即MMSI碼)

		// 提取航行狀態

		int navigation_status; // 航行狀態

		digit_num = 4; // 航行狀態的位數爲4位
		count_e = count_s + digit_num - 1; // 計算數據終止位
		data_tr_valid = 0;
		for (i = count_s; i <= count_e; i++) {
			data_tr_bin = sum_binary[i];
			data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));
		}

		navigation_status = data_tr_valid;

		AISMessage += "航行狀態:  ";
		AISMessage += String.valueOf(navigation_status);
		if (navigation_status == 15)
			AISMessage += " 即 默認值(未定義)";
		AISMessage += "\r\n";

		count_s = count_e + 1; // 提取完畢後,重置數據位起始值

		// END(提取航行狀態)

		// 提取轉向率ROT(AIS)

		int ROT_AIS; // 轉向率ROT(AIS)

		digit_num = 8; // 轉向率ROT(AIS)的位數爲8位
		count_e = count_s + digit_num - 1; // 計算數據終止位
		data_tr_valid = 0;

		if (sum_binary[count_s] != '1') {

			for (i = count_s; i <= count_e; i++) {
				data_tr_bin = sum_binary[i];
				data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));

			}

			ROT_AIS = data_tr_valid;

			AISMessage += "轉向率ROT(AIS):  ";
			AISMessage += String.valueOf(ROT_AIS);
			AISMessage += " 度/分鐘";
			AISMessage += "\r\n";

		}

		else if (sum_binary[count_s] == '1') {
			// ("轉向率是負數\n");
			for (i = count_s + 1; i <= count_e; i++) {
				if (sum_binary[i] == '0')
					data_tr_bin = '1';
				else
					data_tr_bin = '0';

				data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));

			}
			data_tr_valid = data_tr_valid + 1;

			data_tr_valid = -data_tr_valid;

			ROT_AIS = data_tr_valid;

			AISMessage += "轉向率ROT(AIS):  ";
			AISMessage += String.valueOf(ROT_AIS);
			AISMessage += " 度/分鐘";
			if (ROT_AIS == -128)
				AISMessage += " 即默認值(表示無法獲得)";
			AISMessage += "\r\n";
		}

		count_s = count_e + 1; // 提取完畢後,重置數據位起始值

		// END(提取轉向率ROT(AIS))

		// 提取對地航速

		double speed_over_ground; // 對地航速

		digit_num = 10; // 對地航速的位數爲10位
		count_e = count_s + digit_num - 1; // 計算數據終止位
		data_tr_valid = 0;

		for (i = count_s; i <= count_e; i++) {
			data_tr_bin = sum_binary[i];
			data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));
		}

		speed_over_ground = (float) (data_tr_valid) / 10;

		AISMessage += "對地航速:  ";
		AISMessage += String.valueOf(speed_over_ground);
		boat.setSog(speed_over_ground+"kn");
		AISMessage += " kn";
		AISMessage += "\r\n";

		count_s = count_e + 1; // 提取完畢後,重置數據位起始值

		// END(提取對地航速)

		// 提取船位精確度

		int position_accuracy; // 船位精確度

		digit_num = 1; // 船位精確度的位數爲1位
		count_e = count_s + digit_num - 1; // 計算數據終止位
		data_tr_valid = 0;
		for (i = count_s; i <= count_e; i++) {
			data_tr_bin = sum_binary[i];
			data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));

		}

		position_accuracy = data_tr_valid;

		AISMessage += "船位精確度:  ";
		AISMessage += String.valueOf(position_accuracy);
		if (data_tr_valid == 1)
			AISMessage += " 即 高精度(<10m,DGNSS接收機的差分模式)";
		else if (data_tr_valid == 0)
			AISMessage += " 即 低精度(>10m,GNSS接收機或其他電子定位裝置的自主模式)";
		AISMessage += "\r\n";

		count_s = count_e + 1; // 提取完畢後,重置數據位起始值

		// END(提取船位精確度)

		// 提取經度

		double longitude; // 經度

		digit_num = 28; // 經度的位數爲28位
		count_e = count_s + digit_num - 1; // 計算數據終止位
		data_tr_valid = 0;

		int hour;
		int minute;
		double second;

		if (sum_binary[count_s] != '1') {
			// ("經度是正數,即東經\n");
			for (i = count_s; i <= count_e; i++) {
				data_tr_bin = sum_binary[i];
				data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));

			}

			longitude = (float) ((data_tr_valid) / 10000);

			hour = (int) (data_tr_valid / 10000 / 60);

			minute = (int) (longitude - hour * 60);

			second = (longitude - hour * 60 - minute) * 60;

			RecentLongitude = longitude / 60; // 將經度信息傳遞給全局變量,單位爲度

			AISMessage += "經度:  ";
			AISMessage += "東經 ";
			AISMessage += String.valueOf(hour);
			AISMessage += "度";
			AISMessage += String.valueOf(minute);
			AISMessage += "分";
			AISMessage += String.valueOf(0.0000);
			AISMessage += "秒";
			AISMessage += "\r\n";

		}

		else if (sum_binary[count_s] == '1') {
			// ("經度是負數,即西經\n");
			for (i = count_s + 1; i <= count_e; i++) {
				if (sum_binary[i] == '0')
					data_tr_bin = '1';
				else
					data_tr_bin = '0';

				data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));

			}
			data_tr_valid = data_tr_valid + 1; // 經度的絕對值

			longitude = (float) ((data_tr_valid) / 10000);

			hour = (int) (data_tr_valid / 10000 / 60);

			minute = (int) (longitude - hour * 60);

			second = (longitude - hour * 60 - minute) * 60;

			longitude = -longitude; // 經度的真實值

			RecentLongitude = longitude / 60; // 將經度信息傳遞給全局變量

			AISMessage += "經度:  ";
			AISMessage += "西經 ";
			AISMessage += String.valueOf(hour);
			AISMessage += "度";
			AISMessage += String.valueOf(minute);
			AISMessage += "分";
			AISMessage += String.valueOf(0.0000);
			AISMessage += "秒";
			AISMessage += "\r\n";

		}

		count_s = count_e + 1; // 提取完畢後,重置數據位起始值

		// END(提取經度)

		// 提取緯度

		double latitude; // 緯度

		digit_num = 27; // 緯度的位數爲27位
		count_e = count_s + digit_num - 1; // 計算數據終止位
		data_tr_valid = 0;

		if (sum_binary[count_s] != '1') {
			//// ("緯度是正數,即北緯\n");
			for (i = count_s; i <= count_e; i++) {
				data_tr_bin = sum_binary[i];
				data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));

			}

			latitude = (float) (data_tr_valid) / 10000;

			hour = (int) (data_tr_valid / 10000 / 60);

			minute = (int) (latitude - hour * 60);

			second = (latitude - hour * 60 - minute) * 60;

			RecentLatitude = latitude / 60; // 將當前緯度傳遞給全局變量

			AISMessage += "緯度:  ";
			AISMessage += "北緯 ";
			AISMessage += String.valueOf(hour);
			AISMessage += "度";
			AISMessage += String.valueOf(minute);
			AISMessage += "分";
			AISMessage += String.valueOf(0.0000);
			AISMessage += "秒";
			AISMessage += "\r\n";

		}

		else if (sum_binary[count_s] == '1') {
			// ("緯度是負數,即南緯\n");
			for (i = count_s + 1; i <= count_e; i++) {
				if (sum_binary[i] == '0')
					data_tr_bin = '1';
				else
					data_tr_bin = '0';

				data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));

			}
			data_tr_valid = data_tr_valid + 1; // 緯度的絕對值

			latitude = (float) (data_tr_valid) / 10000;

			hour = (int) (data_tr_valid / 10000 / 60);

			minute = (int) (latitude - hour * 60);

			second = (latitude - hour * 60 - minute) * 60;

			latitude = -latitude; // 緯度的真實值

			RecentLatitude = latitude / 60; // 將當前緯度傳遞給全局變量

			AISMessage += "緯度:  ";
			AISMessage += "南緯 ";
			AISMessage += String.valueOf(hour);
			AISMessage += "度";
			AISMessage += String.valueOf(minute);
			AISMessage += "分";
			AISMessage += String.valueOf(0.0000);
			AISMessage += "秒";
			AISMessage += "\r\n";

		}

		count_s = count_e + 1; // 提取完畢後,重置數據位起始值

		// END(提取緯度)

		// 提取對地航向

		double course_over_the_ground;

		digit_num = 12; // 對地航向的位數爲12位
		count_e = count_s + digit_num - 1; // 計算數據終止位
		data_tr_valid = 0;

		for (i = count_s; i <= count_e; i++) {
			data_tr_bin = sum_binary[i];
			data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));
		}

		course_over_the_ground = (float) (data_tr_valid) / 10;

		AISMessage += "對地航向:  ";
		AISMessage += String.valueOf(course_over_the_ground);
		boat.setCog(course_over_the_ground+"度");
		AISMessage += "度";
		if (course_over_the_ground >= 360)
			AISMessage += " 即 默認值(不可用)";
		AISMessage += "\r\n";

		count_s = count_e + 1; // 提取完畢後,重置數據位起始值

		// END(提取對地航向)

		// 提取真航向

		int true_course; // 真航向

		digit_num = 9; // 真航向的位數爲9位
		count_e = count_s + digit_num - 1; // 計算數據終止位
		data_tr_valid = 0;

		for (i = count_s; i <= count_e; i++) {
			data_tr_bin = sum_binary[i];
			data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));
		}

		true_course = data_tr_valid;

		AISMessage += "真航向:  ";
		AISMessage += String.valueOf(true_course);
		AISMessage += "度";
		if (true_course == 511)
			AISMessage += " 即 默認值(不可用)";
		AISMessage += "\r\n";

		count_s = count_e + 1; // 提取完畢後,重置數據位起始值

		// END(提取真航向)

		// 提取時間標記

		int time_marker; // 時間標記

		digit_num = 6; // 時間標記的位數爲6位
		count_e = count_s + digit_num - 1; // 計算數據終止位
		data_tr_valid = 0;
		for (i = count_s; i <= count_e; i++) {
			data_tr_bin = sum_binary[i];
			data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));
		}

		time_marker = data_tr_valid;

		AISMessage += "時間標記:  ";
		AISMessage += "報告產生時的UTC秒: ";
		AISMessage += String.valueOf(time_marker);
		AISMessage += "\r\n";

		count_s = count_e + 1; // 提取完畢後,重置數據位起始值

		// END(提取時間標記)

		// 提取爲地區性應用所保留

		digit_num = 4; // 爲地區性應用所保留的位數爲4位
		count_e = count_s + digit_num - 1; // 計算數據終止位
		data_tr_valid = 0;
		for (i = count_s; i <= count_e; i++) {
			data_tr_bin = sum_binary[i];
			data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));
		}

		AISMessage += "爲地區性應用所保留:  ";
		AISMessage += String.valueOf(data_tr_valid);
		AISMessage += "\r\n";

		count_s = count_e + 1; // 提取完畢後,重置數據位起始值

		// END(提取爲地區性應用所保留)

		// 提取備用位

		digit_num = 1; // 備用位的位數爲1位
		count_e = count_s + digit_num - 1; // 計算數據終止位
		data_tr_valid = 0;
		for (i = count_s; i <= count_e; i++) {
			data_tr_bin = sum_binary[i];
			data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));
		}

		AISMessage += "備用位:  ";
		AISMessage += String.valueOf(data_tr_valid);
		AISMessage += "\r\n";

		count_s = count_e + 1; // 提取完畢後,重置數據位起始值

		// END(提取備用位)

		// 提取RAIM標誌

		int RAIM; // RAIM標誌

		digit_num = 1; // RAIM標誌的位數爲1位
		count_e = count_s + digit_num - 1; // 計算數據終止位
		data_tr_valid = 0;
		for (i = count_s; i <= count_e; i++) {
			data_tr_bin = sum_binary[i];
			data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));
		}

		RAIM = data_tr_valid;

		AISMessage += "RAIM標誌:  ";
		AISMessage += String.valueOf(RAIM);
		if (RAIM == 1)
			AISMessage += " 即 RAIM使用";
		else
			AISMessage += " 即 RAIM未使用(默認)";
		AISMessage += "\r\n";

		count_s = count_e + 1; // 提取完畢後,重置數據位起始值

		// END(提取RAIM標誌)

		// 提取通信狀態

		// fprintf(w1,"%s","通信狀態: ");

		AISMessage += "通信狀態:  ";

		if (message_identifier == 1 || message_identifier == 2) // 通信狀態爲SOTDMA
		{

			AISMessage += "SOTDMA通信狀態";
			AISMessage += "\r\n";

			// 提取同步狀態
			int synchronization_status; // 同步狀態

			digit_num = 2; // 同步狀態的位數爲2位
			count_e = count_s + digit_num - 1; // 計算數據終止位
			data_tr_valid = 0;

			for (i = count_s; i <= count_e; i++) {
				data_tr_bin = sum_binary[i];
				data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));
			}

			synchronization_status = data_tr_valid;

			AISMessage += "  同步狀態:  ";
			AISMessage += String.valueOf(synchronization_status);

			if (synchronization_status == 0) {

				AISMessage += " 即 直接獲取UTC";
				AISMessage += "\r\n";

			} else if (synchronization_status == 1) {

				AISMessage += " 即 間接獲取UTC";
				AISMessage += "\r\n";
			} else if (synchronization_status == 2) {

				AISMessage += " 即 臺站同步於基地臺";
				AISMessage += "\r\n";
			} else if (synchronization_status == 3) {

				AISMessage += " 即 臺站同步於另一個接受臺數量最多的臺站";
				AISMessage += "\r\n";
			}

			count_s = count_e + 1; // 提取完畢後,重置數據位起始值

			// 提取時隙超時
			int TS_overtime; // 時隙超時

			digit_num = 3; // 時隙超時的位數爲3位
			count_e = count_s + digit_num - 1; // 計算數據終止位
			data_tr_valid = 0;

			for (i = count_s; i <= count_e; i++) {
				data_tr_bin = sum_binary[i];
				data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));

			}

			TS_overtime = data_tr_valid;

			AISMessage += "  時隙超時:  ";
			AISMessage += String.valueOf(TS_overtime);

			if (TS_overtime == 0) {
				AISMessage += " 即 這是該時隙最後一次傳輸";
				AISMessage += "\r\n";
			} else {
				AISMessage += " 即 在時隙改變前將保留該時隙 ";
				AISMessage += String.valueOf(TS_overtime);
				AISMessage += " 幀";
				AISMessage += "\r\n";
			}

			count_s = count_e + 1; // 提取完畢後,重置數據位起始值

			// 提取子信息
			int child_information; // 子信息

			digit_num = 14; // 子信息的位數爲14位
			count_e = count_s + digit_num - 1; // 計算數據終止位
			data_tr_valid = 0;

			AISMessage += "  子信息:   ";

			if (TS_overtime == 3 || TS_overtime == 5 || TS_overtime == 7) {
				for (i = count_s; i <= count_e; i++) {
					data_tr_bin = sum_binary[i];
					data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));
				}

				child_information = data_tr_valid;

				AISMessage += " 本臺當前接收到其他臺站數量爲:";
				AISMessage += String.valueOf(child_information);
				AISMessage += "\r\n";

			}

			else if (TS_overtime == 2 || TS_overtime == 4 || TS_overtime == 6) {
				for (i = count_s; i <= count_e; i++) {
					data_tr_bin = sum_binary[i];
					data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));
				}

				child_information = data_tr_valid;

				AISMessage += " 用於該發射的時隙號爲:";
				AISMessage += String.valueOf(child_information);
				AISMessage += "\r\n";
			}

			else if (TS_overtime == 1) {
				int UTC_hour;
				int UTC_min;

				AISMessage += " UTC: ";

				for (i = count_s; i <= count_s + 4; i++) {
					data_tr_bin = sum_binary[i];
					data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_s + 4 - i));
				}

				UTC_hour = data_tr_valid;
				data_tr_valid = 0;

				AISMessage += String.valueOf(UTC_hour);
				AISMessage += " 小時";

				count_s = count_s + 5;

				for (i = count_s; i <= count_s + 6; i++) {
					data_tr_bin = sum_binary[i];
					data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_s + 6 - i));
				}

				UTC_min = data_tr_valid;

				AISMessage += String.valueOf(UTC_min);
				AISMessage += " 分";
				AISMessage += "\r\n";
			}

			else if (TS_overtime == 0) {
				for (i = count_s; i <= count_e; i++) {
					data_tr_bin = sum_binary[i];
					data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));

				}

				child_information = data_tr_valid;

				AISMessage += " 時隙偏移量爲:";
				AISMessage += String.valueOf(child_information);
				AISMessage += "\r\n";

			}

			count_s = count_e + 1; // 提取完畢後,重置數據位起始值
		}

		else if (message_identifier == 3) // 通信狀態爲ITDMA
		{

			AISMessage += "ITDMA通信狀態";
			AISMessage += "\r\n";

			// 提取同步狀態
			int synchronization_status; // 同步狀態

			digit_num = 2; // 同步狀態的位數爲2位
			count_e = count_s + digit_num - 1; // 計算數據終止位
			data_tr_valid = 0;

			for (i = count_s; i <= count_e; i++) {
				data_tr_bin = sum_binary[i];
				data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));
			}

			synchronization_status = data_tr_valid;

			AISMessage += "  同步狀態:  ";
			AISMessage += String.valueOf(synchronization_status);

			if (synchronization_status == 0) {
				AISMessage += " 即 直接獲取UTC";
				AISMessage += "\r\n";
			} else if (synchronization_status == 1) {
				AISMessage += " 即 間接獲取UTC";
				AISMessage += "\r\n";
			} else if (synchronization_status == 2) {
				AISMessage += " 即 臺站同步於基地臺";
				AISMessage += "\r\n";
			} else if (synchronization_status == 3) {
				AISMessage += " 即 臺站同步於另一個接受臺數量最多的臺站";
				AISMessage += "\r\n";
			}

			count_s = count_e + 1; // 提取完畢後,重置數據位起始值

			// 提取時隙增量

			int TS_add; // 時隙增量

			digit_num = 13; // 時隙增量的位數爲13位
			count_e = count_s + digit_num - 1; // 計算數據終止位
			data_tr_valid = 0;

			for (i = count_s; i <= count_e; i++) {
				data_tr_bin = sum_binary[i];
				data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));
			}

			TS_add = data_tr_valid;

			AISMessage += "  時隙增量:  ";
			AISMessage += String.valueOf(TS_add);

			if (TS_add == 0) {
				AISMessage += " 即 不在進行進一步的傳輸";
				AISMessage += "\r\n";
			} else {
				AISMessage += " 即 到下一個將要使用的時隙的偏移爲:";
				AISMessage += String.valueOf(TS_add);
				AISMessage += "幀";
				AISMessage += "\r\n";
			}

			count_s = count_e + 1; // 提取完畢後,重置數據位起始值

			// 提取時隙數
			int TS_num; // 時隙數

			digit_num = 3; // 時隙數的位數爲3位
			count_e = count_s + digit_num - 1; // 計算數據終止位
			data_tr_valid = 0;

			for (i = count_s; i <= count_e; i++) {
				data_tr_bin = sum_binary[i];
				data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));
			}

			TS_num = data_tr_valid;

			AISMessage += "  時隙數:   ";
			AISMessage += " 應分配的連續時隙的數量爲:";
			AISMessage += String.valueOf(TS_num);
			AISMessage += "\r\n";

			count_s = count_e + 1; // 提取完畢後,重置數據位起始值

			// 提取保持標記
			int maintain_marker; // 保持標記

			digit_num = 1; // 保持標記的位數爲1位
			count_e = count_s + digit_num - 1; // 計算數據終止位
			data_tr_valid = 0;

			for (i = count_s; i <= count_e; i++) {
				data_tr_bin = sum_binary[i];
				data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int) (Math.pow(2, count_e - i));
			}

			maintain_marker = data_tr_valid;

			AISMessage += "  保持標記:  ";
			AISMessage += String.valueOf(maintain_marker);
			if (maintain_marker == 1)
				AISMessage += "  即 時隙分配應多保留一幀";
			AISMessage += "\r\n";

			count_s = count_e + 1; // 提取完畢後,重置數據位起始值

		}
		AISLog.logInfo(AIS_Analyse.class, "Analysie123,"+"經度:"+RecentLongitude+",緯度:"+RecentLatitude+",mmsi:"+MMSI+",航速:"+boat.getCog()+",航向:"+boat.getSog());
		System.out.println("經度:"+RecentLongitude+",緯度:"+RecentLatitude+",mmsi:"+MMSI);
		   boat.setLongitude(String.valueOf(RecentLongitude));
		   boat.setLatitude(String.valueOf(RecentLatitude));
		   boat.setMmsiId(String.valueOf(MMSI));
		   BoatData(boat);
		System.out.println("AISMessage:"+AISMessage);
	}

	public void SendToRoll(double angle,SerialPort serialPort)
	{
	    if(serialPort!=null)
	    {
	        String ctrPosition;
	        ctrPosition = "PX";
	        ctrPosition += String.valueOf(angle);
	        ctrPosition += "\n\r";
	        SerialPortManager.sendToPort(serialPort, ctrPosition.getBytes());
	    }
	}

	 public double point_remove(double a, int point_num)
     {
         int k;
         double b;

         k = (int)(a * Math.pow(10, point_num));
         b = k / (Math.pow(10, point_num));

         return b;
     }

  
	 public void PointAngleCount(String textBox12,String textBox13)     //指向角計算函數
     {
         double ship_true_angle = RecentCourse;                          //對地航向
         double base_angle;                                            //基站(點B)相對於船(點A)的方位角
         double base_angle_rad = 0;                                     //基站(點B)相對於船(點A)的方位角的弧度值
         double BaseToShip_rot_angle;                                   //基站對於船首向的方位角,即天線的目的位置                                                                   

         double x, y;

         String temp;
         String temp1;
         String temp_send;
         String temp_send1;
      
         double Base_Long = 0.0;           //基站經度
         double Base_Lat = 0.0;            //基站緯度
         double Ship_Long = point_remove((Math.PI/180*(ShipLongitude)), 8);             //船舶經度,角度轉換爲弧度
         double Ship_Lat = point_remove(Math.PI/180*(ShipLatitude), 8);
         //double Ship_Lat  = rad(90-RecentLatitude) ;						  //船舶相對於正北的緯度(90-緯度)

         switch (basechange)
         {
             case 0:
                 {
                     if (textBox12 != "")
                     {
                         Base_Long = Double.parseDouble(textBox12);
                     }
                     else
                     {
                         Base_Long = 0.0;
                         textBox12 = "0";
                     }
                     Base_Long = rad(Base_Long);         //岸基基站經度(單位爲弧度)

                     if (textBox13 != "")
                     {
                         Base_Lat =  Double.parseDouble(textBox13);                         
                     }
                     else
                     {
                         Base_Lat = 0.0;
                         textBox13 = "0";
                     }
                     Base_Lat = rad(Base_Lat);           //岸基基站緯度(單位爲弧度)                       
                     break;
                 }

             case 1:
                 {
                     Base_Long = rad(BaseLongitude);          //船載移動基站經度(單位爲弧度)
                     Base_Lat = rad(BaseLatitude);            //船載移動基站緯度(單位爲弧度)
                     break;
                 }
         }

         //Base_Long = point_remove(rad(BaseLongitude), 8);                //基站經度(單位爲弧度)
         //Base_Lat = point_remove(rad(BaseLatitude), 8);                  //基站緯度(單位爲弧度)

         double Dif_Long = Base_Long - Ship_Long;                     //兩點經度之差 
        
         y = Math.sin(Dif_Long) * Math.cos(Base_Lat);
         x = Math.cos(Ship_Lat) * Math.sin(Base_Lat) - Math.sin(Ship_Lat) * Math.cos(Base_Lat) * Math.cos(Dif_Long);

         if (y > 0)
         {
             if (x > 0)
             {
                 base_angle_rad = Math.atan(y / x);
             }                   
             else if (x < 0)
             {
                 base_angle_rad = PI - Math.atan(-y / x);
             }                    
             else if (x == 0)
             {
                 base_angle_rad = PI / 2;
             }                   
         }

         else if (y < 0)
         {
             if (x > 0)
             {
                 base_angle_rad = -Math.atan(-y / x);
             }                   
             else if (x < 0)
             {
                 base_angle_rad = Math.atan(y / x) - PI;
             }                    
             else if (x == 0)
             {
                 base_angle_rad = PI * 3 / 2;
             }                   
         }

         else if (y == 0)
         {
             if (x > 0)
             {
                 base_angle_rad = 0;
             }                    
             else if (x < 0)
             {
                 base_angle_rad = PI;
             }                   
             else if (x == 0)
             {
                 temp = "兩點重合";
             }                   
         }

         base_angle = unrad(base_angle_rad);

         //point_num=2;
         base_angle = point_remove(base_angle, 2);

         if (base_angle < 0)
         {
             base_angle = base_angle + 360;
         }

         temp = String.valueOf(base_angle) + " 度";            //基站方位角
         temp_send = String.valueOf(base_angle);
     
         //如天線通信協議中以目的位置作爲參數時,基站對於船首向的方位角,即天線的目的位置,直接根據通信協議寫入控制信號

         if (base_angle > ship_true_angle)                                       //當基站方位角(β)大於航向角(α)時,則基站相對於船舶的方位角θ爲(θ=β-α)
         {
             BaseToShip_rot_angle = base_angle - ship_true_angle;
         }                
         else                                                                //當基站方位角(β)小於航向角(α)時,則基站相對於船舶的方位角θ爲(θ=360-(α-β))
         {
             BaseToShip_rot_angle = 360 - (ship_true_angle - base_angle);
         }
  
         temp1 =  String.valueOf(BaseToShip_rot_angle) + " 度";            //天線指向角
         temp_send1 =  String.valueOf(BaseToShip_rot_angle);

         DestinationAngle = temp_send1;

     }

	 public double rad(double angle)                    //角度轉換爲弧度
     {
         return angle * PI / 180.0;              //弧度 = 角度 * π / 180
     }

     public double unrad(double radian)                 //弧度轉換爲角度
     {
         return radian * 180.0 / PI;             //角度 = 弧度 * 180 / π
     }
	
     
     
    
     
     
     
     
     /**串口數據接收*/
     public static void comport1_DataReceived(String AIS_msg )//, SerialDataReceivedEventArgs e)
     {
        //Boat boat = new Boat();
         {
             try
             {
				/*
				 * int num = port.getDataBits(); char[] buffer = new char[num];
				 * SerialPortManager.readFromPort(port);//(buffer, 0, num);
				 */                 //AIS_msg = new String(buffer);
            	 
            	 char[] buffer  = AIS_msg.toCharArray();

                 //#region CXY   獲取GPRMC
                 for (char b: buffer)
                 {
                     if (b == '$')
                     {
                         _recstatu = true;
                         _buff.clear();
                     }
                     if (_recstatu)                           //是否處於接收數據包狀態
                     {
                         _buff.add(String.valueOf(b));
                     }
                     if (b == '\n')            //幀尾
                     {
                         _recstatu = false;
                        // HandleData(_buff.toArray());
                         _buff.clear();
                     }
                 }
                 //#endregion

                 //textBox1 += AIS_msg;
                 int number;
                 number = buffer.length;

                 String Window_TEXT = null;

                // textBox1.SelectionStart = textBox1.TextLength;
                 //textBox1.ScrollToCaret();
                 
                 data_length = 0;                //單一語句長度

                 int exclamation_num = 0;        //‘!’在語句中的位置
                 int exclamation_count = 0;
                 int enter_num = 0;          //‘\n’在語句中的位置
                 int enter_count = 0;

                 if (AIS_msg.contains("!"))                               //查找語句起始符‘!’
                 {
                     exclamation_count++;                                //‘!’計數
                     exclamation_num = AIS_msg.indexOf('!');               //‘!’在語句中的位置
                 }

                 if (AIS_msg.contains("\n"))                             //查找語句終止符‘\n’
                 {
                     enter_count++;                                    //‘\n’計數
                     enter_num = AIS_msg.indexOf('\n');                  //‘\n’在語句中的位置
                     newline_count++;                                  //累計計算換行符個數
                 }
                                     
                 if (newline_count == 100)                              //如果“AIS數據接收顯示”窗口顯示的數據超過100行,則清空窗口
                 {
                     //textBox1.Clear();
                     newline_count = 0;
                 }                   
                                     
                 //一個事件中語句傳輸完畢:

                 if (exclamation_count != 0 && enter_count != 0 && exclamation_num < enter_num)     //一個事件中語句傳輸完畢,即語句中包含語句起始符‘!’和語句終止符‘\n’,且‘!’在前,‘\n’在後
                 {
                     data_count = 0;

                     //CXY   解析GPS數據
                    // MyFun.GPS_RMC_Parse(AIS_msg.substring(exclamation_num, enter_num - exclamation_num));

                     for (int i = 0; i < AIS_msg.length(); i++)
                     {
                         SingleDataBuffer[i] = buffer[i];
                         data_count++;
                     }
                     
                     data_length = data_count - 1;                       //獲取語句長度                       

                     if (Data_check() != 0)                          //語句傳輸完畢,開始解析
                     {                    
                    	 System.out.println("通過檢查的數據------------------:"+AIS_msg);
                         Data_repro();
                         MainFrame.mDataValiableView.append(new String(AIS_msg) + "\r\n");
                         //System.out.println("defi_m-----------------------------"+defi_m);
                         switch (defi_m)
                         {
                             case 1:
                                 Data_analyze_m123(AIS_msg);
                                 break;
                             case 2:
                                 Data_analyze_m123(AIS_msg);
                                 break;
                             case 3:
                                 Data_analyze_m123(AIS_msg);
                                 break;
                             //case 5:
                             //Data_analyze_m5();
                             //break;
                             case 18:
                               Data_analyze_m18(AIS_msg);
                                 break;
                             case 19:
                                 Data_analyze_m19(AIS_msg);
                                 break;
                             default:
                                 break;
                         }

                         if (basechange == 0)
                         {
                             if (count_enable == 1 && MMSI_enable == 1)
                             {
                                // BaseDistanceCount();
                                 //PointAngleCount();

                                 if (angle_send == 1)
                                 {
                                    // AngleSend();
                                 }
                             }
                         }

                         else if (basechange == 1)
                         {
                            // if (count_enable == 1 && MMSI_enable != 0 && textBox5.Text != null)
                             {
                                // BaseDistanceCount();
                                 //PointAngleCount();

                                 if (angle_send == 1)
                                 {
                              //       AngleSend();
                                 }
                             }
                         }

                        // AIS_filesave_and_timer();
                     }
                     else
                     {
                         //textBox2.Clear();
                         Window_TEXT = "當前語句未通過數據檢查,無需解析\r\n";
                         //textBox2.Text = Window_TEXT;
                         System.out.println("當前語句未通過數據檢查,無需解析");
                         //textBox3.Clear();
                         Window_TEXT = "當前語句未通過數據檢查,無解析結果\r\n";
                         //textBox3.Text = Window_TEXT;
                     }
                 }


                 //一個事件中語句傳輸未完畢,使用多次事件傳輸:

                 if (exclamation_count != 0 && enter_count == 0)     //一個事件中語句傳輸未完成,且該條數據爲語句的第一條數據,即檢測到語句起始符‘!’,沒有語句終止符‘\n’
                 {
                     event_count = 1;                                //將該事件編號設爲1,即該語句的第一條數據
                     data_count = 0;

                     for (i = 0; i < AIS_msg.length(); i++)                
                     {
                         SingleDataBuffer[data_count] = buffer[i];
                         data_count++;
                     }      
                 }

                 else if (event_count != 0 && enter_count == 0)      //一個事件中語句傳輸未完成,且該條數據爲語句的第二條數據,即檢測到事件計數爲1,且沒有語句終止符‘\n’
                 {
                     event_count = 2;                                //將該事件編號設爲2,即該語句的第二條數據                                                                        

                     for (i = 0; i < AIS_msg.length(); i++)                 
                     {
                         SingleDataBuffer[data_count] = buffer[i];
                         data_count++;
                     }        
                 }

                 else if (enter_count != 0)                          //一個事件中語句的剩餘傳輸完成,且不包含下一條語句的起始部分,即該條數據爲不包含語句起始符,且有語句終止符‘\n’
                 {
                     if (event_count != 0)
                     {
                         event_count = 0;                            //語句的剩餘傳輸完成,該條語句的傳輸事件結束,事件計數歸零                                                                      

                         for (i = 0; i < enter_num; i++)               
                         {
                             SingleDataBuffer[data_count] = buffer[i];
                             data_count++;
                         }
     
                         data_length = data_count;               //獲取語句長度                           

                         if (Data_check() != 0)                      //語句傳輸完畢,開始解析
                         {                               

                             Data_repro();

                             switch (defi_m)
                             {
                                 case 1:
                                     Data_analyze_m123(AIS_msg);
                                     break;
                                 case 2:
                                     Data_analyze_m123(AIS_msg);
                                     break;
                                 case 3:
                                     Data_analyze_m123(AIS_msg);
                                     break;
                                 //case 5:
                                 //Data_analyze_m5();
                                 //break;
                                 case 18:
                                     Data_analyze_m18(AIS_msg);
                                     break;
                                 case 19:
                                     Data_analyze_m19(AIS_msg);
                                     break;
                                 default:
                                     break;
                             }

                             if (basechange == 0)
                             {
                                 if (count_enable == 1 && MMSI_enable == 1)
                                 {
                                     //BaseDistanceCount();
                                     //PointAngleCount();

                                     if (angle_send == 1)
                                     {
                                        // AngleSend();
                                     }
                                 }
                             }

                             else if (basechange == 1)
                             {
                                // if (count_enable == 1 && MMSI_enable != 0 && textBox5.Text != null)
                                 {
                                     //BaseDistanceCount();
                                     //PointAngleCount();

                                     if (angle_send == 1)
                                     {
                                        //AngleSend();
                                     }
                                 }
                             }

                             //AIS_filesave_and_timer();               //
                         }else
                         {
                            // textBox2.Clear();
                             //textBox2.Text = "1.當前語句未通過數據檢查,無需解析\r\n";
                        	 System.out.println("當前語句未通過數據檢查,無需解析");
                             //textBox3.Clear();                                
                             //textBox3.Text = "2.當前語句未通過數據檢查,無解析結果\r\n";
                         }                
                     }


                     if (event_count == 0 && exclamation_count != 0 && exclamation_num > enter_num)           //上一條語句傳輸完成,且該事件中包含下一條語句的起始部分
                     {
                         event_count = 1;
                         data_count = 0;

                         for (i = exclamation_num; i < AIS_msg.length(); i++)
                         {
                             SingleDataBuffer[data_count] = buffer[i];
                             data_count++;
                         }             
                     }
                 }
             }catch (Exception e) {
				// TODO: handle exception
            	AISLog.error(AIS_Analyse.class, e.getMessage());
            	 e.printStackTrace();
			}
             
         }
     }
     

   public static int Data_check()
   {
       int i;
       int check_number_count = 0;
       String StatusForAIS = null;
       String SingleAISData ="";        //語句解析結果

       int nt = 0;                       //","分隔符計數器
       int dn = 0;                       //需校驗的有效字符計數器SSS
       int data_xor = 0;                  //異或計算中間變量            
       int check_end = 0;                 //校驗終止位
                             
       
       int separate_num = 0;       //消息分解總條數-
       int serial_num = 0;         //語句序號
       int id_num = 0;             //順序語句標識
       int return_num = 0;         //數據返回碼(消息識別碼+數據起始位+數據終止位+拆分信息)

       
       //查找到校驗和

       int check_sum = 0;
       int[] n = new int[2];
     
       for (i = 0; i < data_count; i++)
       {
           if (SingleDataBuffer[i] == '*' && SingleDataBuffer[i] != '\0')
           {
               // puts("check_sum_in:");

               if (SingleDataBuffer[i + 1] >= '0' && SingleDataBuffer[i + 1] <= '9')  //校驗和最高位轉爲十六進制
                   n[1] = SingleDataBuffer[i + 1] - '0';

               else if (SingleDataBuffer[i + 1] >= 'A' && SingleDataBuffer[i + 1] <= 'Z')
                   n[1] = (SingleDataBuffer[i + 1] - 'A') + 10;

               else if (SingleDataBuffer[i + 1] >= 'a' && SingleDataBuffer[i + 1] <= 'z')
                   n[1] = (SingleDataBuffer[i + 1] - 'a') + 10;

               if (SingleDataBuffer[i + 2] >= '0' && SingleDataBuffer[i + 2] <= '9')  //校驗和最低位轉爲十六進制
                   n[0] = SingleDataBuffer[i + 2] - '0';

               else if (SingleDataBuffer[i + 2] >= 'A' && SingleDataBuffer[i + 2] <= 'Z')
                   n[0] = (SingleDataBuffer[i + 2] - 'A') + 10;

               else if (SingleDataBuffer[i + 2] >= 'a' && SingleDataBuffer[i + 2] <= 'z')
                   n[0] = (SingleDataBuffer[i + 2] - 'a') + 10;

               check_sum = n[1] * 16 + n[0];    //生成校驗和             
           }

           else if (SingleDataBuffer[i] == '\0')
               break;
       }

       //END
       
       //查找地址域,並判斷語句是否爲AIVDM或AIVDO消息

       char[] ad_f = new char[5];          
       char[] AIVDM = { 'A', 'I', 'V', 'D', 'M' };
       char[] AIVDO = { 'A', 'I', 'V', 'D', 'O' };            

       for (i = 0; i < 5; i++)
       {
           ad_f[i] = SingleDataBuffer[i + 1];
         
           if (ad_f[i] != AIVDM[i] && ad_f[i] != AIVDO[i])
           {
                StatusForAIS ="設備類型及語句類型不符合要求,無需解析\r\n";
              // textBox4.Clear();             //清空“當前語句解析狀態顯示”窗口 
               //textBox4.Text = StatusForAIS;
                System.out.println("status-------------"+StatusForAIS);
               sen_f = 0;
               return 0;
           }

           else if (ad_f[i] == AIVDM[i])
           {
               sen_f = 1;                  //接收到其他船舶的AIS信息,則語句類型識別碼爲1
           }                    

           else if (ad_f[i] == AIVDO[i])
           {
               sen_f = 2;                  //接收到其他船舶的AIS信息,則語句類型識別碼爲2
           }                  
       }

       if (sen_f == 1)
       {
           StatusForAIS ="該語句爲AIVDM消息,可以進行解析\r\n";  
           System.out.println("status-------------"+StatusForAIS);
           check_number_count += 1;
       }

       else if (sen_f == 2)
       {
           StatusForAIS ="該語句爲AIVDO消息,可以進行解析\r\n";       
           System.out.println("status-------------"+StatusForAIS);
           check_number_count += 1;
       }
       
       // END


       //找到數據域,並進行異或運算,並對數據進行校驗

       for (i = 0; i < data_count; i++)
       {
           if (SingleDataBuffer[i] == ',')
           {
               nt++;

               if (nt == 5)        //根據分隔符,查找數據域起始位
               {               
                   data_start = i + 2;                  
                   continue;
               }

               else if (nt == 6)   //根據分隔符,查找數據域終止位
               {    
                   check_end = i + 2;
                   data_end = i;          
               }
           }
           else
               continue;
       }
       dn = check_end - 2;             //異或運算次數

       data_xor = SingleDataBuffer[1];    //異或運算中間變量初始化

       for (i = 1; i <= dn; i++)           //對數據進行異或運算
       {           
           data_xor = data_xor ^ SingleDataBuffer[i + 1];            
       }
 
       if (data_xor != check_sum)          //判斷校驗結果是否正確	
       {       
           StatusForAIS = "校驗和錯誤\r\n";
           System.out.println("校驗和錯誤");
          // textBox4.Text = StatusForAIS;
           //textBox4.Clear();             //清空“當前語句解析狀態顯示”窗口              
           return 0;
       }

       else
       {
           check_number_count += 1;        
           System.out.println("校驗和正確");
           StatusForAIS = "校驗和正確\r\n";
       }
       if (check_number_count == 3)
       {
          // textBox2.Clear();         //清空“當前AIS數據顯示”窗口

           for (i = 0; i < data_length; i++)
           {         
               SingleAISData += SingleDataBuffer[i];
           }
           System.out.println("aisdata"+SingleAISData);
           //textBox2.Text = SingleAISData;
       }

       // END

       //拆分語句識別

       //int separate_num = 0;       //消息分解總條數
      // int serial_num = 0;         //語句序號
       //int id_num = 0;             //順序語句標識
       //int return_num = 0;         //數據返回碼(消息識別碼+數據起始位+數據終止位+拆分信息)

       nt = 0;                 //","分隔符計數器歸零

       for (i = 0; i < 82; i++)
       {
           if (SingleDataBuffer[i] == ',')
           {
               nt++;

               if (nt == 1)                                    //根據分隔符,查找消息分解總條數
               {         
                   separate_num = SingleDataBuffer[i + 1] - '0';              
                   continue;
               }

               else if (nt == 2)                               //根據分隔符,查找語句序號
               {    
                   serial_num = SingleDataBuffer[i + 1] - '0';            
                   continue;
               }

               else if (nt == 3 && separate_num > 1)           //根據分隔符,查找順序語句標識
               {            
                   id_num = SingleDataBuffer[i + 1] - '0';            
                   continue;
               }
           }
           else
               continue;
       }

       //查找數據域的第一個參數:“消息識別碼”,並判斷該消息是否含有可用信息,及是否進行解析

       //char start_char = SingleDataBuffer[data_start - 1];
       defi_m = 0;  
       char[] y;//消息識別碼初始化
       y = str_to_bi( SingleDataBuffer[data_start - 1] ).toCharArray();
       System.out.println("y-----"+new String(y));
       for (i = 1; i <= 6; i++)
       {   
           defi_m = defi_m + (y[i-1] - '0') * (int)(Math.pow(2, 6 - i));  
           //System.out.println(i+"-----"+defi_m+",y.i="+y[i-1]);
       }
       System.out.println("解析到的數據:defi_m--------"+defi_m);
       if (separate_num == 1 || serial_num == 1)          //對單一語句或拆分語句的
       {       
           if (defi_m != 1 && defi_m != 2 && defi_m != 3 && defi_m != 18 && defi_m != 19)                              //暫時不考慮靜態信息,只解析帶有經緯度信息的AIS語句 2017.10.26
           {                          
               //textBox4.Clear();           //清空“當前語句解析狀態顯示”窗口 
               System.out.println("此消息不屬於需使用的消息類型(消息1、2、3、5、18、19),無需解析");
                           
               return 0;
           }
           else
           {
               check_number_count += 1;               
               StatusForAIS = "該消息內包含可用信息,可以進行參數提取\r\n";
               System.out.println(StatusForAIS);
               //textBox4.Text = StatusForAIS;                    
           }          
       }

       else
       //AfxMessageBox("該消息爲拆分語句的後續語句,可以直接進行參數提取\n");
       {
           StatusForAIS += "該消息爲拆分語句的後續語句,可以合併後進行參數提取\r\n";
           //textBox4.Clear();              //清空“當前語句解析狀態顯示”窗口  
           System.out.println(StatusForAIS);
           return 0;
       }


       //textBox4.Clear();            //清空“當前語句解析狀態顯示”窗口
      

       if (check_number_count == 3)
       {
           //textBox2.Clear();         //清空“當前AIS數據顯示”窗口

           for (i = 0; i < data_length; i++)
           {         
               SingleAISData += SingleDataBuffer[i];
           }
           System.out.println("SingleAISData--------"+SingleAISData);
       }

       // END
       // 返回值整合(當語句未拆分時,返回消息識別碼、數據域起始值和數據域結束值;當拆分語句時,返回值增加語句序號和順序語句標識)

       if (separate_num == 1)
       {
           //("該條語句未進行拆分\n\n");  
           
           return_num = defi_m * 10000000 + data_start * 100000 + data_end * 1000 + 100;
          // textBox4.Text = StatusForAIS;
           return return_num;
       }

       else
       {
           //("該條語句爲拆分語句,共拆分爲%d條,該條語句的語句序號爲:%d\n\n");

           return_num = defi_m * 10000000 + data_start * 100000 + data_end * 1000 + separate_num * 100 + serial_num * 10 + id_num;
           return return_num;
       }          
     
   }
   
   
     
   public static int Data_repro()
   {
       //消息識別完畢,取數據域內容

       int dn_data;  //數據域有效字符計數器
       
       int i;

       //string temp;
       StringBuilder AISDataUnpack = new StringBuilder();

       StringBuilder y = new StringBuilder();

       dn_data = data_end - data_start + 1;

       for (i = 0; i < dn_data; i++)
       {
    	   String tempStr = str_to_bi(SingleDataBuffer[data_start + i - 1]).toString();
    	   if(tempStr!=null) {
    		   y =y.append(tempStr); 
    	   } else {
    		   System.out.println("null Error");
    	   }            
       }
       AISDataUnpack = y;
      // textBox3.Clear();                       //清空“數據解封裝結果顯示”窗口
      // textBox3.Text += "\r\n";
      // textBox3.Text += "語句解封裝後對應的二進制碼:\r\n";
       //textBox3.Text += AISDataUnpack;
//
       sum_binary = AISDataUnpack.toString().toCharArray();

       return 0;
   }     
     /**有效字符轉化爲6位二進制*/
   public static  String  str_to_bi(char a)     //有效字符轉化爲6位二進制
   {
       int rb;       //轉化中間變量return_binary
       rb = a + 0x28;

       if (rb > 0x80)
           rb = rb + 0x20;
       else
           rb = rb + 0x28;      //將有效字符轉化成十六進制,

       rb = rb & 0x3f;   //取後六位

       //將十六進制數轉化爲二進制字符

       char[] bi = new char[6];  //保留數組數據至程序執行完成
       int i;
       int r, n;               //聲明餘數和除數

       n = rb;

       for (i = 1; i <= 6; i++)
       {
           if (n != 0)
           {
               r = n % 2;
               n = n / 2;

               if(r == 1)
               {
                   bi[i - 1] = '1';
               }
               else
               {
                   bi[i - 1] = '0';
               }
                   
           }
           else
           {
               bi[i - 1] = '0';
           }
               
       }

       
       for (i = 1; i <= 3; i++)      //逆序輸出
       {
           char m;
           m = bi[i - 1];
           bi[i - 1] = bi[6 - i];
           bi[6 - i] = m;
       }

       String str = new String(bi);
       return str;
   }
 
     
     
     
     /**消息18數據解析*/
   public static void Data_analyze_m18(String AISMessage)   //消息18數據解析
   {
       int i=0;
       Boat boat = new Boat();            
       String temp1;
       String temp2;
       String temp3;
       String temp4;

       //String AISMessage = null;
      
       String MMSI_OUT;
       //String temp_MMSI;
       String temp_BaseShipMMSI = null;
       MMSI_enable = 0;

       //temp_MMSI = textBox5.Text;                          //讀取目前跟蹤的用戶船MMSI碼
       //temp_BaseShipMMSI = textBox18.Text;                  //讀取當前基站船的MMSI碼

       AISMessage += "\r\n\r\n";
       AISMessage += "解析後的數據如下:\r\n\r\n";

       
       // 二進制數據向有效數據轉換

       char data_tr_bin = 0;       //二進制數據中間變量初始化
       int data_tr_valid = 0;    //有效數據中間變量初始化
       int count_s = 0;          //數據位起始值
       int count_e = 0;          //數據位終止值
       int digit_num;          //數據位數

       // 提取消息識別碼

       int message_identifier;  //消息識別碼

       digit_num = 6;           //消息識別碼的位數爲6位
       count_e = count_s + digit_num - 1;   //計算數據終止位

       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));
       }

       message_identifier = data_tr_valid;

       if (message_identifier == 18)
       {    
           AISMessage += "消息識別碼:  ";
           AISMessage += message_identifier;
           AISMessage += "  即 消息類型爲“標準B類設備位置報告”。\r\n";
       }

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取消息識別碼)

       // 提取轉發指示符

       int transpond_indicate;   //轉發指示符

       digit_num = 2;           //轉發指示符的位數爲2位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));
       }

       transpond_indicate = data_tr_valid;

       AISMessage += "轉發指示符:  ";
       AISMessage += transpond_indicate;
       AISMessage += "  即 該條消息被轉發的次數爲:";
       AISMessage += transpond_indicate;
       AISMessage += "  次。\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取轉發指示符)

       // 提取用戶識別碼,即MMSI碼

       int MMSI;     //用戶識別碼

       digit_num = 30;           //用戶識別碼,即MMSI碼的位數爲30位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));                
       }

       MMSI = data_tr_valid;

       AISMessage += "用戶識別碼(即MMSI碼):  ";
       AISMessage += MMSI;
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       MMSI_OUT = String.valueOf(MMSI);       //提取當前信息的MMSI碼,用於船舶識別
       System.out.print("MMSI_OUT:"+MMSI_OUT);
       // END(提取用戶識別碼,即MMSI碼)

       // 提取爲地區或區域應用保留

       digit_num = 8;           //爲地區或區域應用保留的位數爲8位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));              
       }
 
       AISMessage += "爲地區性應用所保留:  ";
       AISMessage += data_tr_valid;
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取爲地區或區域應用保留)

       // 提取對地航速

       double speed_over_ground;     //對地航速

       digit_num = 10;           //對地航速的位數爲10位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;

       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));             
       }
     
       speed_over_ground = (float)(data_tr_valid) / 10;

       AISMessage += "對地航速:  ";
       AISMessage += speed_over_ground;
       boat.setSog(speed_over_ground+"kn");
       AISMessage += " kn";
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取對地航速)

       // 提取船位精確度

       int position_accuracy;     //船位精確度

       digit_num = 1;           //船位精確度的位數爲1位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));               
       }

       position_accuracy = data_tr_valid;

       AISMessage += "船位精確度:  ";
       AISMessage += position_accuracy;
       if (data_tr_valid == 1)
           AISMessage += " 即 高精度(<10m,DGNSS接收機的差分模式)";
       else if (data_tr_valid == 0)
           AISMessage += " 即 低精度(>10m,GNSS接收機或其他電子定位裝置的自主模式)";
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取船位精確度)

       // 提取經度

       double longitude;      //經度

       digit_num = 28;           //經度的位數爲28位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;

       int hour;
       int minute;
       double second;

       if (sum_binary[count_s] != '1')
       {
           //("經度是正數,即東經\n");
           for (i = count_s; i <= count_e; i++)
           {
               data_tr_bin = sum_binary[i];
               data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));    
               //System.out.print("原始經度數據:"+data_tr_valid);
           }

           longitude = (float)(data_tr_valid) / 10000;
      
           hour = (int)(data_tr_valid / 10000 / 60);
       
           minute = (int)(longitude - hour * 60);
      
           second = (longitude - hour * 60 - minute) * 60;

           RecentLongitude = longitude / 60;  //將經度信息傳遞給全局變量,單位爲度

           AISMessage += "經度:  ";
           AISMessage += "東經 ";
           AISMessage += hour;
           AISMessage += "度";
           AISMessage += minute;              
           AISMessage += "分";
           AISMessage += second;
           AISMessage += "秒";
           AISMessage += "\r\n";

       }

       else if (sum_binary[count_s] == '1')
       {
           //("經度是負數,即西經\n");
           for (i = count_s + 1; i <= count_e; i++)
           {
               if (sum_binary[i] == '0')
                   data_tr_bin = '1';
               else
                   data_tr_bin = '0';

               data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));
               //System.out.print("原始經度數據:"+data_tr_valid);
           }
           data_tr_valid = data_tr_valid + 1;  //經度的絕對值
                                     
           longitude = (float)(data_tr_valid) / 10000;
          
           hour = (int)(data_tr_valid / 10000 / 60);
          
           minute = (int)(longitude - hour * 60);
       
           second = (longitude - hour * 60 - minute) * 60;

           longitude = -longitude;      //經度的真實值                                        

           RecentLongitude = longitude / 60;  //將經度信息傳遞給全局變量

           AISMessage += "經度:  ";
           AISMessage += "西經 ";
           AISMessage += hour;
           AISMessage += "度";
           AISMessage += minute;
           AISMessage += "分";
           AISMessage += second;
           AISMessage += "秒";
           AISMessage += "\r\n";

       }

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取經度)

       // 提取緯度

       double latitude;    //緯度

       digit_num = 27;           //緯度的位數爲27位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;

       if (sum_binary[count_s] != '1')
       {
           //("緯度是正數,即北緯\n");
           for (i = count_s; i <= count_e; i++)
           {
               data_tr_bin = sum_binary[i];
               data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));   
               //System.out.print("原始經度數據:"+data_tr_valid);
           }

           latitude = (float)(data_tr_valid) / 10000;
        
           hour = (int)(data_tr_valid / 10000 / 60);
       
           minute = (int)(latitude - hour * 60);
        
           second = (latitude - hour * 60 - minute) * 60;

           RecentLatitude = latitude / 60;    //將當前緯度傳遞給全局變量

           AISMessage += "緯度:  ";
           AISMessage += "北緯 ";
           AISMessage += hour;
           AISMessage += "度";
           AISMessage += minute;
           AISMessage += "分";
           AISMessage += second;
           AISMessage += "秒";
           AISMessage += "\r\n";

       }

       else if (sum_binary[count_s] == '1')
       {
           //("緯度是負數,即南緯\n");
           for (i = count_s + 1; i <= count_e; i++)
           {
               if (sum_binary[i] == '0')
                   data_tr_bin = '1';
               else
                   data_tr_bin = '0';

               data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));
               //System.out.print("原始經度數據:"+data_tr_valid);
           }
           data_tr_valid = data_tr_valid + 1;  //緯度的絕對值                                              

           latitude = (float)(data_tr_valid) / 10000;
         
           hour = (int)(data_tr_valid / 10000 / 60);
      
           minute = (int)(latitude - hour * 60);
        
           second = (latitude - hour * 60 - minute) * 60;

           latitude = -latitude;      //緯度的真實值                                      

           RecentLatitude = latitude / 60;    //將當前緯度傳遞給全局變量
       
           AISMessage += "緯度:  ";
           AISMessage += "北緯 ";
           AISMessage += hour;
           AISMessage += "度";
           AISMessage += minute;
           AISMessage += "分";
           AISMessage += second;
           AISMessage += "秒";
           AISMessage += "\r\n";

       }

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取緯度)

       // 提取對地航向

       double course_over_the_ground;

       digit_num = 12;           //對地航向的位數爲12位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;

       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));             
       }

       course_over_the_ground = (float)(data_tr_valid) / 10;
  
       AISMessage += "對地航向:  ";
       AISMessage += course_over_the_ground;
       boat.setCog(course_over_the_ground+"度");
       AISMessage += "度";
       if (course_over_the_ground >= 360)
           AISMessage += " 即 默認值(不可用)";
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取對地航向)

       // 提取真航向

       int true_course;     //真航向

       digit_num = 9;           //真航向的位數爲9位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;

       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));          
       }

       true_course = data_tr_valid;

       AISMessage += "真航向:  ";
       AISMessage += true_course;
       AISMessage += "度";
       if (true_course == 511)
           AISMessage += " 即 默認值(不可用)";
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取真航向)

       // 提取時間標記

       int time_marker;    //時間標記

       digit_num = 6;           //時間標記的位數爲6位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));           
       }

       time_marker = data_tr_valid;

       AISMessage += "時間標記:  ";
       AISMessage += "報告產生時的UTC秒: ";
       AISMessage += time_marker;
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取時間標記)

       // 提取爲地區性應用所保留

       digit_num = 4;           //爲地區性應用所保留的位數爲4位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));             
       }
  
       AISMessage += "爲地區性應用所保留:  ";
       AISMessage += data_tr_valid;
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取爲地區性應用所保留)

       // 提取備用位

       digit_num = 4;           //備用位的位數爲4位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));              
       }
              
       AISMessage += "備用位:  ";
       AISMessage += data_tr_valid;
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取備用位)

       // 提取RAIM標誌

       int RAIM;     //RAIM標誌

       digit_num = 1;           //RAIM標誌的位數爲1位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));              
       }

       RAIM = data_tr_valid;

       AISMessage += "RAIM標誌:  ";
       AISMessage += RAIM;
       if (RAIM == 1)
           AISMessage += " 即 RAIM使用";
       else
           AISMessage += " 即 RAIM未使用(默認)";
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取RAIM標誌)

       // 提取通信狀態選擇標誌

       int conmunication_choose;

       digit_num = 1;           //通信狀態選擇標誌的位數爲1位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));              
       }

       conmunication_choose = data_tr_valid;

       AISMessage += "通信狀態選擇標誌:  ";
       AISMessage += conmunication_choose;

       switch (conmunication_choose)
       {
           case 0:
               AISMessage += " 即 SOTDMA通信狀態";
               break;
           case 1:                    
               AISMessage += " 即 ITDMA通信狀態";
               break;
           default:
               break;
       }

       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取通信狀態選擇標誌)

       // 提取通信狀態

      
       AISMessage += "通信狀態:  ";

       if (conmunication_choose == 0)         //通信狀態爲SOTDMA
       {
    
           AISMessage += "SOTDMA通信狀態";
           AISMessage += "\r\n";

           //提取同步狀態
           int synchronization_status;    //同步狀態

           digit_num = 2;           //同步狀態的位數爲2位
           count_e = count_s + digit_num - 1;   //計算數據終止位
           data_tr_valid = 0;

           for (i = count_s; i <= count_e; i++)
           {
               data_tr_bin = sum_binary[i];
               data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));            
           }

           synchronization_status = data_tr_valid;

           AISMessage += "  同步狀態:  ";
           AISMessage += synchronization_status;

           if (synchronization_status == 0)
           {                   
               AISMessage += " 即 直接獲取UTC";
               AISMessage += "\r\n";
           }
           else if (synchronization_status == 1)
           {
               AISMessage += " 即 間接獲取UTC";
               AISMessage += "\r\n";
           }
           else if (synchronization_status == 2)
           {
               AISMessage += " 即 臺站同步於基地臺";
               AISMessage += "\r\n";
           }
           else if (synchronization_status == 3)
           {
               AISMessage += " 即 臺站同步於另一個接受臺數量最多的臺站";
               AISMessage += "\r\n";
           }

           count_s = count_e + 1;     //提取完畢後,重置數據位起始值

           //提取時隙超時
           int TS_overtime;    //時隙超時

           digit_num = 3;           //時隙超時的位數爲3位
           count_e = count_s + digit_num - 1;   //計算數據終止位
           data_tr_valid = 0;

           for (i = count_s; i <= count_e; i++)
           {
               data_tr_bin = sum_binary[i];
               data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));                 
           }

           TS_overtime = data_tr_valid;

           AISMessage += "  時隙超時:  ";
           AISMessage += TS_overtime;

           if (TS_overtime == 0)
           {
               AISMessage += " 即 這是該時隙最後一次傳輸";
               AISMessage += "\r\n";
           }
           else
           {
               AISMessage += " 即 在時隙改變前將保留該時隙 ";
               AISMessage += TS_overtime;
               AISMessage += " 幀";
               AISMessage += "\r\n";
           }

           count_s = count_e + 1;     //提取完畢後,重置數據位起始值

           //提取子信息
           int child_information;    //子信息

           digit_num = 14;           //子信息的位數爲14位
           count_e = count_s + digit_num - 1;   //計算數據終止位
           data_tr_valid = 0;
    
           AISMessage += "  子信息:    ";

           if (TS_overtime == 3 || TS_overtime == 5 || TS_overtime == 7)
           {
               for (i = count_s; i <= count_e; i++)
               {
                   data_tr_bin = sum_binary[i];
                   data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));               
               }

               child_information = data_tr_valid;
   
               AISMessage += " 本臺當前接收到其他臺站數量爲:";
               AISMessage += child_information;
               AISMessage += "\r\n";
           }

           else if (TS_overtime == 2 || TS_overtime == 4 || TS_overtime == 6)
           {
               for (i = count_s; i <= count_e; i++)
               {
                   data_tr_bin = sum_binary[i];
                   data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));                      
               }

               child_information = data_tr_valid;

    
               AISMessage += " 用於該發射的時隙號爲:";
               AISMessage += child_information;
               AISMessage += "\r\n";
           }

           else if (TS_overtime == 1)
           {
               int UTC_hour;
               int UTC_min;          

               AISMessage += " UTC: ";

               for (i = count_s; i <= count_s + 4; i++)
               {
                   data_tr_bin = sum_binary[i];
                   data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_s + 4 - i));                      
               }

               UTC_hour = data_tr_valid;
               data_tr_valid = 0;

               AISMessage += UTC_hour;
               AISMessage += " 小時";

               count_s = count_s + 5;

               for (i = count_s; i <= count_s + 6; i++)
               {
                   data_tr_bin = sum_binary[i];
                   data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_s + 6 - i));                     
               }

               UTC_min = data_tr_valid;

               AISMessage += UTC_min;
               AISMessage += " 分";
               AISMessage += "\r\n";
           }

           else if (TS_overtime == 0)
           {
               for (i = count_s; i <= count_e; i++)
               {
                   data_tr_bin = sum_binary[i];
                   data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));                      
               }

               child_information = data_tr_valid;

               AISMessage += " 時隙偏移量爲:";
               AISMessage += child_information;
               AISMessage += "\r\n";
           }

           count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       }

       else if (conmunication_choose == 1)         //通信狀態爲ITDMA
       {

           AISMessage += "ITDMA通信狀態";
           AISMessage += "\r\n";

           //提取同步狀態
           int synchronization_status;    //同步狀態

           digit_num = 2;           //同步狀態的位數爲2位
           count_e = count_s + digit_num - 1;   //計算數據終止位
           data_tr_valid = 0;

           for (i = count_s; i <= count_e; i++)
           {
               data_tr_bin = sum_binary[i];
               data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));
               //printf("%d\n",data_tr_valid);
           }

           synchronization_status = data_tr_valid;

           AISMessage += "  同步狀態:  ";
           AISMessage += synchronization_status;

           if (synchronization_status == 0)
           {           
               AISMessage += " 即 直接獲取UTC";
               AISMessage += "\r\n";
           }
           else if (synchronization_status == 1)
           {
               AISMessage += " 即 間接獲取UTC";
               AISMessage += "\r\n";
           }
           else if (synchronization_status == 2)
           {
               AISMessage += " 即 臺站同步於基地臺";
               AISMessage += "\r\n";
           }
           else if (synchronization_status == 3)
           {
               AISMessage += " 即 臺站同步於另一個接受臺數量最多的臺站";
               AISMessage += "\r\n";
           }

           count_s = count_e + 1;     //提取完畢後,重置數據位起始值

           //提取時隙增量

           int TS_add;    //時隙增量

           digit_num = 13;           //時隙增量的位數爲13位
           count_e = count_s + digit_num - 1;   //計算數據終止位
           data_tr_valid = 0;

           for (i = count_s; i <= count_e; i++)
           {
               data_tr_bin = sum_binary[i];
               data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));                  
           }

           TS_add = data_tr_valid;

           AISMessage += "  時隙增量:  ";
           AISMessage += TS_add;

           if (TS_add == 0)
           {
               AISMessage += " 即 不在進行進一步的傳輸";
               AISMessage += "\r\n";
           }
           else
           {
               AISMessage += " 即 到下一個將要使用的時隙的偏移爲:";
               AISMessage += TS_add;
               AISMessage += "幀";
               AISMessage += "\r\n";
           }

           count_s = count_e + 1;     //提取完畢後,重置數據位起始值

           //提取時隙數
           int TS_num;    //時隙數

           digit_num = 3;           //時隙數的位數爲3位
           count_e = count_s + digit_num - 1;   //計算數據終止位
           data_tr_valid = 0;

           for (i = count_s; i <= count_e; i++)
           {
               data_tr_bin = sum_binary[i];
               data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));                  
           }

           TS_num = data_tr_valid;

           AISMessage += "  時隙數:   ";
           AISMessage += " 應分配的連續時隙的數量爲:";
           AISMessage += TS_num;
           AISMessage += "\r\n";

           count_s = count_e + 1;     //提取完畢後,重置數據位起始值

           //提取保持標記
           int maintain_marker;    //保持標記

           digit_num = 1;           //保持標記的位數爲1位
           count_e = count_s + digit_num - 1;   //計算數據終止位
           data_tr_valid = 0;

           for (i = count_s; i <= count_e; i++)
           {
               data_tr_bin = sum_binary[i];
               data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));                 
           }

           maintain_marker = data_tr_valid;

           AISMessage += "  保持標記:  ";
           AISMessage += maintain_marker;
           if (maintain_marker == 1)
               AISMessage += "  即 時隙分配應多保留一幀";
           AISMessage += "\r\n";

           count_s = count_e + 1;   //提取完畢後,重置數據位起始值

       }

       /*
       //僅提取“通信狀態”數值

       for(i=count_s;i<=count_e;i++)   
       {
           data_tr_bin=s[i];
           data_tr_valid =data_tr_valid+(data_tr_bin-'0')*(int)(Math.Pow(2,count_e-i));	
           //printf("%d\n",data_tr_valid);
       }

       fprintf(w18,"%s","通信狀態:  ");
       fprintf(w18,"%d",data_tr_valid);
           fprintf(w18,"%s","\n");

       count_s=count_e+1;     //提取完畢後,重置數據位起始值

   */

   // END(提取通信狀態)

    
   
   //if (MMSI_OUT == temp_MMSI)                      //如果該條信息是選中的用戶船舶信息,則可進行參數提取和方位計算
   if (sen_f == 2)
   {         
       AISMessage += "\r\n";
       AISMessage += "該條信息是選中的用戶船舶信息,可進行參數提取和方位計算";

       MMSI_enable = 1;
       
       //textBox5.Clear();
       //textBox5.Text = MMSI_OUT;

       temp1 = String.valueOf(speed_over_ground);
       //textBox19.Clear();
      // textBox19.Text = temp1;

       temp2 = String.valueOf(RecentLongitude);
       //temp2 = RecentLongitude.ToString();
       //textBox22.Clear();                          //清空“船舶信息顯示的經度”窗口                
      // textBox22.Text = temp2;
       ShipLongitude = RecentLongitude;

       temp3 = String.valueOf(RecentLatitude);
       //temp3 = RecentLatitude.ToString();
       //textBox20.Clear();                          //清空“船舶信息顯示的緯度”窗口
       //textBox20.Text = temp3;
       ShipLatitude = RecentLatitude;

       RecentCourse = course_over_the_ground;        //將對地航向信息傳遞給全局變量
       //RecentCourse=true_course;					  //將真航向信息傳遞給全局變量

       if (RecentCourse >= 0 && RecentCourse < 360)
       {
           temp4 = String.valueOf(RecentCourse);
       }

       else
       {
           RecentCourse = 0;                           //當航向信息不可用時,則指向角的計算將不考慮航向信息
           temp4 = "不可用";
       }
       /*
               if(RecentCourse!=511)
               {
                   temp4.Format( "%d",RecentCourse);
               }

               else
               {
                   RecentCourse=0;	
                   temp4="不可用";
               }

       */

       //textBox21.Clear();          //清空“船舶信息顯示的真航向”窗口
       //textBox21.Text = temp4;                               
   }

   else if (MMSI_OUT == temp_BaseShipMMSI)             //如果該條信息是跟蹤的基站船舶信息,則可進行參數提取和方位計算
   {          
       AISMessage += "\r\n";
       AISMessage += "該條信息是跟蹤的基站船舶信息,則可進行參數提取和方位計算";

       MMSI_enable = 2;

       temp2 = String.valueOf(RecentLongitude);
       //temp2 = RecentLongitude.ToString();
       //textBox17.Clear();                          //清空“船載基站信息顯示的經度”窗口               
       //textBox17.Text = temp2;
       BaseLongitude = RecentLongitude;

       temp3 =String.valueOf(RecentLatitude);
       //temp3 = RecentLatitude.ToString();
       //textBox15.Clear();                          //清空“船載基站信息顯示的緯度”窗口
       //textBox15.Text = temp3;
       BaseLatitude = RecentLatitude;

   }

   else                                                //如果該條語句不是選中船舶(用戶船或基站船)的信息,則無需進行參數提取和方位計算     
   {       
       AISMessage += "\r\n";
       AISMessage += "該條信息不是選中的船舶信息,無需進行方位計算";

       MMSI_enable = 0;
   }
   AISLog.logInfo(AIS_Analyse.class, "Analysie18,"+"經度:"+RecentLongitude+",緯度:"+RecentLatitude+",mmsi:"+MMSI+",航速:"+boat.getCog()+",航向:"+boat.getSog());
   System.out.println("經度:"+RecentLongitude+",緯度:"+RecentLatitude+",mmsi:"+MMSI);
   boat.setLongitude(String.valueOf(RecentLongitude));
   boat.setLatitude(String.valueOf(RecentLatitude));
   boat.setMmsiId(String.valueOf(MMSI));
   BoatData(boat);
   System.out.println(AISMessage);
   //textBox3.Text += AISMessage;
}

    /**船舶經緯度是否改變*/ 
     public static Boolean PlaceChange(Boat boat,String Longtitude,String Latitude){
    	 if(!Longtitude.equals(boat.getLongitude())||!Latitude.equals(boat.getLatitude())){
    		 return true;
    	 } else {
    		 return false;
    	 }
     }
     
   /**判斷是否是新船*/
     public static Boolean NewBoat(Boat boat){
    	 List<Boat> nowBoatList = boatMapper.getAllBoat();
    	 if(nowBoatList!=null){
    		 for(Boat boatx:nowBoatList){
        		 if(boat.getMmsiId().equals(boatx.getMmsiId())){
        			 return false;
        		 }
        	 } 
    	 } else{
    		 System.out.print("沒有船隻");
    		 return true;
    	 }
    	
    	 return true;
     }
     
   /**船舶數據入庫*/
     public static void BoatData(String Longitude,String Latitude,String MMSI){
    	 Boat boat = new Boat();
    	 boat.setLatitude(Latitude);
    	 boat.setLongitude(Longitude);
    	 boat.setMmsiId(MMSI);
    	 boat.setId(MiscUtil.getUUID());
    	 boat.setStatus("1");
    	 if(NewBoat(boat)){
    		 Msg msg = boatService.insert(boat);
    		 System.out.print(msg.getMsg());
    	 } else {
    		 boat = boatMapper.selectByMMSI(MMSI);
    		 if(PlaceChange(boat, Longitude, Latitude)){
    			 boat.setLongitude(Longitude);
    			 boat.setLatitude(Latitude);
    			 int result =   boatService.updateByPrimaryKey(boat); 
    			 System.out.print(result);
    		 } else {
    			 System.out.print("位置沒有改變");
    		 }	 
    	 }
     }
     /**船舶數據入庫*/
     public static void BoatData(Boat boat){
    	 Boat boat2 = new Boat();
    	 boat2.setLatitude(boat.getLatitude());
    	 boat2.setLongitude(boat.getLongitude());
    	 boat2.setMmsiId(boat.getMmsiId());
    	 boat2.setId(MiscUtil.getUUID());
    	 boat2.setStatus("1");
    	 boat2.setCog(boat.getCog());
    	 boat2.setSog(boat.getSog());
    	 if(NewBoat(boat2)){
    		 Msg msg = boatService.insert(boat2);
    		 System.out.print(msg.getMsg());
    		 Msg msg2 = boatHistoryService.insert(boat2);
    		 System.out.print(msg2.getMsg());
    	 } else {
    		 boat = boatMapper.selectByMMSI(boat.getMmsiId());
    		 boat.setCog(boat2.getCog());
    		 boat.setSog(boat2.getSog());
    		 boat.setLatitude(boat.getLongitude());
    		 boat.setLatitude(boat.getLatitude());
    		 Msg msg2 = boatHistoryService.insert(boat);
    		 System.out.print(msg2.getMsg());
    		 boatMapper.updateByPrimaryKey(boat);
    		 /*if(PlaceChange(boat, boat.getLongitude(), boat.getLatitude())){
    			 boat.setLongitude(boat.getLongitude());
    			 boat.setLatitude(boat.getLatitude());
    			 int result =   boatService.updateByPrimaryKey(boat); 
    			 System.out.print(result);
    		 } else {
    			 System.out.print("位置沒有改變");
    		 }	 */
    	 }
     }
   
   /**消息19數據解析*/
   public static void Data_analyze_m19(String AISMessage)        //消息19數據解析
   {
       int i=0, j=0;
       Boat boat = new Boat(); 
       String temp1;
       String temp2;
       String temp3;
       String temp4;

      // String AISMessage = null;

       String MMSI_OUT;
       String temp_MMSI;
       String temp_BaseShipMMSI = null;
       MMSI_enable = 0;

       //temp_MMSI = textBox5.Text;                          //讀取目前跟蹤的用戶船MMSI碼
       //temp_BaseShipMMSI = textBox18.Text;                  //讀取當前基站船的MMSI碼

       AISMessage += "\r\n\r\n";
       AISMessage += "解析後的數據如下:\r\n\r\n";

       // 二進制數據向有效數據轉換

       char data_tr_bin = 0;       //二進制數據中間變量初始化
       int data_tr_valid = 0;    //有效數據中間變量初始化
       int count_s = 0;          //數據位起
       // 提取消息識別碼

       int message_identifier;  //消息識別碼

       int digit_num = 6;           //消息識別碼的位數爲6位
       int  count_e = count_s + digit_num - 1;   //計算數據終止位

       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));
       }

       message_identifier = data_tr_valid;

       if (message_identifier == 19)
       {       
           AISMessage += "消息識別碼:  ";
           AISMessage += message_identifier;
           AISMessage += "  即 消息類型爲“擴展B類設備位置報告”。\r\n";
       }

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取消息識別碼)

       // 提取轉發指示符

       int transpond_indicate;   //轉發指示符

        digit_num = 2;           //轉發指示符的位數爲2位
         count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));
       }

       transpond_indicate = data_tr_valid;

       AISMessage += "轉發指示符:  ";
       AISMessage += transpond_indicate;
       AISMessage += "  即 該條消息被轉發的次數爲:";
       AISMessage += transpond_indicate;
       AISMessage += "  次。\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取轉發指示符)

       // 提取用戶識別碼,即MMSI碼

       int MMSI;     //用戶識別碼

       digit_num = 30;           //用戶識別碼,即MMSI碼的位數爲30位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));               
       }

       MMSI = data_tr_valid;

       AISMessage += "用戶識別碼(即MMSI碼):  ";
       AISMessage += MMSI;
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       MMSI_OUT = String.valueOf(MMSI);                             //提取當前信息的MMSI碼,用於船舶識別

       // END(提取用戶識別碼,即MMSI碼)

       // 提取爲地區或區域應用保留

       digit_num = 8;           //爲地區或區域應用保留的位數爲8位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));            
       }

       AISMessage += "爲地區性應用所保留:  ";
       AISMessage += data_tr_valid;
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取爲地區或區域應用保留)

       // 提取對地航速

       double speed_over_ground;     //對地航速

       digit_num = 10;           //對地航速的位數爲10位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;

       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));              
       }
    
       speed_over_ground = (float)(data_tr_valid) / 10;

       AISMessage += "對地航速:  ";
       AISMessage += speed_over_ground;
       boat.setSog(speed_over_ground+"kn");
       AISMessage += " kn";
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取對地航速)

       // 提取船位精確度

       int position_accuracy;     //船位精確度

       digit_num = 1;           //船位精確度的位數爲1位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));          
       }

       position_accuracy = data_tr_valid;

       AISMessage += "船位精確度:  ";
       AISMessage += position_accuracy;
       if (data_tr_valid == 1)
           AISMessage += " 即 高精度(<10m,DGNSS接收機的差分模式)";
       else if (data_tr_valid == 0)
           AISMessage += " 即 低精度(>10m,GNSS接收機或其他電子定位裝置的自主模式)";
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取船位精確度)

       // 提取經度

       double longitude;      //經度

       digit_num = 28;           //經度的位數爲28位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;

       int hour;
       int minute;
       double second;

       if (sum_binary[count_s] != '1')
       {
           //("經度是正數,即東經\n");
           for (i = count_s; i <= count_e; i++)
           {
               data_tr_bin = sum_binary[i];
               data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));
               //System.out.print("原始經度數據:"+data_tr_valid);
           }

           longitude = (float)(data_tr_valid) / 10000;
     
           hour = (int)(data_tr_valid / 10000 / 60);

           minute = (int)(longitude - hour * 60);

           second = (longitude - hour * 60 - minute) * 60;

           RecentLongitude = longitude / 60;  //將經度信息傳遞給全局變量,單位爲度

           AISMessage += "經度:  ";
           AISMessage += "東經 ";
           AISMessage += hour;
           AISMessage += "度";
           AISMessage += hour;
           AISMessage += "分";
           AISMessage += second;
           AISMessage += "秒";
           AISMessage += "\r\n";
    
       }

       else if (sum_binary[count_s] == '1')
       {
           //("經度是負數,即西經\n");
           for (i = count_s + 1; i <= count_e; i++)
           {
               if (sum_binary[i] == '0')
                   data_tr_bin = '1';
               else
                   data_tr_bin = '0';

               data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));
               //System.out.print("原始經度數據:"+data_tr_valid);
           }
           data_tr_valid = data_tr_valid + 1;  //經度的絕對值
         
           longitude = (float)(data_tr_valid) / 10000;
          
           hour = (int)(data_tr_valid / 10000 / 60);
        
           minute = (int)(longitude - hour * 60);
        
           second = (longitude - hour * 60 - minute) * 60;

           longitude = -longitude;      //經度的真實值  
                                   
           RecentLongitude = longitude / 60;  //將經度信息傳遞給全局變量

           AISMessage += "經度:  ";
           AISMessage += "西經 ";
           AISMessage += hour;
           AISMessage += "度";
           AISMessage += minute;
           AISMessage += "分";
           AISMessage += second;
           AISMessage += "秒";
           AISMessage += "\r\n";
       }

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取經度)

       // 提取緯度

       double latitude;    //緯度

       digit_num = 27;           //緯度的位數爲27位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
       System.out.print("18經度終止位數,count_e:" + count_e+ ",count_s:"+ count_s + ",data_tr_bin" + data_tr_bin);
       if (sum_binary[count_s] != '1')
       {
           //("緯度是正數,即北緯\n");
           for (i = count_s; i <= count_e; i++)
           {
               data_tr_bin = sum_binary[i];
               data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));      
              
           }           
           latitude = (float)(data_tr_valid) / 10000;
        
           hour = (int)(data_tr_valid / 10000 / 60);
     
           minute = (int)(latitude - hour * 60);
    
           second = (latitude - hour * 60 - minute) * 60;

           RecentLatitude = latitude / 60;    //將當前緯度傳遞給全局變量

           AISMessage += "緯度:  ";
           AISMessage += "北緯 ";
           AISMessage += hour;
           AISMessage += "度";
           AISMessage += minute;
           AISMessage += "分";
           AISMessage += second;
           AISMessage += "秒";
           AISMessage += "\r\n";
       }

       else if (sum_binary[count_s] == '1')
       {
           //("緯度是負數,即南緯\n");
           for (i = count_s + 1; i <= count_e; i++)
           {
               if (sum_binary[i] == '0')
                   data_tr_bin = '1';
               else
                   data_tr_bin = '0';

               data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));
               //System.out.print("原始經度數據:"+data_tr_valid);
           }

           data_tr_valid = data_tr_valid + 1;  //緯度的絕對值
                                        
           latitude = (float)(data_tr_valid) / 10000;
         
           hour = (int)(data_tr_valid / 10000 / 60);
         
           minute = (int)(latitude - hour * 60);
          
           second = (latitude - hour * 60 - minute) * 60;

           latitude = -latitude;      //緯度的真實值  
                                    
           RecentLatitude = latitude / 60;    //將當前緯度傳遞給全局變量

           AISMessage += "緯度:  ";
           AISMessage += "北緯 ";
           AISMessage += hour;
           AISMessage += "度";
           AISMessage += minute;
           AISMessage += "分";
           AISMessage += second;
           AISMessage += "秒";
           AISMessage += "\r\n";
       }


       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取緯度)

       // 提取對地航向

       double course_over_the_ground;

       digit_num = 12;           //對地航向的位數爲12位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;

       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));              
       }

       course_over_the_ground = (float)(data_tr_valid) / 10;

       AISMessage += "對地航向:  ";
       AISMessage += course_over_the_ground;
       boat.setCog(course_over_the_ground+"度");
       AISMessage += "度";
       if (course_over_the_ground >= 360)
           AISMessage += " 即 默認值(不可用)";
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取對地航向)

       // 提取真航向

       int true_course;     //真航向

       digit_num = 9;           //真航向的位數爲9位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;

       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));            
       }

       true_course = data_tr_valid;

       AISMessage += "真航向:  ";
       AISMessage += true_course;
       AISMessage += "度";
       if (true_course == 511)
           AISMessage += " 即 默認值(不可用)";
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取真航向)

       // 提取時間標記

       int time_marker;    //時間標記

       digit_num = 6;           //時間標記的位數爲6位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));            
       }

       time_marker = data_tr_valid;

       AISMessage += "時間標記:  ";
       AISMessage += "報告產生時的UTC秒: ";
       AISMessage += time_marker;
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取時間標記)

       // 提取爲地區性應用所保留

       digit_num = 4;           //爲地區性應用所保留的位數爲4位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));               
       }

       AISMessage += "爲地區性應用所保留:  ";
       AISMessage += data_tr_valid;
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取爲地區性應用所保留)

       // 提取名稱

       char ASC_trans;                //ASC碼轉換中間變量

       digit_num = 120;           //名稱的位數爲120位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
    
       AISMessage += "名稱:  ";

       for (i = count_s; i <= count_e; i++)
       {
           for (j = 0; j < 6; j++)
           {
               data_tr_bin = sum_binary[i + j];
               data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, 5 - j));                  
           }

           ASC_trans = six_to_eight_ASC(data_tr_valid);
           data_tr_valid = 0;

           AISMessage += ASC_trans;

           i = i + 5;
       }
 
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取名稱)

       // 提取船舶及載貨類型

       int ship_type;
       int ship_type_A;       //船舶類型的第一個字符
       int ship_type_B;       //船舶類型的第二個字符

       digit_num = 8;           //船舶及載貨類型的位數爲8位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));               
       }

       ship_type = data_tr_valid;

       AISMessage += "船舶及載貨類型:  ";
       AISMessage += ship_type;

       ship_type_A = (int)(ship_type / 10);
       ship_type_B = ship_type - ship_type_A * 10;

       if (ship_type_A == 5)
       {
           switch (ship_type)
           {
               case 50:                      
                   AISMessage += " 即 領航船";
                   break;
               case 51:
                   AISMessage += " 即 搜救船";
                   break;
               case 52:
                   AISMessage += " 即 拖輪";
                   break;
               case 53:
                   AISMessage += " 即 港口供應船";
                   break;
               case 54:
                   AISMessage += " 即 載有防污染裝置和設備的船舶";
                   break;
               case 55:
                   AISMessage += " 即 執法船";
                   break;
               case 56:
                   AISMessage += " 即 備用一分配給當地船舶使用";
                   break;
               case 57:
                   AISMessage += " 即 備用一分配給當地船舶使用";
                   break;
               case 58:
                   AISMessage += " 即 醫療船(如1949年日內瓦公約及附加條款所規定)";
                   break;
               case 59:
                   AISMessage += " 即 符合《無線電規則》第18號決議(Mob-83)的船舶";
                   break;
               default:
                   break;
           }
       }

       if (ship_type_A == 3)
       {
           switch (ship_type_B)
           {
               case 0:
                   AISMessage += " 即 從事捕魚的船舶";
                   break;
               case 1:
                   AISMessage += " 即 從事拖帶作業的船舶";
                   break;
               case 2:
                   AISMessage += " 即 從事拖帶作業,且拖帶長度超過200m,或寬度超過25m的船舶";
                   break;
               case 3:
                   AISMessage += " 即 從事疏浚或水下作業的船舶";
                   break;
               case 4:
                   AISMessage += " 即 從事潛水作業的船舶";
                   break;
               case 5:
                   AISMessage += " 即 參與軍事行動的船舶";
                   break;
               case 6:
                   AISMessage += " 即 駛帆航行的船舶";
                   break;
               case 7:
                   AISMessage += " 即 娛樂船";
                   break;
               case 8:
                   AISMessage += " 即 爲將來使用保留";
                   break;
               case 9:
                   AISMessage += " 即 爲將來使用保留";
                   break;
               default:
                   break;
           }
       }

       switch (ship_type_A)
       {
           case 1:
               AISMessage += " 即 爲將來使用保留";
               break;
           case 2:
               AISMessage += " 即 地效應船";
               break;
           case 4:
               AISMessage += " 即 高速船";
               break;
           case 6:
               AISMessage += " 即 客船";
               break;
           case 7:
               AISMessage += " 即 貨船";
               break;
           case 8:
               AISMessage += " 即 油輪";
               break;
           case 9:
               AISMessage += " 即 其他類型的船舶";
               break;
           default:
               break;
       }

       if (ship_type_A != 3 && ship_type_A != 5)
       {
           switch (ship_type_B)
           {
               case 0:
                   AISMessage += " 這一類型的所有船舶";
                   break;
               case 1:
                   AISMessage += " 載有危險品(DG),有害物質(HS)或海上污染物,屬IMO規定的A類有害或污染物質";
                   break;
               case 2:
                   AISMessage += " 載有危險品,有害物質或海上污染物(MP),屬IMO規定的B類有害或污染物質";
                   break;
               case 3:
                   AISMessage += " 載有危險品,有害物質或海上污染物,屬IMO規定的C類有害或污染物質";
                   break;
               case 4:
                   AISMessage += " 載有危險品,有害物質或海上污染物,屬IMO規定的D類有害或污染物質";
                   break;
               case 9:
                   AISMessage += " 無附加信息";
                   break;
               default:
                   AISMessage += " 爲將來使用保留";
                   break;
           }
       }
                
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取船舶及載貨類型)

       // 提取船舶尺度/位置參照

       int ship_size_A;
       int ship_size_B;
       int ship_size_C;
       int ship_size_D;

       digit_num = 30;           //船舶尺度/位置參照的位數爲30位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
                
       AISMessage += "船舶尺度/位置參照:  ";

       for (i = count_s; i <= (count_s + 8); i++)
       {
           data_tr_bin = sum_binary[i];              
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, 8 + count_s - i));          
       }

       ship_size_A = data_tr_valid;
   
       count_s = count_s + 9;
       data_tr_valid = 0;

       AISMessage += "距船首 ";
       AISMessage += ship_size_A;
       AISMessage += " m;";

       for (i = count_s; i <= (count_s + 8); i++)
       {
           data_tr_bin = sum_binary[i];              
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, 8 + count_s - i));               
       }

       ship_size_B = data_tr_valid;
       count_s = count_s + 9;
       data_tr_valid = 0;

       AISMessage += "距船尾 ";
       AISMessage += ship_size_B;
       AISMessage += " m;";

       for (i = count_s; i <= (count_s + 5); i++)
       {
           data_tr_bin = sum_binary[i];             
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, 5 + count_s - i));        
       }

       ship_size_C = data_tr_valid;
       count_s = count_s + 6;
       data_tr_valid = 0;

       AISMessage += "距左舷 ";
       AISMessage += ship_size_C;
       AISMessage += " m;";

       for (i = count_s; i <= (count_s + 5); i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, 5 + count_s - i));            
       }

       ship_size_D = data_tr_valid;

       AISMessage += "距右舷 ";
       AISMessage += ship_size_D;
       AISMessage += " m;";
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取船舶尺度/位置參照)

       // 提取電子定位裝置類型

       int locate_type;

       digit_num = 4;           //電子定位裝置類型的位數爲4位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));          
       }

       locate_type = data_tr_valid;

       AISMessage += "電子定位裝置類型:  ";
       AISMessage += locate_type;

       switch (locate_type)
       {
           case 0:
               AISMessage += " 即 未定義(預設)";
               break;
           case 1:
               AISMessage += " 即 GPS";
               break;
           case 2:
               AISMessage += " 即 GLONASS";
               break;
           case 3:
               AISMessage += " 即 組合 GPS/GLONASS";
               break;
           case 4:
               AISMessage += " 即 羅蘭";
               break;
           case 5:
               AISMessage += " 即 Chayka";
               break;
           case 6:
               AISMessage += " 即 綜合導航系統";
               break;
           case 7:
               AISMessage += " 即 觀測";
               break;
           default:
               AISMessage += " 即 不用";
               break;
       }

       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取電子定位裝置類型)

       // 提取RAIM標誌

       int RAIM;     //RAIM標誌

       digit_num = 1;           //RAIM標誌的位數爲1位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));           
       }

       RAIM = data_tr_valid;

       AISMessage += "RAIM標誌:  ";
       AISMessage += RAIM;
       if (RAIM == 1)
           AISMessage += " 即 RAIM使用";
       else
           AISMessage += " 即 RAIM未使用(默認)";
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取RAIM標誌)

       // 提取數據終端設備指示符

       int data_sys;

       digit_num = 1;           //數據終端設備指示符的位數爲1位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));
           //System.out.print("原始經度數據:"+data_tr_valid);
       }

       data_sys = data_tr_valid;

       AISMessage += "數據終端設備指示符:  ";
       AISMessage += data_sys;
       if (data_sys == 0)
           AISMessage += " 即 數據終端設備可用";
       else
           AISMessage += " 即 數據終端設備不可用(默認)";
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取數據終端設備指示符)

       // 提取備用位

       digit_num = 5;           //備用位的位數爲1位
       count_e = count_s + digit_num - 1;   //計算數據終止位
       data_tr_valid = 0;
       for (i = count_s; i <= count_e; i++)
       {
           data_tr_bin = sum_binary[i];
           data_tr_valid = data_tr_valid + (data_tr_bin - '0') * (int)(Math.pow(2, count_e - i));               
       }

       AISMessage += "備用位:  ";
       AISMessage += data_tr_valid;
       AISMessage += "\r\n";

       count_s = count_e + 1;     //提取完畢後,重置數據位起始值

       // END(提取備用位)

       //if (MMSI_OUT == temp_MMSI)                      //如果該條信息是選中的用戶船舶信息,則可進行參數提取和方位計算
       if (sen_f == 2)
       {        
           AISMessage += "\r\n";
           AISMessage += "該條信息是選中的用戶船舶信息,可進行參數提取和方位計算";

           MMSI_enable = 1;

           //textBox5.Clear();
           //textBox5.Text = MMSI_OUT;

           temp1 = String.valueOf(speed_over_ground);
           //textBox19.Clear();
           //textBox19.Text = temp1;

           temp2 = String.valueOf(RecentLongitude);
           //temp2 = RecentLongitude.ToString();
           //textBox22.Clear();                          //清空“船舶信息顯示的經度”窗口                
          // textBox22.Text = temp2;
           ShipLongitude = RecentLongitude;

           temp3 = String.valueOf(RecentLatitude);
           //temp3 = RecentLatitude.ToString();
           //textBox20.Clear();                          //清空“船舶信息顯示的緯度”窗口
           //textBox20.Text = temp3;
           ShipLatitude = RecentLatitude;


           RecentCourse = course_over_the_ground;        //將對地航向信息傳遞給全局變量
           //RecentCourse=true_course;					  //將真航向信息傳遞給全局變量

           if (RecentCourse >= 0 && RecentCourse < 360)
           {
               temp4 = String.valueOf(RecentCourse);
           }

           else
           {
               RecentCourse = 0;                           //當航向信息不可用時,則指向角的計算將不考慮航向信息
               temp4 = "不可用";
           }
           /*
                   if(RecentCourse!=511)
                   {
                       temp4.Format( "%d",RecentCourse);
                   }

                   else
                   {
                       RecentCourse=0;	
                       temp4="不可用";
                   }

           */

           //textBox21.Clear();          //清空“船舶信息顯示的真航向”窗口
           //textBox21.Text = temp4;
           
       }

       else if (MMSI_OUT == temp_BaseShipMMSI)             //如果該條信息是跟蹤的基站船舶信息,則可進行參數提取和方位計算
       {
    
           AISMessage += "\r\n";
           AISMessage += "該條信息是跟蹤的基站船舶信息,則可進行參數提取和方位計算";

           MMSI_enable = 2;

           temp2 = String.valueOf(RecentLongitude);
           //temp2 = RecentLongitude.ToString();
           //textBox17.Clear();                          //清空“船載基站信息顯示的經度”窗口               
           //textBox17.Text = temp2;
           BaseLongitude = RecentLongitude;

           temp3 = String.valueOf(RecentLatitude);
           //temp3 = RecentLatitude.ToString();
           //textBox15.Clear();                          //清空“船載基站信息顯示的緯度”窗口
           //textBox15.Text = temp3;
           BaseLatitude = RecentLatitude;

       }

       else                                                //如果該條語句不是選中船舶(用戶船或基站船)的信息,則無需進行參數提取和方位計算     
       {      
           AISMessage += "\r\n";
           AISMessage += "該條信息不是選中的船舶信息,無需進行方位計算";

           MMSI_enable = 0;
       }
       AISLog.logInfo(AIS_Analyse.class, "Analysie19,"+"經度:"+RecentLongitude+",緯度:"+RecentLatitude+",mmsi:"+MMSI+",航速:"+boat.getCog()+",航向:"+boat.getSog());
       System.out.println("經度:"+RecentLongitude+",緯度:"+RecentLatitude+",mmsi:"+MMSI);
       boat.setLongitude(String.valueOf(RecentLongitude));
       boat.setLatitude(String.valueOf(RecentLatitude));
       boat.setMmsiId(String.valueOf(MMSI));
       BoatData(boat);
       System.out.println(AISMessage);
   }
   
   /**ASC碼轉換函數*/
   public static char six_to_eight_ASC(int t)        
   {
       char code = '\0';

       switch (t)
       {
           case 0:
               code = '@';
               break;
           case 1:
               code = 'A';
               break;
           case 2:
               code = 'B';
               break;
           case 3:
               code = 'C';
               break;
           case 4:
               code = 'D';
               break;
           case 5:
               code = 'E';
               break;
           case 6:
               code = 'F';
               break;
           case 7:
               code = 'G';
               break;
           case 8:
               code = 'H';
               break;
           case 9:
               code = 'I';
               break;
           case 10:
               code = 'J';
               break;
           case 11:
               code = 'K';
               break;
           case 12:
               code = 'L';
               break;
           case 13:
               code = 'M';
               break;
           case 14:
               code = 'N';
               break;
           case 15:
               code = 'O';
               break;
           case 16:
               code = 'P';
               break;
           case 17:
               code = 'Q';
               break;
           case 18:
               code = 'R';
               break;
           case 19:
               code = 'S';
               break;
           case 20:
               code = 'T';
               break;
           case 21:
               code = 'U';
               break;
           case 22:
               code = 'V';
               break;
           case 23:
               code = 'W';
               break;
           case 24:
               code = 'X';
               break;
           case 25:
               code = 'Y';
               break;
           case 26:
               code = 'Z';
               break;
           case 27:
               code = ' ';
               break;
           case 28:
               code = ' ';
               break;
           case 29:
               code = ' ';
               break;
           case 30:
               code = '^';
               break;
           case 31:
               code = '_';
               break;
           case 32:
               code = ' ';
               break;
           case 33:
               code = '!';
               break;
           case 34:
               code = '“';
               break;
           case 35:
               code = '#';
               break;
           case 36:
               code = '$';
               break;
           case 37:
               code = '%';
               break;
           case 38:
               code = '&';
               break;
           case 39:
               code = '‘';
               break;
           case 40:
               code = '(';
               break;
           case 41:
               code = ')';
               break;
           case 42:
               code = '*';
               break;
           case 43:
               code = '+';
               break;
           case 44:
               code = ',';
               break;
           case 45:
               code = '—';
               break;
           case 46:
               code = '.';
               break;
           case 47:
               code = '/';
               break;
           case 48:
               code = '0';
               break;
           case 49:
               code = '1';
               break;
           case 50:
               code = '2';
               break;
           case 51:
               code = '3';
               break;
           case 52:
               code = '4';
               break;
           case 53:
               code = '5';
               break;
           case 54:
               code = '6';
               break;
           case 55:
               code = '7';
               break;
           case 56:
               code = '8';
               break;
           case 57:
               code = '9';
               break;
           case 58:
               code = ':';
               break;
           case 59:
               code = ';';
               break;
           case 60:
               code = '<';
               break;
           case 61:
               code = '=';
               break;
           case 62:
               code = '>';
               break;
           case 63:
               code = '?';
               break;
           default:
               break;
       }

       return code;
   }
}
   
   
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章