From 27fa371d0fff1590be0534277fe8680ed6515315 Mon Sep 17 00:00:00 2001
From: ‘liusuyi’ <1951119284@qq.com>
Date: 星期三, 07 六月 2023 17:18:18 +0800
Subject: [PATCH] 增加管线泄露报警点坐标算法

---
 ard-work/src/main/java/com/ruoyi/alarm/tubeAlarm/service/impl/LeakPointCalculation.java |   50 ++++++++
 ard-work/src/main/java/com/ruoyi/alarm/tubeAlarm/service/impl/GeoPoint.java             |   18 +++
 ard-work/src/main/java/com/ruoyi/alarm/tubeAlarm/service/impl/testService.java          |  220 ++++++++++++++++++++++++++++++++++++
 ard-work/src/main/java/com/ruoyi/alarm/tubeAlarm/service/impl/MyLatLng.java             |   39 ++++++
 ard-work/src/main/java/com/ruoyi/alarm/tubeAlarm/service/impl/Point3D.java              |   19 +++
 5 files changed, 346 insertions(+), 0 deletions(-)

diff --git a/ard-work/src/main/java/com/ruoyi/alarm/tubeAlarm/service/impl/GeoPoint.java b/ard-work/src/main/java/com/ruoyi/alarm/tubeAlarm/service/impl/GeoPoint.java
new file mode 100644
index 0000000..8138933
--- /dev/null
+++ b/ard-work/src/main/java/com/ruoyi/alarm/tubeAlarm/service/impl/GeoPoint.java
@@ -0,0 +1,18 @@
+package com.ruoyi.alarm.tubeAlarm.service.impl;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * @ClassName GeoPoint
+ * @Description:
+ * @Author 鍒樿嫃涔�
+ * @Date 2023/6/6 20:22
+ * @Version 1.0
+ */
+@Data
+@AllArgsConstructor
+public class GeoPoint {
+    Double longitude;
+    Double latitude;
+}
diff --git a/ard-work/src/main/java/com/ruoyi/alarm/tubeAlarm/service/impl/LeakPointCalculation.java b/ard-work/src/main/java/com/ruoyi/alarm/tubeAlarm/service/impl/LeakPointCalculation.java
new file mode 100644
index 0000000..05a6225
--- /dev/null
+++ b/ard-work/src/main/java/com/ruoyi/alarm/tubeAlarm/service/impl/LeakPointCalculation.java
@@ -0,0 +1,50 @@
+package com.ruoyi.alarm.tubeAlarm.service.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LeakPointCalculation {
+    public static void main(String[] args) {
+        // 鍋囪鏈変笁娈电绾�
+        List<Point3D> pipeline = new ArrayList<>();
+        pipeline.add(new Point3D(124.925198285, 46.68693001, 147.5));     // 绗竴娈电绾跨殑璧风偣鍧愭爣
+        pipeline.add(new Point3D(124.925490653, 46.687071291, 148.2));  // 绗竴娈电绾跨殑缁堢偣鍧愭爣鍜岄珮绋�
+        pipeline.add(new Point3D(124.926401943, 46.686812672, 143.5));  // 绗簩娈电绾跨殑缁堢偣鍧愭爣鍜岄珮绋�
+        pipeline.add(new Point3D(124.926981879, 46.686644854, 147.4));  // 绗笁娈电绾跨殑缁堢偣鍧愭爣鍜岄珮绋�
+
+        double leakPointDistance = 100.0;  // 娉勬紡鐐圭浉瀵逛簬绠$嚎璧风偣鐨勯暱搴�
+
+        // 1. 纭畾娉勬紡鐐规墍鍦ㄧ殑绠$嚎娈�
+        Point3D startPoint = null;
+        Point3D endPoint = null;
+        double accumulatedLength = 0.0;
+        for (int i = 0; i < pipeline.size() - 1; i++) {
+            startPoint = pipeline.get(i);
+            endPoint = pipeline.get(i + 1);
+            double segmentLength = calculateDistance(startPoint, endPoint);
+            accumulatedLength += segmentLength;
+            if (accumulatedLength >= leakPointDistance) {
+                break;
+            }
+        }
+
+        // 2. 璁$畻娉勬紡鐐瑰湪鎵�鍦ㄧ绾挎涓婄殑鐩稿浣嶇疆
+        double relativePosition = (accumulatedLength - leakPointDistance) / calculateDistance(startPoint, endPoint);
+
+        // 3. 璁$畻娉勬紡鐐圭殑鍧愭爣
+        double x = startPoint.getX() + (endPoint.getX() - startPoint.getX()) * relativePosition;
+        double y = startPoint.getY() + (endPoint.getY() - startPoint.getY()) * relativePosition;
+        double z = startPoint.getZ() + (endPoint.getZ() - startPoint.getZ()) * relativePosition;
+
+        Point3D leakPoint = new Point3D(x, y, z);
+        System.out.println("娉勬紡鐐瑰潗鏍囷細" + leakPoint);
+    }
+
+    // 璁$畻涓や釜鐐逛箣闂寸殑璺濈
+    private static double calculateDistance(Point3D point1, Point3D point2) {
+        double dx = point2.getX() - point1.getX();
+        double dy = point2.getY() - point1.getY();
+        double dz = point2.getZ() - point1.getZ();
+        return Math.sqrt(dx * dx + dy * dy + dz * dz);
+    }
+}
\ No newline at end of file
diff --git a/ard-work/src/main/java/com/ruoyi/alarm/tubeAlarm/service/impl/MyLatLng.java b/ard-work/src/main/java/com/ruoyi/alarm/tubeAlarm/service/impl/MyLatLng.java
new file mode 100644
index 0000000..549d7b9
--- /dev/null
+++ b/ard-work/src/main/java/com/ruoyi/alarm/tubeAlarm/service/impl/MyLatLng.java
@@ -0,0 +1,39 @@
+package com.ruoyi.alarm.tubeAlarm.service.impl;
+
+import lombok.Data;
+
+/**
+ * @ClassName MyLatLng
+ * @Description:
+ * @Author 鍒樿嫃涔�
+ * @Date 2023/6/6 20:14
+ * @Version 1.0
+ */
+@Data
+public class MyLatLng {
+    final static double Rc = 6378137;
+    final static double Rj = 6356725;
+    double m_LoDeg, m_LoMin, m_LoSec;
+    double m_LaDeg, m_LaMin, m_LaSec;
+    double m_Longitude, m_Latitude;
+    double m_RadLo, m_RadLa;
+    double Ec;
+    double Ed;
+
+    public MyLatLng(double longitude, double latitude) {
+        m_LoDeg = (int) longitude;
+        m_LoMin = (int) ((longitude - m_LoDeg) * 60);
+        m_LoSec = (longitude - m_LoDeg - m_LoMin / 60.) * 3600;
+
+        m_LaDeg = (int) latitude;
+        m_LaMin = (int) ((latitude - m_LaDeg) * 60);
+        m_LaSec = (latitude - m_LaDeg - m_LaMin / 60.) * 3600;
+
+        m_Longitude = longitude;
+        m_Latitude = latitude;
+        m_RadLo = longitude * Math.PI / 180.;
+        m_RadLa = latitude * Math.PI / 180.;
+        Ec = Rj + (Rc - Rj) * (90. - m_Latitude) / 90.;
+        Ed = Ec * Math.cos(m_RadLa);
+    }
+}
diff --git a/ard-work/src/main/java/com/ruoyi/alarm/tubeAlarm/service/impl/Point3D.java b/ard-work/src/main/java/com/ruoyi/alarm/tubeAlarm/service/impl/Point3D.java
new file mode 100644
index 0000000..7629d0e
--- /dev/null
+++ b/ard-work/src/main/java/com/ruoyi/alarm/tubeAlarm/service/impl/Point3D.java
@@ -0,0 +1,19 @@
+package com.ruoyi.alarm.tubeAlarm.service.impl;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * @Description:
+ * @ClassName: Point3D
+ * @Author: 鍒樿嫃涔�
+ * @Date: 2023骞�06鏈�07鏃�15:12
+ * @Version: 1.0
+ **/
+@Data
+@AllArgsConstructor
+public class Point3D {
+    private double x;
+    private double y;
+    private double z;
+}
diff --git a/ard-work/src/main/java/com/ruoyi/alarm/tubeAlarm/service/impl/testService.java b/ard-work/src/main/java/com/ruoyi/alarm/tubeAlarm/service/impl/testService.java
new file mode 100644
index 0000000..7f7ff27
--- /dev/null
+++ b/ard-work/src/main/java/com/ruoyi/alarm/tubeAlarm/service/impl/testService.java
@@ -0,0 +1,220 @@
+package com.ruoyi.alarm.tubeAlarm.service.impl;
+
+import com.ruoyi.alarmpoints.tube.domain.ArdTubesDetails;
+import com.ruoyi.alarmpoints.tube.mapper.ArdTubesDetailsMapper;
+import com.ruoyi.device.hiksdk.util.hikSdkUtil.GisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.List;
+
+
+/**
+ * @Description:
+ * @ClassName: testService
+ * @Author: 鍒樿嫃涔�
+ * @Date: 2023骞�06鏈�06鏃�15:20
+ * @Version: 1.0
+ **/
+@Service
+@Slf4j
+public class testService {
+
+    @Resource
+    ArdTubesDetailsMapper ardTubesDetailsMapper;
+
+    // 璁$畻涓や釜鐐逛箣闂寸殑璺濈
+    public static double calculateDistance(double x1, double y1, double z1, double x2, double y2, double z2) {
+        double deltaX = x2 - x1;
+        double deltaY = y2 - y1;
+        double deltaZ = z2 - z1;
+        double distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);
+        return distance;
+    }
+
+    @PostConstruct
+    public void getlist() {
+        Integer alarmPointDistance = 100;
+        ArdTubesDetails atd = new ArdTubesDetails();
+        atd.setReelNumber("10");
+        List<ArdTubesDetails> ardTubesDetails = ardTubesDetailsMapper.selectArdTubesDetailsList(atd);
+        TreeMap<Integer, Double> distanceMap = new TreeMap<>();
+        // 鍒涘缓鑷畾涔夌殑Comparator瀵硅薄锛屾寜鐓nflectionPointNumber瀛楁杩涜鎺掑簭
+        Comparator<ArdTubesDetails> comparator = Comparator.comparingInt(person -> Integer.parseInt(person.getInflectionPointNumber()));
+        // 浣跨敤Collections.sort鏂规硶杩涜鎺掑簭
+        Collections.sort(ardTubesDetails, comparator);
+        /*璧风偣鍧愭爣*/
+        Double x = ardTubesDetails.get(0).getLongitude();
+        Double y = ardTubesDetails.get(0).getLatitude();
+        TreeMap<Integer, Object> pointMap = new TreeMap<>();
+        Double tempX = x;
+        Double tempY = y;
+        Double tempD = 0.0;
+        for (ArdTubesDetails ardtd : ardTubesDetails) {
+            double distance = GisUtil.getDistance(tempX, tempY, ardtd.getLongitude(), ardtd.getLatitude());
+            tempD += distance;
+            distanceMap.put(Integer.parseInt(ardtd.getInflectionPointNumber()), tempD);
+            pointMap.put(Integer.parseInt(ardtd.getInflectionPointNumber()), ardtd);
+            tempX = ardtd.getLongitude();
+            tempY = ardtd.getLatitude();
+        }
+
+
+        /*鎸夐『搴忔瘮瀵硅窛绂伙紝鎵惧埌璇ヨ窛绂诲睘浜庡摢涓嫄鐐逛箣鍚�*/
+        int num = 1;//鎷愮偣搴忓彿
+        Double distanceDiff = 0.0;//涓庢嫄鐐硅窛绂诲樊
+        Double distanceA = 0.0;
+        Double distanceB = 0.0;
+        while (distanceB < alarmPointDistance) {
+            num++;
+            distanceA = distanceMap.get(num-1);
+            distanceB = distanceMap.get(num);
+        }
+        log.info("鎶ヨ鐐瑰湪鎷愮偣" + (num - 1) + "涓�" + (num) + "涔嬮棿");
+        /*鑾峰彇褰撳墠鎶ヨ鐐规墍鍦ㄧ殑2涓嫄鐐圭殑鍧愭爣*/
+        ArdTubesDetails point1 = (ArdTubesDetails) pointMap.get(num - 1);
+        double x0 = point1.getLongitude();
+        double y0 = point1.getLatitude();
+        double z0 = point1.getAltitude();
+        ArdTubesDetails point2 = (ArdTubesDetails) pointMap.get(num);
+        double x1 = point2.getLongitude();
+        double y1 = point2.getLatitude();
+        double z1 = point2.getAltitude();
+        /*璁$畻鎶ヨ鐐瑰潗鏍�*/
+        double ABdistance = GisUtil.getDistance(x0, y0, x1, y1);
+        double Bdistance = z1 > z0 ? z1 - z0 : z0 - z1;
+        double angleC = Math.atan(Bdistance / ABdistance);
+        log.info("瀵硅竟涓庨偦杈瑰搴旇鐨勫姬搴︼細" + angleC + " 搴�");
+        // 灏嗗姬搴﹁浆鎹负瑙掑害
+        double angleDeg = Math.toDegrees(angleC);
+        log.info("瀵硅竟涓庨偦杈瑰搴旇鐨勮搴︼細" + angleDeg + " 搴�");
+
+        /*鎶ヨ鎵�鍦ㄧ殑2涓嫄鐐癸紝璧风偣楂樹簬缁堢*/
+        if(z0>z1)
+        {
+            distanceDiff = alarmPointDistance - distanceA;
+            GeoPoint aPoint = new GeoPoint(x0, y0);
+            GeoPoint bPoint = new GeoPoint(x1, y1);
+            double sp = Math.sin(angleC) * distanceDiff;
+            log.info("姘村钩璺濈锛�" + sp + " 绫�");
+            GeoPoint geoPoint = caculateRawGeoPoint(aPoint, bPoint, sp);
+            log.info(geoPoint.toString());
+            /*璁$畻楂樺眰*/
+            double ACdistance = GisUtil.getDistance(geoPoint.getLongitude(), geoPoint.getLatitude(),x1, y1);
+            // 姹傝В鏂滆竟鐨勯暱搴�
+            double hypotenuse = ACdistance * Math.tan(angleC) + z1;
+            log.info("C鐐归珮灞傦細" + hypotenuse + " 绫�");
+        }
+        else
+        {
+            distanceDiff = alarmPointDistance - distanceA;
+            GeoPoint aPoint = new GeoPoint(x0, y0);
+            GeoPoint bPoint = new GeoPoint(x1, y1);
+            double sp = Math.sin(angleC) * distanceDiff;
+            log.info("姘村钩璺濈锛�" + sp + " 绫�");
+            GeoPoint geoPoint = caculateRawGeoPoint(aPoint, bPoint, sp);
+            log.info(geoPoint.toString());
+            /*璁$畻楂樺眰*/
+            double ACdistance = GisUtil.getDistance(x0, y0, geoPoint.getLongitude(), geoPoint.getLatitude());
+            // 姹傝В鏂滆竟鐨勯暱搴�
+            double hypotenuse = ACdistance * Math.tan(angleC) + z0;
+            log.info("C鐐归珮灞傦細" + hypotenuse + " 绫�");
+        }
+
+    }
+
+
+    //鍒ゆ柇2涓嚎娈电殑鏂滅巼
+    public static void main(String[] args) {
+        // 鍋囪缁欏畾鐨勪笁涓潗鏍囩偣 A銆丅銆丆
+        double x1 = 124.925490653;
+        double y1 = 46.687071291;
+        double x2 = 124.9255455011709;
+        double y2 = 46.68705572539618;
+        double x3 = 124.926401943;
+        double y3 = 46.686812672;
+        // 璁$畻鏂滅巼
+        double slope1 = (y2 - y1) / (x2 - x1);
+        double slope2 = (y3 - y2) / (x3 - x2);
+
+        // 璁剧疆鏂滅巼宸�肩殑闃堝��
+        double threshold = 0.0000001;
+
+        // 妫�鏌ユ枩鐜囨槸鍚︾浉绛�
+        if (Math.abs(slope1 - slope2) < threshold) {
+            log.info("杩欎笁涓偣鍏辩嚎");
+        } else {
+            log.info("杩欎笁涓偣涓嶅叡绾�");
+        }
+    }
+
+    /**
+     * 宸茬煡WGS84鍧愭爣绯� A 鐐癸紝B鐐�, X 鍦ˋB 寮х嚎涓�, 涓旀槸鏈�鐭殑杩欐潯, AX璺濈宸茬煡锛屾眰X鐐瑰潗鏍�.
+     *
+     * @param aPoint
+     * @param bPoint
+     * @param distance_ax_in_meter
+     * @return
+     */
+    public static GeoPoint caculateRawGeoPoint(GeoPoint aPoint, GeoPoint bPoint, double distance_ax_in_meter) {
+        MyLatLng a = new MyLatLng(aPoint.getLongitude(), aPoint.getLatitude());
+        MyLatLng b = new MyLatLng(bPoint.getLongitude(), bPoint.getLatitude());
+        double angle = getAngle(a, b); //getAngle(a,x)==getAngle(a,b)
+        MyLatLng x = getMyLatLng(a, distance_ax_in_meter / 1000.0, angle);
+        GeoPoint xPoint = new GeoPoint(x.m_Longitude, x.m_Latitude);
+        return xPoint;
+    }
+    public static GeoPoint caculateRawGeoPoint1(GeoPoint aPoint, GeoPoint bPoint, double distance_ax_in_meter) {
+        MyLatLng a = new MyLatLng(aPoint.getLongitude(), aPoint.getLatitude());
+        MyLatLng b = new MyLatLng(bPoint.getLongitude(), bPoint.getLatitude());
+        double angle = getAngle(a, b);
+        MyLatLng x = getMyLatLng(a, (360-distance_ax_in_meter) / 1000.0, angle);
+        GeoPoint xPoint = new GeoPoint(x.m_Longitude, x.m_Latitude);
+        return xPoint;
+    }
+    /**
+     * 姹侭鐐圭粡绾害
+     *
+     * @param A            宸茬煡鐐圭殑缁忕含搴︼紝
+     * @param distanceInKM AB涓ゅ湴鐨勮窛绂�  鍗曚綅km
+     * @param angle        AB杩炵嚎涓庢鍖楁柟鍚戠殑澶硅锛�0~360锛�
+     * @return B鐐圭殑缁忕含搴�
+     */
+    public static MyLatLng getMyLatLng(MyLatLng A, double distanceInKM, double angle) {
+
+        double dx = distanceInKM * 1000 * Math.sin(Math.toRadians(angle));
+        double dy = distanceInKM * 1000 * Math.cos(Math.toRadians(angle));
+
+        double bjd = (dx / A.Ed + A.m_RadLo) * 180. / Math.PI;
+        double bwd = (dy / A.Ec + A.m_RadLa) * 180. / Math.PI;
+        return new MyLatLng(bjd, bwd);
+    }
+
+    /**
+     * 鑾峰彇AB杩炵嚎涓庢鍖楁柟鍚戠殑瑙掑害
+     *
+     * @param A A鐐圭殑缁忕含搴�
+     * @param B B鐐圭殑缁忕含搴�
+     * @return AB杩炵嚎涓庢鍖楁柟鍚戠殑瑙掑害锛�0~360锛�
+     */
+    public static double getAngle(MyLatLng A, MyLatLng B) {
+        double dx = (B.m_RadLo - A.m_RadLo) * A.Ed;
+        double dy = (B.m_RadLa - A.m_RadLa) * A.Ec;
+        double angle = 0.0;
+        angle = Math.atan(Math.abs(dx / dy)) * 180. / Math.PI;
+        double dLo = B.m_Longitude - A.m_Longitude;
+        double dLa = B.m_Latitude - A.m_Latitude;
+        if (dLo > 0 && dLa <= 0) {
+            angle = (90. - angle) + 90;
+        } else if (dLo <= 0 && dLa < 0) {
+            angle = angle + 180.;
+        } else if (dLo < 0 && dLa >= 0) {
+            angle = (90. - angle) + 270;
+        }
+        return angle;
+    }
+
+}

--
Gitblit v1.9.3