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对象,按照InflectionPointNumber字段进行排序
|
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、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;
|
}
|
|
}
|