package gmt.common.util;

import java.text.DecimalFormat;

public class GeoUitls {
	/**
     * 두 좌표 거리 구하기
     * @param latitude1 Start latitude
     * @param longitude1 Start longitude
     * @param latitude2 End latitude
     * @param longitude2 End longitude
     * @return Distance(NM)
     */
    public static double geoDistance(double latitude1, double longitude1, double latitude2, double longitude2) {

        DecimalFormat df = new DecimalFormat("#.#####");

        if ((latitude1 == latitude2) && (longitude1 == longitude2)) {
            return 0;
        } else {
            double theta = longitude1 - longitude2;
            double distance = Math.sin(Math.toRadians(latitude1)) * Math.sin(Math.toRadians(latitude2)) +
                    Math.cos(Math.toRadians(latitude1)) * Math.cos(Math.toRadians(latitude2)) * Math.cos(Math.toRadians(theta));
            distance = Math.acos(distance);
            distance = Math.toDegrees(distance);
            distance = distance * 60 * 1.1515;
            distance = distance * 1.609344;

            //distance --> 0보다 클 경우
            if (0 < distance) {
                distance = Double.valueOf(df.format(distance));    //소숫점 다섯째 자리에서 반올림

                // distance --> 0일 경우
            } else {
                distance = 0;
            }

            distance = distance * 1.000/1.852; //km --> NM으로 변환

            return distance;
        }

    }
    
    /**
     * 두 좌표 방위각 구하기
     * @param latitude1 Start latitude
     * @param longitude1 Start longitude
     * @param latitude2 End latitude
     * @param longitude2 End longitude
     * @return bearing
     */
    public static Double bearingP1toP2(double latitude1, double longitude1, double latitude2, double longitude2) {
    	if (latitude1 == latitude2 && longitude1 == longitude2) {
    		return 0.0;
    	} else if (longitude1 == longitude2) {
    		if (latitude1 > latitude2) {
    			return 180.0;
    		}    		
    	} else if (latitude1 == latitude2) {
    		if (longitude1 > longitude2) {
    			return 270.0;
    		} else {
    			return 90.0;    			
    		}
    	} 
    	
        // 현재 위치 : 라디안
        double Cur_Lat_radian = latitude1 * (Math.PI / 180);
        double Cur_Lon_radian = longitude1 * (Math.PI / 180);

        // 목표 위치 : 라디안
        double Dest_Lat_radian = latitude2 * (Math.PI / 180);
        double Dest_Lon_radian = longitude2 * (Math.PI / 180);

        // radian distance
        double radian_distance = 0;
        radian_distance = Math.acos(Math.sin(Cur_Lat_radian) * Math.sin(Dest_Lat_radian)
                + Math.cos(Cur_Lat_radian) * Math.cos(Dest_Lat_radian) * Math.cos(Cur_Lon_radian - Dest_Lon_radian));

        // 목적지 이동 방향(라디안)
        double radian_bearing = Math.acos((Math.sin(Dest_Lat_radian) - Math.sin(Cur_Lat_radian)
                * Math.cos(radian_distance)) / (Math.cos(Cur_Lat_radian) * Math.sin(radian_distance)));

        double true_bearing = 0;
        if (Math.sin(Dest_Lon_radian - Cur_Lon_radian) < 0) {
            true_bearing = radian_bearing * (180 / Math.PI);
            true_bearing = 360 - true_bearing;
        } else {
            true_bearing = radian_bearing * (180 / Math.PI);
        }

        return (Double) true_bearing;
    }
 
}
