/*
* Copyright (C) 2014 Jason M. Heim
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jasonmheim.rollout.data;
import static java.lang.Math.PI;
import static java.lang.Math.acos;
import static java.lang.Math.atan2;
import static java.lang.Math.cos;
import static java.lang.Math.sin;
import static java.lang.Math.toDegrees;
/**
* Utility methods for calculating geographic distance and direction between points
*/
class GeoUtils {
// 16 point compass where N is at index 0, counting up clockwise from there.
private static final String[] DIRECTIONS = {
"N",
"NNE",
"NE",
"ENE",
"E",
"ESE",
"SE",
"SSE",
"S",
"SSW",
"SW",
"WSW",
"W",
"WNW",
"NW",
"NNW",
};
static double distanceInMiles(double lat1, double lon1, double lat2, double lon2) {
double dist = acos(sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(lon2 - lon1));
dist = toDegrees(dist);
dist = dist * 60 * 1.1515;
return (dist);
}
static String compassDirection(double lat1, double lon1, double lat2, double lon2) {
double theta = lon2 - lon1;
double dy = sin(theta) * cos(lat2);
double dx = (cos(lat1) * sin(lat2)) - (sin(lat1) * cos(lat2) * cos(theta));
// Get the arctangent in radians, measuring clockwise from true north.
// Normalize to a range from -8 to 8, which represents 16 tick marks on the compass
// Add 16.5 - this is one full rotation plus half a tick mark so that we can round down
// Compute modulo 16 to ensure range 0 to 16.
// Round down by casting to an int to get a compass point index.
int compassPoint = (int) (((atan2(dy, dx) * 8 / PI) + 16.5) % 16);
return DIRECTIONS[compassPoint];
}
}