package com.younike.common.utils.geo;

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

public class DistanceUtil {
    /**
     * 定义 地球半径
     */
    private static final BigDecimal EARTH_RADIUS = new BigDecimal(6378.137);

    /**
     * 定义 Math.PI
     */
    private static final BigDecimal MATH_PI = new BigDecimal(Math.PI);

    /**
     * 计算弧长
     **/
    private static BigDecimal getRed(BigDecimal big) {
        return big.multiply(MATH_PI).divide(new BigDecimal(180), BigDecimal.ROUND_DOWN);
    }

    public static BigDecimal format(BigDecimal big, int scale) {
        scale = 0 > scale ? 0 : scale;
        big = big.setScale(scale, BigDecimal.ROUND_HALF_UP);
        return big;
    }

    /**
     * 计算 两点 之间  的 最短距离 <br/>
     * 返回 数据 为 两点之间的 公里数
     */
    public static BigDecimal getShortestDistance(BigDecimal lat1, BigDecimal lng1,
                                                 BigDecimal lat2, BigDecimal lng2) {

        BigDecimal radLat1 = getRed(lat1);
        BigDecimal radLat2 = getRed(lat2);
        BigDecimal a = radLat1.subtract(radLat2);
        BigDecimal b = getRed(lng1).subtract(getRed(lng2));

        Double sinA = Math.sin(a.doubleValue() / 2);
        Double sinB = Math.sin(b.doubleValue() / 2);
        Double cosA = radLat1.doubleValue();
        Double cosB = radLat2.doubleValue();

        Double obj = 2 * Math.asin(Math.sqrt(Math.pow(sinA, 2) + Math.cos(cosA) * Math.cos(cosB) * Math.pow(sinB, 2)));
        BigDecimal s = new BigDecimal(obj);
        s = s.multiply(EARTH_RADIUS);
        return format(s, 3);
    }

    /**
     * 附近n公里经纬度方形范围
     *
     * @param longitude 经度
     * @param latitude 纬度
     * @param distance 搜索范围（n公里）
     * @return 经纬度范围
     */
    public static GeoSquare calcGeoSquareData(double longitude, double latitude, double distance) {
        GeoSquare.GeoSquareBuilder geoSquareBuilder = GeoSquare.builder();
        // 地球半径(千米)
        double r = EARTH_RADIUS.doubleValue();
        double dlng = 2 * Math.asin(Math.sin(distance / (2 * r))
                / Math.cos(longitude * Math.PI / 180));
        // 角度转为弧度
        dlng = dlng * 180 / Math.PI;
        double dlat = distance / r;
        dlat = dlat * 180 / Math.PI;
        if (dlng < 0) {
            geoSquareBuilder.minLng(longitude + dlng);
            geoSquareBuilder.maxLng(longitude - dlng);
        } else {
            geoSquareBuilder.minLng(longitude - dlng);
            geoSquareBuilder.maxLng(longitude + dlng);
        }
        if (dlat < 0) {
            geoSquareBuilder.minLat(latitude + dlat);
            geoSquareBuilder.maxLat(latitude - dlat);
        } else {
            geoSquareBuilder.minLat(latitude - dlat);
            geoSquareBuilder.maxLat(latitude + dlat);
        }
        return geoSquareBuilder.build();
    }

    /**
     * 2021-11-23 Another 根据 传入的km 转化（1km下显示米，1km以上保留一位小数）
     * @param distance 距离（千米）
     * @return
     */
    public static String conversionDistance(BigDecimal distance) {
        if (distance == null) {
            return "";
        }
        if (distance.compareTo(new BigDecimal(1)) < 0) {
            return distance.multiply(new BigDecimal(1000)).stripTrailingZeros().toPlainString() + "米";
        } else {
            return distance.setScale(1, RoundingMode.HALF_DOWN).stripTrailingZeros().toPlainString() + "km";
        }
    }

}
