From 606d7388589829e6a7108a48898d4e4126312d73 Mon Sep 17 00:00:00 2001
From: ‘liusuyi’ <1951119284@qq.com>
Date: Wed, 01 Nov 2023 16:38:11 +0800
Subject: [PATCH] 增加雷达角度引导信息反馈

---
 src/main/java/com/ard/alarm/radar/service/impl/ArdEquipRadarServiceImpl.java |    4 +
 src/main/java/com/ard/utils/tcp/ClientHandler.java                           |    2 
 src/main/java/com/ard/utils/other/GisUtils.java                              |   33 +++++++++++
 src/main/java/com/ard/alarm/radar/controller/RadarController.java            |   79 ++++++++++++++++++++++++++
 src/main/java/com/ard/utils/other/ByteUtils.java                             |   31 ++++++++++
 src/main/java/com/ard/utils/tcp/ClientInitialize.java                        |    6 +
 src/main/java/com/ard/utils/mqtt/MqttProducer.java                           |    1 
 src/main/java/com/ard/alarm/radar/service/IArdEquipRadarService.java         |    2 
 src/main/java/com/ard/alarm/radar/domain/GuideInfo.java                      |   15 +++++
 9 files changed, 169 insertions(+), 4 deletions(-)

diff --git a/src/main/java/com/ard/alarm/radar/controller/RadarController.java b/src/main/java/com/ard/alarm/radar/controller/RadarController.java
new file mode 100644
index 0000000..e4dfbad
--- /dev/null
+++ b/src/main/java/com/ard/alarm/radar/controller/RadarController.java
@@ -0,0 +1,79 @@
+package com.ard.alarm.radar.controller;
+
+import com.ard.alarm.radar.domain.ArdEquipRadar;
+import com.ard.alarm.radar.domain.GuideInfo;
+import com.ard.alarm.radar.service.IArdEquipRadarService;
+import com.ard.utils.http.AjaxResult;
+import com.ard.utils.other.ByteUtils;
+import com.ard.utils.other.GisUtils;
+import com.ard.utils.tcp.ClientInitialize;
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.Channel;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * @Description: 雷达接口
+ * @ClassName: RadarController
+ * @Author: 刘苏义
+ * @Date: 2023年11月01日14:12:31
+ **/
+@RestController
+@RequestMapping("/radar")
+public class RadarController {
+
+    @Resource
+    IArdEquipRadarService ardEquipRadarService;
+
+    /**
+     * 角度引导信息反馈
+     */
+    @PostMapping("/guideInfoBack")
+    public AjaxResult guideInfoBack(@RequestBody GuideInfo guideInfo) {
+        double[] targetPosition = guideInfo.getTargetPosition();
+        ArdEquipRadar ardEquipRadar = ardEquipRadarService.selectArdEquipRadarById(guideInfo.getRadarId());
+        if (ardEquipRadar == null) {
+            return AjaxResult.error("雷达不存在");
+        }
+        Channel channel = (Channel)ClientInitialize.SuccessConnectMap.get(ardEquipRadar.getId());
+        if (channel==null)
+        {
+            return AjaxResult.error("雷达未连接");
+        }
+        Double longitude = ardEquipRadar.getLongitude();//雷达经度
+        Double latitude = ardEquipRadar.getLatitude();//雷达纬度
+        Double altitude = ardEquipRadar.getAltitude();//雷达高度
+        //计算水平角度
+        float p = (float)GisUtils.getNorthAngle(longitude, latitude, targetPosition[0], targetPosition[1]);
+        //计算垂直角度
+        double[] radarPosition = new double[2];
+        radarPosition[0] = longitude;
+        radarPosition[1] = latitude;
+        double distance = GisUtils.getDistance(radarPosition, targetPosition);
+        float angleInRadians = (float)Math.atan(distance / altitude);
+        float t = 90-(float)Math.toDegrees(angleInRadians);
+
+        //发送告警前端的角度提示
+        byte[] header = {0x01, 0x02, 0x01};//包头
+        byte[] payloadHeader = {0x10, 0x03, 0x40, 0x00};//负载头
+        byte[] distanceBytes = ByteUtils.decimalToBytes((int)distance);
+        byte[] pBytes = ByteUtils.floatToBytes(p);
+        byte[] tBytes = ByteUtils.floatToBytes(t);
+        byte[] resBytes=new byte[20];
+        byte[] payloadBody = ByteUtils.appendArrays(distanceBytes,pBytes,tBytes,resBytes);//负载
+
+        byte[] payload = ByteUtils.appendArrays(payloadHeader,payloadBody);//负载头+负载
+        byte[] payloadCrc32 = ByteUtils.parseCrc32(payload);//负载头+负载的crc32校验
+        byte[] footer = {0x01, 0x02, 0x00};//包尾
+        byte[] data = ByteUtils.appendArrays(header, payload, payloadCrc32, footer);
+        System.out.println(ByteUtils.printHexBinary(data));
+        ByteBuf message = channel.alloc().buffer();
+        message.writeBytes(data);
+        channel.writeAndFlush(message);
+        return AjaxResult.success();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ard/alarm/radar/domain/GuideInfo.java b/src/main/java/com/ard/alarm/radar/domain/GuideInfo.java
new file mode 100644
index 0000000..1ea7bbf
--- /dev/null
+++ b/src/main/java/com/ard/alarm/radar/domain/GuideInfo.java
@@ -0,0 +1,15 @@
+package com.ard.alarm.radar.domain;
+
+import lombok.Data;
+
+/**
+ * @Description:
+ * @ClassName: GuideInfo
+ * @Author: 刘苏义
+ * @Date: 2023年11月01日15:45:10
+ **/
+@Data
+public class GuideInfo {
+    String radarId;
+    double[] targetPosition;
+}
diff --git a/src/main/java/com/ard/alarm/radar/service/IArdEquipRadarService.java b/src/main/java/com/ard/alarm/radar/service/IArdEquipRadarService.java
index c999aa5..97c6b45 100644
--- a/src/main/java/com/ard/alarm/radar/service/IArdEquipRadarService.java
+++ b/src/main/java/com/ard/alarm/radar/service/IArdEquipRadarService.java
@@ -18,5 +18,5 @@
      * @return radar集合
      */
     public List<ArdEquipRadar> selectArdEquipRadarList(ArdEquipRadar ardEquipRadar);
-
+    public ArdEquipRadar selectArdEquipRadarById(String radarId);
 }
\ No newline at end of file
diff --git a/src/main/java/com/ard/alarm/radar/service/impl/ArdEquipRadarServiceImpl.java b/src/main/java/com/ard/alarm/radar/service/impl/ArdEquipRadarServiceImpl.java
index 5b141dc..1cb657a 100644
--- a/src/main/java/com/ard/alarm/radar/service/impl/ArdEquipRadarServiceImpl.java
+++ b/src/main/java/com/ard/alarm/radar/service/impl/ArdEquipRadarServiceImpl.java
@@ -34,4 +34,8 @@
         return ardEquipRadarMapper.selectList(queryWrapper);
     }
 
+    @Override
+    public ArdEquipRadar selectArdEquipRadarById(String radarId) {
+        return ardEquipRadarMapper.selectById(radarId);
+    }
 }
diff --git a/src/main/java/com/ard/utils/mqtt/MqttProducer.java b/src/main/java/com/ard/utils/mqtt/MqttProducer.java
index aef7240..901dc64 100644
--- a/src/main/java/com/ard/utils/mqtt/MqttProducer.java
+++ b/src/main/java/com/ard/utils/mqtt/MqttProducer.java
@@ -56,6 +56,7 @@
             getClient();
             // 2 设置配置
             MqttConnectOptions options = getOptions();
+            options.setMaxInflight(1000);
             // 3 最后设置
             create(options);
         } catch (Exception e) {
diff --git a/src/main/java/com/ard/utils/other/ByteUtils.java b/src/main/java/com/ard/utils/other/ByteUtils.java
index b82cd85..f89e0e9 100644
--- a/src/main/java/com/ard/utils/other/ByteUtils.java
+++ b/src/main/java/com/ard/utils/other/ByteUtils.java
@@ -1,5 +1,6 @@
 package com.ard.utils.other;
 
+import javax.xml.bind.DatatypeConverter;
 import java.io.ByteArrayOutputStream;
 import java.io.UnsupportedEncodingException;
 import java.nio.ByteBuffer;
@@ -14,6 +15,14 @@
  * @Version: 1.0
  **/
 public class ByteUtils {
+
+    /**
+     * 打印十六进制二进制
+     */
+    public static String printHexBinary(byte[] bytes) {
+        return DatatypeConverter.printHexBinary(bytes);
+    }
+
     /**
      * byte数组转中文字符串
      */
@@ -116,6 +125,28 @@
     }
 
     /**
+     * double转byte数组
+     */
+    public static byte[] doubleToBytes(double d) {
+        long value = Double.doubleToRawLongBits(d);
+        byte[] byteRet = new byte[8];
+        for (int i = 0; i < 8; i++) {
+            byteRet[i] = (byte) ((value >> 8 * i) & 0xff);
+        }
+        return byteRet;
+    }
+    /**
+     * float转byte数组
+     */
+    public static byte[] floatToBytes(float f) {
+        // 创建一个 ByteBuffer,分配足够的空间来存储一个 float 值
+        ByteBuffer buffer = ByteBuffer.allocate(Float.BYTES);
+        // 将 float 值写入 ByteBuffer
+        buffer.putFloat(f);
+        // 获取字节数组
+        return buffer.array();
+    }
+    /**
      * byte数组拼接
      */
     public static byte[] appendArrays(byte[]... arrays) {
diff --git a/src/main/java/com/ard/utils/other/GisUtils.java b/src/main/java/com/ard/utils/other/GisUtils.java
index e58ca17..29b96c6 100644
--- a/src/main/java/com/ard/utils/other/GisUtils.java
+++ b/src/main/java/com/ard/utils/other/GisUtils.java
@@ -3,6 +3,7 @@
 import org.gavaghan.geodesy.Ellipsoid;
 import org.gavaghan.geodesy.GeodeticCalculator;
 import org.gavaghan.geodesy.GlobalCoordinates;
+import org.gavaghan.geodesy.GlobalPosition;
 
 /**
  * @Description: gis工具类
@@ -12,6 +13,23 @@
  * @Version: 1.0
  **/
 public class GisUtils {
+    public static GeodeticCalculator geodeticCalculator = new GeodeticCalculator();
+    /**
+     * 根据经纬度,计算两点间的距离
+     *
+     * @param From 第一个点的经纬度
+     * @param To  第二个点的经纬度
+     * @return 返回距离 单位米
+     */
+    public static double getDistance(double[] From, double[] To) {
+        double longitudeFrom = From[0];
+        double latitudeFrom = From[1];
+        double longitudeTo = To[0];
+        double latitudeTo = To[1];
+        GlobalCoordinates source = new GlobalCoordinates(latitudeFrom, longitudeFrom);
+        GlobalCoordinates target = new GlobalCoordinates(latitudeTo, longitudeTo);
+        return geodeticCalculator.calculateGeodeticCurve(Ellipsoid.WGS84, source, target).getEllipsoidalDistance();
+    }
     /**
      * 通过A点坐标,长度和Y轴角度计算B点坐标
      */
@@ -26,4 +44,19 @@
         GlobalCoordinates globalCoordinates1 = calculator.calculateEndingGlobalCoordinates(Ellipsoid.WGS84, globalCoordinates, angleWithYAxisDegrees, AB);
         return new Double[]{globalCoordinates1.getLongitude(), globalCoordinates1.getLatitude()};
     }
+    /**
+     * 计算从from到to方向的直线与正北方向夹角
+     *
+     * @param longitudeFrom 第一个点的经度
+     * @param latitudeFrom  第一个点的纬度
+     * @param longitudeTo   第二个点的经度
+     * @param latitudeTo    第二个点的纬度
+     * @return 返回角度
+     */
+    public static double getNorthAngle(double longitudeFrom, double latitudeFrom, double longitudeTo, double latitudeTo) {
+        GlobalPosition source = new GlobalPosition(latitudeFrom, longitudeFrom, 0);
+        GlobalPosition target = new GlobalPosition(latitudeTo, longitudeTo, 0);
+        return geodeticCalculator.calculateGeodeticMeasurement(Ellipsoid.WGS84, source, target).getAzimuth();
+    }
+
 }
diff --git a/src/main/java/com/ard/utils/tcp/ClientHandler.java b/src/main/java/com/ard/utils/tcp/ClientHandler.java
index 6df4b26..2693e76 100644
--- a/src/main/java/com/ard/utils/tcp/ClientHandler.java
+++ b/src/main/java/com/ard/utils/tcp/ClientHandler.java
@@ -43,7 +43,7 @@
      * @throws Exception
      */
     @Override
-    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+    public void channelActive(ChannelHandlerContext ctx) {
         context = ctx;
         startHeartbeatTask();//开始发送心跳
     }
diff --git a/src/main/java/com/ard/utils/tcp/ClientInitialize.java b/src/main/java/com/ard/utils/tcp/ClientInitialize.java
index 15023cf..dfc0ca8 100644
--- a/src/main/java/com/ard/utils/tcp/ClientInitialize.java
+++ b/src/main/java/com/ard/utils/tcp/ClientInitialize.java
@@ -49,7 +49,7 @@
     private Bootstrap bootstrap;
     public static CopyOnWriteArraySet<ArdEquipRadar> falseConnectSet = new CopyOnWriteArraySet();
     public static ConcurrentHashMap<ChannelId, ArdEquipRadar> tureConnectMap = new ConcurrentHashMap();
-
+    public static ConcurrentHashMap<String, Object> SuccessConnectMap = new ConcurrentHashMap();
     /**
      * Netty初始化配置
      */
@@ -110,12 +110,14 @@
                 falseConnectSet.add(ardEquipRadar);
                 // 连接失败信息从map移除
                 tureConnectMap.remove(futureListener.channel().id());
+                SuccessConnectMap.remove(ardEquipRadar.getId());
             } else {
                 log.debug("雷达【" + host + ":" + port + "】连接成功");
                 // 连接成功信息从Set拔除
                 falseConnectSet.remove(ardEquipRadar);
                 // 连接成功信息写入map
                 tureConnectMap.put(futureListener.channel().id(), ardEquipRadar);
+                SuccessConnectMap.put(ardEquipRadar.getId(),futureListener.channel());
             }
         });
     }
@@ -124,7 +126,7 @@
      * 初始化方法
      */
     @Override
-    public void run(ApplicationArguments args) throws Exception {
+    public void run(ApplicationArguments args) {
         if (!tcpClientEnable) {
             return;
         }

--
Gitblit v1.9.3