persolijn

an efficient router for busses
Log | Files | Refs

Point.java (6135B)


      1 package osm.geo;
      2 
      3 import java.util.Collection;
      4 
      5 import osm.common.ArrayIterable;
      6 
      7 /**
      8  * Represents a geographical point with latitude and longitude coordinates.
      9  */
     10 public interface Point {
     11 
     12     /** Earth radius in kilometers. */
     13     public static final int EARTH_RADIUS = 6371;
     14 
     15     /** Threshold for direct distance in meters squared. */
     16     public static final double DIRECT_DISTANCE_THRESHOLD = 50 * 50;
     17 
     18     /**
     19      * Calculates the distance between two points using their latitude and
     20      * longitude.
     21      *
     22      * @param a The first point.
     23      * @param b The second point.
     24      * @return The distance between the two points in meters.
     25      */
     26     public static long distance(Point a, Point b) {
     27         return distance(a.getLatitude(), a.getLongitude(), b.getLatitude(), b.getLongitude());
     28     }
     29 
     30     /**
     31      * Calculates the distance between a point and specified latitude and longitude.
     32      *
     33      * @param aLat The latitude of the first point.
     34      * @param aLon The longitude of the first point.
     35      * @param b    The second point.
     36      * @return The distance between the two points in meters.
     37      */
     38     public static long distance(double aLat, double aLon, Point b) {
     39         return distance(aLat, aLon, b.getLatitude(), b.getLongitude());
     40     }
     41 
     42     /**
     43      * Calculates the distance between two sets of latitude and longitude
     44      * coordinates.
     45      *
     46      * @param aLat The latitude of the first point.
     47      * @param aLon The longitude of the first point.
     48      * @param bLat The latitude of the second point.
     49      * @param bLon The longitude of the second point.
     50      * @return The distance between the two points in meters.
     51      */
     52     public static long distance(double aLat, double aLon, double bLat, double bLon) {
     53         aLat = Math.toRadians(aLat);
     54         bLat = Math.toRadians(bLat);
     55         aLon = Math.toRadians(aLon);
     56         bLon = Math.toRadians(bLon);
     57 
     58         double a = 0.5 - Math.cos(bLat - aLat) / 2 + Math.cos(aLat) * Math.cos(bLat) * (1 - Math.cos(bLon - aLon)) / 2;
     59 
     60         return Math.round(2.0 * 1000 * EARTH_RADIUS * Math.asin(Math.sqrt(a)));
     61     }
     62 
     63     /**
     64      * Calculates the center point of a collection of points.
     65      *
     66      * @param points The collection of points.
     67      * @return The center point.
     68      */
     69     public static Point center(Collection<? extends Point> points) {
     70         double lat = 0;
     71         double lon = 0;
     72 
     73         for (Point point : points) {
     74             lat += point.getLatitude();
     75             lon += point.getLongitude();
     76         }
     77 
     78         return Point.of(lat / points.size(), lon / points.size());
     79     }
     80 
     81     /**
     82      * Calculates the angle formed by three points.
     83      *
     84      * @param a The first point.
     85      * @param b The second point.
     86      * @param c The third point.
     87      * @return The angle in radians.
     88      */
     89     public static double getAngle(Point a, Point b, Point c) {
     90         if (a == null)
     91             return 0;
     92 
     93         return Math.atan2(c.getLongitude() - a.getLongitude(), c.getLatitude() - a.getLatitude()) -
     94                 Math.atan2(b.getLongitude() - a.getLongitude(), b.getLatitude() - a.getLatitude());
     95     }
     96 
     97     /**
     98      * Calculates the total distance along a path defined by an array of points.
     99      *
    100      * @param path The array of points defining the path.
    101      * @return The total distance along the path in meters.
    102      */
    103     public static long distance(Point... path) {
    104         return distance(new ArrayIterable<>(path));
    105     }
    106 
    107     /**
    108      * Calculates the total distance along a path defined by an iterable collection
    109      * of points.
    110      *
    111      * @param path The iterable collection of points defining the path.
    112      * @return The total distance along the path in meters.
    113      */
    114     public static long distance(Iterable<? extends Point> path) {
    115         long dist = 0;
    116         Point prev = null;
    117 
    118         for (Point current : path) {
    119             if (prev != null)
    120                 dist += Point.distance(prev, current);
    121 
    122             prev = current;
    123         }
    124 
    125         return dist;
    126     }
    127 
    128     /**
    129      * Creates a new Point instance with the specified latitude and longitude.
    130      *
    131      * @param latitude  The latitude of the point.
    132      * @param longitude The longitude of the point.
    133      * @return A new Point instance.
    134      */
    135     public static Point of(double latitude, double longitude) {
    136         return new Point() {
    137             @Override
    138             public double getLatitude() {
    139                 return latitude;
    140             }
    141 
    142             @Override
    143             public double getLongitude() {
    144                 return longitude;
    145             }
    146 
    147             @Override
    148             public boolean equals(Object other) {
    149                 if (!(other instanceof Point))
    150                     return false;
    151 
    152                 return latitude == ((Point) other).getLatitude()
    153                         && longitude == ((Point) other).getLongitude();
    154             }
    155 
    156             @Override
    157             public int hashCode() {
    158                 return Double.hashCode(latitude) + Double.hashCode(longitude);
    159             }
    160 
    161             @Override
    162             public String toString() {
    163                 return String.format("Point[%f, %f]", getLatitude(), getLongitude());
    164             }
    165         };
    166     }
    167 
    168     /**
    169      * Calculates the distance from this point to another point.
    170      *
    171      * @param other The other point.
    172      * @return The distance to the other point in meters.
    173      */
    174     default long distanceTo(Point other) {
    175         return distance(this, other);
    176     }
    177 
    178     /**
    179      * Calculates the distance from this point to a specified latitude and
    180      * longitude.
    181      *
    182      * @param latitude  The latitude of the target point.
    183      * @param longitude The longitude of the target point.
    184      * @return The distance to the target point in meters.
    185      */
    186     default long distanceTo(double latitude, double longitude) {
    187         return distance(latitude, longitude, this);
    188     }
    189 
    190     /**
    191      * Gets the latitude of the point.
    192      *
    193      * @return The latitude.
    194      */
    195     double getLatitude();
    196 
    197     /**
    198      * Gets the longitude of the point.
    199      *
    200      * @return The longitude.
    201      */
    202     double getLongitude();
    203 }