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