diff --git a/casic-ship/pom.xml b/casic-ship/pom.xml index 4b0c4e0..d445c1f 100644 --- a/casic-ship/pom.xml +++ b/casic-ship/pom.xml @@ -51,6 +51,12 @@ fastjson ${fastjson.version} + + + org.locationtech.spatial4j + spatial4j + 0.8 + diff --git a/casic-ship/pom.xml b/casic-ship/pom.xml index 4b0c4e0..d445c1f 100644 --- a/casic-ship/pom.xml +++ b/casic-ship/pom.xml @@ -51,6 +51,12 @@ fastjson ${fastjson.version} + + + org.locationtech.spatial4j + spatial4j + 0.8 + diff --git a/casic-ship/src/main/java/com/casic/missiles/modular/system/service/impl/RobotServiceImpl.java b/casic-ship/src/main/java/com/casic/missiles/modular/system/service/impl/RobotServiceImpl.java index 51ee60d..2fd43b3 100644 --- a/casic-ship/src/main/java/com/casic/missiles/modular/system/service/impl/RobotServiceImpl.java +++ b/casic-ship/src/main/java/com/casic/missiles/modular/system/service/impl/RobotServiceImpl.java @@ -34,7 +34,7 @@ @Override public void saveRobotInfo() { //TODO 测试数据 - RobotInfo robotInfo = DataParser.parseRobotInfo(RobotConstant.DATA); + RobotInfo robotInfo = DataParser.decodeRobotInfo(RobotConstant.DATA); QueryWrapper query = new QueryWrapper<>(); query.eq("ROBOT_ID", robotInfo.getRobotId()); if (this.count(query) == 0) { diff --git a/casic-ship/pom.xml b/casic-ship/pom.xml index 4b0c4e0..d445c1f 100644 --- a/casic-ship/pom.xml +++ b/casic-ship/pom.xml @@ -51,6 +51,12 @@ fastjson ${fastjson.version} + + + org.locationtech.spatial4j + spatial4j + 0.8 + diff --git a/casic-ship/src/main/java/com/casic/missiles/modular/system/service/impl/RobotServiceImpl.java b/casic-ship/src/main/java/com/casic/missiles/modular/system/service/impl/RobotServiceImpl.java index 51ee60d..2fd43b3 100644 --- a/casic-ship/src/main/java/com/casic/missiles/modular/system/service/impl/RobotServiceImpl.java +++ b/casic-ship/src/main/java/com/casic/missiles/modular/system/service/impl/RobotServiceImpl.java @@ -34,7 +34,7 @@ @Override public void saveRobotInfo() { //TODO 测试数据 - RobotInfo robotInfo = DataParser.parseRobotInfo(RobotConstant.DATA); + RobotInfo robotInfo = DataParser.decodeRobotInfo(RobotConstant.DATA); QueryWrapper query = new QueryWrapper<>(); query.eq("ROBOT_ID", robotInfo.getRobotId()); if (this.count(query) == 0) { diff --git a/casic-ship/src/main/java/com/casic/missiles/modular/system/utils/DataParser.java b/casic-ship/src/main/java/com/casic/missiles/modular/system/utils/DataParser.java index 2e787a7..0c2c3e1 100644 --- a/casic-ship/src/main/java/com/casic/missiles/modular/system/utils/DataParser.java +++ b/casic-ship/src/main/java/com/casic/missiles/modular/system/utils/DataParser.java @@ -4,7 +4,9 @@ import com.casic.missiles.modular.system.constants.CheckCode; import com.casic.missiles.modular.system.model.RobotInfo; import com.casic.missiles.modular.system.model.RobotRegion; +import org.locationtech.spatial4j.distance.DistanceUtils; +import java.text.DecimalFormat; import java.util.*; /** @@ -16,6 +18,8 @@ private static final int BITS_OF_HEAD = 0x2A; private static final int BITS_OF_END = 0x0A; + //赤道半径(单位km) + private static final double EARTH_RADIUS = 6371.393; private static boolean isCorrectData(int[] bytes) { if (bytes[0] != BITS_OF_HEAD) { @@ -27,7 +31,7 @@ /** * 水下机器人信息 */ - public static RobotInfo parseRobotInfo(int[] bytes) { + public static RobotInfo decodeRobotInfo(int[] bytes) { RobotInfo robot = new RobotInfo(); if (!isCorrectData(bytes)) { return robot; @@ -94,7 +98,7 @@ /** * 区域覆盖 */ - public static RobotRegion parseRobotRegion(int[] bytes) { + public static RobotRegion decodeRobotRegion(int[] bytes) { RobotRegion region = new RobotRegion(); if (!isCorrectData(bytes)) { return region; @@ -147,7 +151,7 @@ /** * 路径规划 */ - public static String parseRobotRoute(int[] bytes) { + public static String decodeRobotRoute(int[] bytes) { if (!isCorrectData(bytes)) { return ""; } @@ -166,7 +170,7 @@ /** * 定向任务 */ - public static String parseDirectedTask(int[] bytes) { + public static String decodeDirectedTask(int[] bytes) { if (!isCorrectData(bytes)) { return ""; } @@ -184,7 +188,7 @@ /** * 航路点任务 */ - public static String parseTaskRoute(int[] bytes) { + public static String decodeTaskRoute(int[] bytes) { if (!isCorrectData(bytes)) { return ""; } @@ -207,7 +211,7 @@ /** * 定深直航任务 */ - public static String parseDirectFlightTask(int[] bytes) { + public static String decodeDirectFlightTask(int[] bytes) { if (!isCorrectData(bytes)) { return ""; } @@ -229,7 +233,7 @@ /** * 驻留任务 */ - public static String parseResideTask(int[] bytes) { + public static String decodeResideTask(int[] bytes) { if (!isCorrectData(bytes)) { return ""; } @@ -255,7 +259,7 @@ /** * 投放任务 */ - public static String parsePutTask(int[] bytes) { + public static String decodePutTask(int[] bytes) { if (!isCorrectData(bytes)) { return ""; } @@ -286,9 +290,25 @@ } /** + * 短信内容 + */ + public static String decodeSMS(int[] bytes) { + //帧头、帧长度、帧类型、子类型、机器人ID,CRC16校验码、帧尾总长度=8 + int dataLen = bytes.length - 8; + + int[] dataBytes = new int[dataLen]; + System.arraycopy(bytes, 5, dataBytes, 0, dataLen); + StringBuilder builder = new StringBuilder(); + for (int dataByte : dataBytes) { + builder.append((char) dataByte); + } + return builder.toString(); + } + + /** * AIS数据请求 */ - public static String parseAISRequest(int[] bytes) { + public static String decodeAISRequest(int[] bytes) { if (!isCorrectData(bytes)) { return ""; } @@ -303,8 +323,10 @@ /** * 方舱位置 + * 编码encode + * 解码decode */ - public static String parseShelterPosition(int[] bytes) { + public static String decodeShelterPosition(int[] bytes) { if (!isCorrectData(bytes)) { return ""; } @@ -453,7 +475,7 @@ /** * 环境数据 */ - public static String parseEnvironmentalData(String data) { + public static String encodeEnvironment(String data) { //包含除校验位之前的所有数据 List dataLinkedList = createDataHead("01"); @@ -486,14 +508,14 @@ } //机器人与台风中心距离 - double distance = 355.56; + double distance = distance(115.6314213, 12.9691386, 112.0623457, 19.9936680); int[] distanceBytes = radiusToHex(distance); for (int distanceByte : distanceBytes) { dataLinkedList.add(hex(distanceByte)); } //机器人与台风的方位角 - double angle = 170.85; + double angle = azimuth(115.6314213, 12.9691386, 112.0623457, 19.9936680); int[] angleBytes = angleToHex(angle); for (int angleByte : angleBytes) { dataLinkedList.add(hex(angleByte)); @@ -539,8 +561,8 @@ dataLinkedList.add(hex(depthByte)); } - //重新设置数据长度,不包括CRC16数据长度 - int length = dataLinkedList.size(); + //重新设置数据长度,不包括CRC16数据长度但需要加上帧尾长度(1字节) + int length = dataLinkedList.size() + 1; dataLinkedList.set(1, hex(length)); //计算CRC16校验码 @@ -551,14 +573,14 @@ } //帧尾 - dataLinkedList.add("OA"); + dataLinkedList.add("0A"); return formatData(dataLinkedList); } /** - * 环境数据 + * AIS数据 */ - public static String parseAISData(String data) { + public static String encodeAIS(String data) { List dataLinkedList = createDataHead("02"); //船只数量 @@ -581,8 +603,8 @@ } } - //重新设置数据长度,不包括CRC16数据长度 - int length = dataLinkedList.size(); + //重新设置数据长度,不包括CRC16数据长度但需要加上帧尾长度(1字节) + int length = dataLinkedList.size() + 1; dataLinkedList.set(1, hex(length)); //计算CRC16校验码 @@ -593,7 +615,35 @@ } //帧尾 - dataLinkedList.add("OA"); + dataLinkedList.add("0A"); + return formatData(dataLinkedList); + } + + /** + * 短信数据 + */ + public static String encodeSMS(String data) { + List dataLinkedList = createDataHead("03"); + + //短信内容 + byte[] msgBytes = data.getBytes(); + for (byte msgByte : msgBytes) { + dataLinkedList.add(hex(msgByte)); + } + + //重新设置数据长度,不包括CRC16数据长度但需要加上帧尾长度(1字节) + int length = dataLinkedList.size() + 1; + dataLinkedList.set(1, hex(length)); + + //计算CRC16校验码 + int crc = CRC16(dataLinkedList); + int[] crcBytes = crc16ToHex(crc); + for (int crcByte : crcBytes) { + dataLinkedList.add(hex(crcByte)); + } + + //帧尾 + dataLinkedList.add("0A"); return formatData(dataLinkedList); } @@ -711,4 +761,43 @@ tempBytes[3] = (per) & 0xFF; return tempBytes; } + + /** + * 经纬度转弧度 + */ + private static double lnglatToRadian(double d) { + return d * Math.PI / 180.0; + } + + /** + * 经纬度距离计算 + */ + private static double distance(double lonA, double latA, double lonB, double latB) { + double aLng = lnglatToRadian(lonA); + double aLat = lnglatToRadian(latA); + double bLng = lnglatToRadian(lonB); + double bLat = lnglatToRadian(latB); + + double dist = DistanceUtils.distHaversineRAD(aLat, aLng, bLat, bLng) * EARTH_RADIUS; + DecimalFormat df = new DecimalFormat("#.00"); + return Double.parseDouble(df.format(dist)); + } + + /** + * 方位角 + *

+ * https://blog.csdn.net/dulingwen/article/details/96868530 + */ + private static int azimuth(double lonA, double latA, double lonB, double latB) { + double deltaLng = lonB - lonA; + + double y = Math.sin(deltaLng) * Math.cos(latB); + double x = Math.cos(latA) * Math.sin(latB) - Math.sin(latA) * Math.cos(latB) * Math.cos(deltaLng); + + double bearing = Math.atan2(y, x); + bearing = Math.toDegrees(bearing); + bearing = (bearing + 360) % 360; + + return (int) bearing; + } } \ No newline at end of file