package utils; public class GeoIntermediate { // Earths radius in km static final double EarthRadius = 6371.0; private double coords[][]; private enum navigationEnum { RHUMB, ARC } private navigationEnum navigationSwitcher; public GeoIntermediate(double startLon, double startLat, double endLon, double endLat, int sliceCount) { navigationSwitcher = navigationEnum.RHUMB; // Calculate full distance double distance = 0; switch (navigationSwitcher) { case RHUMB: distance = Utils.rhumbDistance(startLon, startLat, endLon, endLat); break; case ARC: distance = Utils.greatCircDistSpherLawCos(startLon, startLat, endLon, endLat); break; } double distanceSlice = distance / (double) sliceCount; // Convert to radians double rlon1 = Utils.longNormalise(Math.toRadians(startLon)); double rlat1 = Math.toRadians(startLat); double rlon2 = Utils.longNormalise(Math.toRadians(endLon)); double rlat2 = Math.toRadians(endLat); coords = new double[sliceCount + 1][2]; coords[0][0] = startLon; coords[0][1] = startLat; coords[sliceCount][0] = endLon; coords[sliceCount][1] = endLat; for (int i = 1; i < sliceCount; i++) { distance = distanceSlice; double rDist = distance / EarthRadius; double bearing = 0; // Calculate the bearing switch (navigationSwitcher) { case RHUMB: bearing = Utils.rhumbBearing(rlon1, rlat1, rlon2, rlat2); break; case ARC: bearing = Utils.bearing(rlon1, rlat1, rlon2, rlat2); break; } // use the bearing and the start point to find the // destination double newLonRad = Utils.longNormalise(rlon1 + Math.atan2(Math.sin(bearing) * Math.sin(rDist) * Math.cos(rlat1), Math.cos(rDist) - Math.sin(rlat1) * Math.sin(rlat2))); double newLatRad = Math.asin(Math.sin(rlat1) * Math.cos(rDist) + Math.cos(rlat1) * Math.sin(rDist) * Math.cos(bearing)); // Convert from radians to degrees double newLat = Math.toDegrees(newLatRad); double newLon = Math.toDegrees(newLonRad); coords[i][0] = newLon; coords[i][1] = newLat; // This updates the input to calculate new bearing rlon1 = newLonRad; rlat1 = newLatRad; switch (navigationSwitcher) { case RHUMB: distance = Utils.rhumbDistance(newLon, newLat, endLon, endLat); break; case ARC: distance = Utils.greatCircDistSpherLawCos(newLon, newLat, endLon, endLat); break; } distanceSlice = distance / (sliceCount - i); }// END: sliceCount loop }// END: RhumbIntermediate() public double[][] getCoords() { return coords; } public void setRhumbNavigation() { navigationSwitcher = navigationEnum.RHUMB; } public void setArcNavigation() { navigationSwitcher = navigationEnum.ARC; } }// END: RhumbIntermediate class