Advertisement

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

阅读量:

解析工具类

复制代码
    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();
    		}
    	}

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

全部评论 (0)

还没有任何评论哟~