利用串口解析AIS接收机数据

串口:
串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方式的扩展接口。串行接口 (Serial Interface) 是指数据一位一位地顺序传送,其特点是通信线路简单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线),从而大大降低了成本,特别适用于远距离通信,但传送速度较慢。

AIS接收机
船舶自动识别系统,是指一种应用于船和岸、船和船之间的海事安全与通信的新型助航系统。常由VHF通信机、GPS定位仪和与船载显示器及传感器等相连接的通信控制器组成,能自动交换船位、航速、航向、船名、呼号等重要信息。装在船上的AIS在向外发送这些信息的同时,同样接收VHF覆盖范围内其他船舶的信息,从而实现了自动应答。此外,作为一种开放式数据传输系统,它可与雷达、ARPA、ECDIS、VTS等终端设备和INTERNET实现连接,构成海上交管和监视网络,是不用雷达探测也能获得交通信息的有效手段,可以有效减少船舶碰撞事故。

GitHub源码:https://github.com/Phoenixsmf/AIS

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 findPorts() {
		// 获得当前所有可用串口
		Enumeration portList = CommPortIdentifier.getPortIdentifiers();
		ArrayList portNameList = new ArrayList();
		// 将可用串口名添加到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 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 _buff = new ArrayList();
	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 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;
   }
}
   
   

你可能感兴趣的:(通信)