北斗卫星定位GPS解析全过程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/P923284735/article/details/89643291

解析工具类

package com.jeesite.modules.utils;

import java.text.DecimalFormat;
import org.apache.commons.lang.StringUtils;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;

/**
 * @Desc 解析GPS发送数据工具类
 * @author PGQing
 */
@Slf4j
public class HexMathUtils {

	/**
	 * @Desc 1.将收到的GPS定位数据解析成JSON格式
	 * @param hex
	 * @return
	 * @throws Exception
	 */
	public static JSONObject formatHexStr(String hexStr) throws Exception {
		log.info("准备解析的数据:\n" + hexStr);
		JSONObject result = new JSONObject();
		try {
			if (StringUtils.isNotBlank(hexStr) && hexStr.replaceAll(" ", "").length() == 110) {
				JSONObject info = new JSONObject();
				// 去空
				String content = hexStr.replaceAll(" ", "");
				// 长度
				info.put("length", content.getBytes("UTF-8").length / 2);
				// 消息头
				info.put("head", content.substring(0, 2));
				// 消息长度
				info.put("length", content.substring(2, 4));
				// 消息ID
				info.put("id", content.substring(4, 6));
				// 设备编号
				info.put("no", content.substring(6, 14));
				// 消息体
				info.put("body", content.substring(14, 106));
				// 校验位
				info.put("bit", content.substring(106));
				// 解析设备编号、消息体
				result = formatJSONObject(info);
				log.info("解析数据为:\n" + result.toJSONString());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * @Desc 2.解析消息体以及设备编号信息
	 * @param hexObj
	 * @return
	 */
	public static JSONObject formatJSONObject(JSONObject hexObj) {
		JSONObject obj = new JSONObject();
		try {
			if (!hexObj.isEmpty()) {
				// 解析设备编号
				String no = hexObj.getString("no");
				if (StringUtils.isNotBlank(no)) {
					long sbbh = Long.parseLong(no, 16);// 16进制转换为10进制
					no = String.valueOf(sbbh);
					String endStr = "";
					// 如果不够10位,最高位补0
					for (int i = 0; i < 10 - no.length(); i++) {
						endStr += "0";
					}
					no = "CNTL" + endStr + no;
					obj.put("no", no);
				}
				// 解析消息体
				String body = hexObj.getString("body");
				if (StringUtils.isNotBlank(body)) {
					JSONObject bodyObj = formatHexBodyStr(body);
					obj.put("body", bodyObj);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return obj;
	}

	/**
	 * @Desc 3.解析消息体中的经纬度、设备报警信息
	 * @param hex
	 * @return
	 */
	public static JSONObject formatHexBodyStr(String hexBodyStr) {
		JSONObject result = new JSONObject();
		try {
			if (StringUtils.isNotBlank(hexBodyStr)) {
				// 去空
				String content = hexBodyStr.replaceAll(" ", "");
				// 解析设备状态及报警信息
				String msg1 = content.substring(0, 2);
				int msgResult1 = Integer.parseInt(msg1, 16);// 16进制转换为10进制
				msg1 = Integer.toBinaryString(msgResult1);// 10进制转换为2进制
				String msg2 = content.substring(2, 4);
				int msgResult2 = Integer.parseInt(msg2, 16);
				msg2 = Integer.toBinaryString(msgResult2);
				result.put("msg", msg1 + msg2);
				// 纬度
				String lng = content.substring(2 * 2, 2 * 2 + 8);
				// 度
				int a = Integer.parseInt(lng.substring(0, 2), 16);// 首位,16进制转换为10进制为度
				// 分
				int a1 = Integer.parseInt(lng.substring(2, 4), 16);// 分,第1位
				int a2 = Integer.parseInt(lng.substring(4, 6), 16);// 分,第2位
				int a3 = Integer.parseInt(lng.substring(6, 8), 16);// 分,第3位
				// 将分转换为度
				double a4 = Double.parseDouble("0." + addZero(a1) + addZero(a2) + addZero(a3));
				int a5 = new Double(String.valueOf(a4 * 1000000)).intValue();
				DecimalFormat df = new DecimalFormat("0.00");
				String a6 = df.format((float) a5 / 60);
				String a7 = String.valueOf((int) (new Double(a6) * 100));
				// 补位
				for(int j=0;j<(6-a7.length());j++) {
					a7 = "0"+a7;
				}
				String tempLng = String.valueOf(a) + "." + a7;
				result.put("lat", tempLng);

				// 经度
				String lat = content.substring(6 * 2, 6 * 2 + 10);
				// 度
				int c = Integer.parseInt(lat.substring(0, 2), 16);// 第1个字节,16进制转换为10进制为度
				int d = Integer.parseInt(lat.substring(2, 4), 16);// 第2个字节,16进制转换为10进制为度
				// 分
				int d1 = Integer.parseInt(lat.substring(4, 6), 16);// 分,第1位
				int d2 = Integer.parseInt(lat.substring(6, 8), 16);// 分,第2位
				int d3 = Integer.parseInt(lat.substring(8, 10), 16);// 分,第3位
				double d4 = Double.parseDouble("0." + addZero(d1) + addZero(d2) + addZero(d3));
				int d5 = new Double(String.valueOf(d4 * 1000000)).intValue();
				DecimalFormat df1 = new DecimalFormat("0.00");
				String d6 = df1.format((float) d5 / 60);
				double d7 = Double.parseDouble(d6);
				String d8 = String.valueOf((int) (d7 * 10 * 10));
				// 补位
				for(int l=0;l<(6-d8.length());l++) {
					d8="0"+d8;
				}
				String tempLat = String.valueOf(c) + "" + String.valueOf(d) + "."+ d8;
				result.put("lng", tempLat);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 0.byte[]数组转换为16进制的字符串
	 *
	 * @param bytes 要转换的字节数组
	 * @return 转换后的结果
	 * 
	 */
	public static String bytesToHexString(byte[] bytes) {
		StringBuffer sf = new StringBuffer();
		for (int i = 0; i < bytes.length; i++) {
			String hex = Integer.toHexString(0xFF & bytes[i]);
			if (hex.length() == 1) {
				sf.append('0');
			}
			sf.append(hex);
		}
		return sf.toString();
	}
	
	/**
	 * 补位
	 * @param num
	 * @return
	 */
	public static String addZero(int num) {
		String result = "";
		if(num<10) {
			result="0"+num;
		}else {
			result = String.valueOf(num);
		}
		return result;
	}

	// 测试方法
	public static void main(String[] args) throws Exception {
// 		String hexStr = "AA37C400D4889100622604411901123845530EF3000000CB16000306000000070509111706130C0C050509C15A18001304160D0D320973";
		String hexStr = "AA37C400D6D690006224395E0C01121A11120EA1002100054D001A02000000050311130616160101180303C15A0D0013041B10013508B6";
		HexMathUtils.formatHexStr(hexStr).toJSONString();
	}

}

注意:一般设备发我们发的数据都是ASCII编码的数据,我们用Socket通讯收到的数据通过数据流读取到后就是字节了,所以我们直接将读取到的字节转换为16进制的字符串,然后在调用我的测试方法,就可以了。
读取数据的线程的部分代码,如下:

@Override
	public void run() {
		try {
			int len = 0;
			byte[] bytes = new byte[1024];
			byte [] bytes1 = null;
			String temp = null;
			while ((len = is.read(bytes))!=-1) {
				bytes1 = new byte[len];
				System.arraycopy(bytes, 0, bytes1, 0, len);
				// 将1024长度的数组的可用内容复制出来,因为读取到的数据不一定有1024那么长,会有默认值0。
				temp = HexMathUtils.bytesToHexString(bytes1);
				// 发送GPS信息请求
				Map<String, String> map = new HashMap<>();
				map.put("param", temp);
				HttpUtils.send("http://localhost:8085/jyzs/socket/saveInfo", map, 10);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

到这里基本上就写完了。关键的代码都贴上了,尤其是工具类的解析代码!

猜你喜欢

转载自blog.csdn.net/P923284735/article/details/89643291