/* * Author: Cedric Holzl - Mohamed Khadri * Sciper: 257844 - 261203 */ package ch.epfl.alpano; import java.util.Locale; import static java.lang.Math.abs; import static java.lang.Math.cos; import static java.lang.Math.sin; import static java.lang.Math.PI; import static java.lang.Math.atan2; import static java.lang.Math.sqrt; import static java.lang.Math.toDegrees; import static ch.epfl.alpano.Preconditions.checkArgument; import static ch.epfl.alpano.Math2.haversin; import static ch.epfl.alpano.Distance.toMeters; import static ch.epfl.alpano.Azimuth.fromMath; import static ch.epfl.alpano.Azimuth.canonicalize; /** * Definition of a geographical point on Earth's surface using spherical * coordinates. */ public class GeoPoint { private final double longitude; private final double latitude; /** * Constructor of a GeoPoint * * @param longitude * : longitude position * @param latitude * : latitude position * @throws IllegalArgumentException * if longitude is not in [−Pi;Pi] or latitude is not in * [−2Pi;2Pi] */ public GeoPoint(double longitude, double latitude) { checkArgument(!(abs(longitude) > PI || abs(latitude) * 2.0 > PI)); this.longitude = longitude; this.latitude = latitude; } /** * Returns the longitude value of the GeoPoint * * @return longitude */ public double longitude() { return this.longitude; } /** * Returns the latitude value of the GeoPoint * * @return latitude */ public double latitude() { return this.latitude; } /** * Computes the distance between two points * * @param that * : a GeoPoint * @return distance in meters between two points */ public double distanceTo(GeoPoint that) { return toMeters( 2 * Math.asin(sqrt(haversin(this.latitude - that.latitude) + cos(this.latitude) * cos(that.latitude) * haversin(this.longitude - that.longitude)))); } /** * Mathematical angular distance from a geoPoint to another * * @param that * @return angle expressed in radian in the mathematical convention */ private double mathAzimuthTo(GeoPoint that) { return atan2( (sin(this.longitude - that.longitude) * cos(that.latitude)), (cos(this.latitude) * sin(that.latitude) - sin(this.latitude) * cos(that.latitude) * cos(this.longitude - that.longitude))); } /** * Angular distance from a geoPoint to another in azimuth * * @param that * : a GeoPoint * @return angle expressed in radian in the azimuth convention */ public double azimuthTo(GeoPoint that) { return fromMath(canonicalize(mathAzimuthTo(that))); } /** * Redefines the to String method * * @return a string , [lon,lat], lon and lat being the longitude and * latitude values of the GeoPoint */ @Override public String toString() { return String.format((Locale) null, "(%.4f,%.4f)", toDegrees(this.longitude), toDegrees(this.latitude)); } }