package com.ltgk.common.utils;

import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * @Auther: zhouyaoyao
 * @Date: 2021/10/26 09:08
 * @Description: 摄像角度调整工具类
 */
@Slf4j
public class CameraDegreesUtil {


    /**
     * 根据摄像和目标的经纬度位置，计算摄像需要旋转的角度
     */
    public static BigDecimal rotateForNorthByLR(double lon1, double lat1, double lon2, double lat2, int rotateT) {
        BigDecimal latitude1 = new BigDecimal(lat1);
        BigDecimal latitude2 = new BigDecimal(lat2);
        BigDecimal longitude1 = new BigDecimal(lon1);
        BigDecimal longitude2 = new BigDecimal(lon2);

        BigDecimal lonVal = longitude1.subtract(longitude2).setScale(10, RoundingMode.HALF_UP);
        BigDecimal latVal = latitude1.subtract(latitude2).setScale(10, RoundingMode.HALF_UP);
        BigDecimal zeroVal = BigDecimal.ZERO.setScale(10,RoundingMode.HALF_UP);

        int lonJudge = lonVal.compareTo(zeroVal);
        int latJudge = latVal.compareTo(zeroVal);

        if (lonJudge != 0 && latJudge != 0) {
            double k1 = lonJudge*rotateT;
            double k2 = latJudge;
            BigDecimal latToLon = latVal.divide(lonVal,10,RoundingMode.HALF_UP).abs();
            double atanVal = Math.PI/2 + k2*Math.atan(latToLon.doubleValue()/Math.cos(latitude1.doubleValue()*Math.PI/180));
            double degreesVal = k1*Math.toDegrees(atanVal);
            BigDecimal degrees = new BigDecimal(degreesVal).setScale(4,RoundingMode.HALF_UP);
            return degrees;
        } else {
            if (lonJudge == 0 && (latJudge == -1 || latJudge == 0)) {
                return BigDecimal.ZERO;
            } else if (lonJudge == 0 && latJudge == 1) {
                return new BigDecimal("180");
            } else if (latJudge == 0 && lonJudge == 1) {
                return new BigDecimal("-90");
            } else if (latJudge == 0 && lonJudge == -1) {
                return new BigDecimal("90");
            } else {
                return BigDecimal.ZERO;
            }
        }
    }

    /**
     * 根据摄像和目标的经纬度位置，计算摄像需要旋转的角度
     */
    public static BigDecimal rotateForSouthByLR(double lon1, double lat1, double lon2, double lat2) {
        BigDecimal latitude1 = new BigDecimal(lat1);
        BigDecimal latitude2 = new BigDecimal(lat2);
        BigDecimal longitude1 = new BigDecimal(lon1);
        BigDecimal longitude2 = new BigDecimal(lon2);

        BigDecimal lonVal = longitude1.subtract(longitude2).setScale(10, RoundingMode.HALF_UP);
        BigDecimal latVal = latitude1.subtract(latitude2).setScale(10, RoundingMode.HALF_UP);
        BigDecimal zeroVal = BigDecimal.ZERO.setScale(10,RoundingMode.HALF_UP);

        int lonJudge = lonVal.compareTo(zeroVal);
        int latJudge = latVal.compareTo(zeroVal);

        if (lonJudge != 0 && latJudge != 0) {
            double k1 = lonJudge;
            double k2 = latJudge*(-1);
            BigDecimal latToLon = latVal.divide(lonVal,10,RoundingMode.HALF_UP).abs();
            double atanVal = Math.PI/2 + k2*Math.atan(latToLon.doubleValue()/Math.cos(latitude1.doubleValue()*Math.PI/180));
            double degreesVal = k1*Math.toDegrees(atanVal);
            BigDecimal degrees = new BigDecimal(degreesVal).setScale(4,RoundingMode.HALF_UP);
            return degrees;
        } else {
            if (lonJudge == 0 && (latJudge == -1 || latJudge == 0)) {
                return new BigDecimal("180");
            } else if (lonJudge == 0 && latJudge == 1) {
                return BigDecimal.ZERO;
            } else if (latJudge == 0 && lonJudge == 1) {
                return new BigDecimal("90");
            } else if (latJudge == 0 && lonJudge == -1) {
                return new BigDecimal("-90");
            } else {
                return BigDecimal.ZERO;
            }
        }
    }

    /**
     * 根据摄像的高度high和距离目标的长度distance,计算摄像需要下调的角度
     */
    public static BigDecimal rotateByUD(double high,double lon1, double lat1, double lon2, double lat2) {
        double distance = 0d;
        BigDecimal latitude1 = new BigDecimal(lat1);
        BigDecimal latitude2 = new BigDecimal(lat2);
        BigDecimal longitude1 = new BigDecimal(lon1);
        BigDecimal longitude2 = new BigDecimal(lon2);

        BigDecimal lonVal = longitude1.subtract(longitude2).setScale(10, RoundingMode.HALF_UP);
        BigDecimal latVal = latitude1.subtract(latitude2).setScale(10, RoundingMode.HALF_UP);
        BigDecimal zeroVal = BigDecimal.ZERO.setScale(10,RoundingMode.HALF_UP);

        int lonJudge = lonVal.compareTo(zeroVal);
        int latJudge = latVal.compareTo(zeroVal);

        if (lonJudge == 0 || latJudge == 0) {
            if (latJudge != 0) {
                return latVal.abs();
            } else if (lonJudge != 0) {
                return lonVal.abs();
            }
            return BigDecimal.ZERO;
        } else {
            double lonPow = Math.pow(lonVal.doubleValue(),2) * 111 * Math.cos(latitude1.doubleValue()*Math.PI/180);
            double latPow = Math.pow(latVal.doubleValue(),2) * 111;
            distance = Math.sqrt(Math.pow(lonPow,2) + Math.pow(latPow,2));
        }
        BigDecimal distanceVal = getDistance( lon1,  lat1,  lon2,  lat2);
        BigDecimal highVal = new BigDecimal(high);

        BigDecimal hToD = highVal.divide(distanceVal,4,RoundingMode.HALF_UP);
        double degreesVal = Math.toDegrees(Math.atan(hToD.doubleValue()));
        BigDecimal degrees = new BigDecimal(degreesVal).setScale(4,RoundingMode.HALF_UP);
        return degrees;
    }


    /**
     * 赤道半径（单位：米）
     */
    private static final double EQUATOR_RADIUS = 6378137;

    /**
     * 方法一：（反余弦计算方式）
     */
    public static BigDecimal getDistance(double longitude1, double latitude1, double longitude2, double latitude2) {
        double lat1 = Math.toRadians(latitude1);
        double lat2 = Math.toRadians(latitude2);
        double lon1 = Math.toRadians(longitude1);
        double lon2 = Math.toRadians(longitude2);
        double a = lat1 - lat2;
        double b = lon1 - lon2;
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(b / 2), 2)));
        s = s * EQUATOR_RADIUS;
        return new BigDecimal(s/1000);
    }

    /**
     * 计算摄像距离目标的长度distance
     */
    public static BigDecimal distanceByUD(double lon1, double lat1, double lon2, double lat2) {
        double distance = 0d;
        BigDecimal latitude1 = new BigDecimal(lat1);
        BigDecimal latitude2 = new BigDecimal(lat2);
        BigDecimal longitude1 = new BigDecimal(lon1);
        BigDecimal longitude2 = new BigDecimal(lon2);

        BigDecimal lonVal = longitude1.subtract(longitude2).setScale(10, RoundingMode.HALF_UP);
        BigDecimal latVal = latitude1.subtract(latitude2).setScale(10, RoundingMode.HALF_UP);
        BigDecimal zeroVal = BigDecimal.ZERO.setScale(10,RoundingMode.HALF_UP);

        int lonJudge = lonVal.compareTo(zeroVal);
        int latJudge = latVal.compareTo(zeroVal);

        if (lonJudge == 0 || latJudge == 0) {
            if (latJudge != 0) {
                return latVal.abs();
            } else if (lonJudge != 0) {
                return lonVal.abs();
            }
            return BigDecimal.ZERO;
        } else {
            double lonPow = Math.pow(lonVal.doubleValue(),2) * 111 * Math.cos(latitude1.doubleValue()*Math.PI/180);
            double latPow = Math.pow(latVal.doubleValue(),2) * 111;
            distance = Math.sqrt(Math.pow(lonPow,2) + Math.pow(latPow,2));
        }
        BigDecimal distanceVal = new BigDecimal(distance);
        return distanceVal;
    }

}
