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 = ardTubesDetailsMapper.selectArdTubesDetailsList(atd); TreeMap distanceMap = new TreeMap<>(); // 创建自定义的Comparator对象,按照InflectionPointNumber字段进行排序 Comparator 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 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、B、C 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 在AB 弧线上, 且是最短的这条, 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; } /** * 求B点经纬度 * * @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; } }