2 * ============LICENSE_START====================================================
4 * ===========================================================================
5 * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6 * ===========================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END====================================================
22 package org.onap.aaf.cadi.routing;
24 import org.onap.aaf.misc.env.util.Split;
26 public class GreatCircle {
27 // Note: multiplying by this constant is faster than calling Math equivalent function
28 private static final double DEGREES_2_RADIANS = Math.PI/180.0;
30 public static final double DEGREES_2_NM = 60;
31 public static final double DEGREES_2_KM = DEGREES_2_NM * 1.852; // 1.852 is exact ratio per 1929 Standard Treaty, adopted US 1954
32 public static final double DEGREES_2_MI = DEGREES_2_NM * 1.1507795;
36 * Calculate the length of an arc on a perfect sphere based on Latitude and Longitudes of two points
37 * Parameters are in Degrees (i.e. the coordinate system you get from GPS, Mapping WebSites, Phones, etc)
39 * L1 = Latitude of point A
40 * G1 = Longitude of point A
41 * L2 = Latitude of point B
42 * G2 = Longitude of point B
44 * d = acos (sin(L1)*sin(L2) + cos(L1)*cos(L2)*cos(G1 - G2))
46 * Returns answer in Degrees
48 * Since there are 60 degrees per nautical miles, you can convert to NM by multiplying by 60
50 * Essential formula from a Princeton website, the "Law of Cosines" method.
52 * Refactored cleaned up for speed Jonathan 3/8/2013
60 public static double calc(double latA, double lonA, double latB, double lonB) {
61 // Formula requires Radians. Expect Params to be Coordinates (Degrees)
62 // Simple ratio, quicker than calling Math.toRadians()
63 latA *= DEGREES_2_RADIANS;
64 lonA *= DEGREES_2_RADIANS;
65 latB *= DEGREES_2_RADIANS;
66 lonB *= DEGREES_2_RADIANS;
69 Math.sin(latA) * Math.sin(latB) +
70 Math.cos(latA) * Math.cos(latB) * Math.cos(lonA-lonB)
76 * Convert from "Lat,Long Lat,Long" String format
77 * "Lat,Long,Lat,Long" Format
78 * or all four entries "Lat Long Lat Long"
80 * (Convenience function)
82 * Since Distance is positive, a "-1" indicates an error in String formatting
84 public static double calc(String ... coords) {
87 switch(coords.length) {
89 array = Split.split(',',coords[0]);
90 if(array.length!=4)return -1;
92 Double.parseDouble(array[0]),
93 Double.parseDouble(array[1]),
94 Double.parseDouble(array[2]),
95 Double.parseDouble(array[3])
98 array = Split.split(',',coords[0]);
99 String [] array2 = Split.split(',',coords[1]);
100 if(array.length!=2 || array2.length!=2)return -1;
102 Double.parseDouble(array[0]),
103 Double.parseDouble(array[1]),
104 Double.parseDouble(array2[0]),
105 Double.parseDouble(array2[1])
109 Double.parseDouble(coords[0]),
110 Double.parseDouble(coords[1]),
111 Double.parseDouble(coords[2]),
112 Double.parseDouble(coords[3])
118 } catch (NumberFormatException e) {
126 //* Haverside method, from Princeton
134 //public static double calc3(double alat, double alon, double blat, double blon) {
135 // alat *= DEGREES_2_RADIANS;
136 // alon *= DEGREES_2_RADIANS;
137 // blat *= DEGREES_2_RADIANS;
138 // blon *= DEGREES_2_RADIANS;
139 // return 2 * Math.asin(
140 // Math.min(1, Math.sqrt(
141 // Math.pow(Math.sin((blat-alat)/2), 2) +
142 // (Math.cos(alat)*Math.cos(blat)*
144 // Math.sin((blon-alon)/2),2)
149 // / DEGREES_2_RADIANS;
155 //This is a MEAN radius. The Earth is not perfectly spherical
156 // public static final double EARTH_RADIUS_KM = 6371.0;
157 // public static final double EARTH_RADIUS_NM = 3440.07;
158 // public static final double KM_2_MILES_RATIO = 0.621371192;
160 //* Code on Internet based on Unknown book. Lat/Long is in Degrees
167 //public static double calc1(double alat, double alon, double blat, double blon) {
168 // alat *= DEGREES_2_RADIANS;
169 // alon *= DEGREES_2_RADIANS;
170 // blat *= DEGREES_2_RADIANS;
171 // blon *= DEGREES_2_RADIANS;
174 // double cosAlat,cosBlat;
177 // ((cosAlat=Math.cos(alat))*Math.cos(alon)*(cosBlat=Math.cos(blat))*Math.cos(blon)) +
178 // (cosAlat*Math.sin(alon)*cosBlat*Math.sin(blon)) +
179 // (Math.sin(alat)*Math.sin(blat))
180 // )/DEGREES_2_RADIANS;
185 * This method was 50% faster than calculation 1, and 75% than the Haverside method
186 * Also, since it's based off of Agree standard Degrees of the Earth, etc, the calculations are more exact,
187 * at least for Nautical Miles and Kilometers