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