/**
 * Calculation of the geographic midpoint (also known as the geographic center,
 * or center of gravity) for two or more points on the earth's surface Ref:
 * http://www.geomidpoint.com/calculation.html
 *
 * @param points
 * @return
 */
public static Point2D.Double midpoint(List<Point2D.Double> points) {
    double Totweight = 0;
    double xt = 0;
    double yt = 0;
    double zt = 0;
    for (Point2D.Double point : points) {
        Double latitude = point.x;
        Double longitude = point.y;

        /**
         * Convert Lat and Lon from degrees to radians.
         */
        double latn = latitude * Math.PI / 180;
        double lonn = longitude * Math.PI / 180;

        /**
         * Convert lat/lon to Cartesian coordinates
         */
        double xn = Math.cos(latn) * Math.cos(lonn);
        double yn = Math.cos(latn) * Math.sin(lonn);
        double zn = Math.sin(latn);

        /**
         * Compute weight (by time) If locations are to be weighted equally,
         * set wn to 1
         */
        double years = 0;
        double months = 0;
        double days = 0;
        double wn = true ? 1 : (years * 365.25) + (months * 30.4375) + days;

        /**
         * Compute combined total weight for all locations.
         */
        Totweight = Totweight + wn;
        xt += xn * wn;
        yt += yn * wn;
        zt += zn * wn;
    }

    /**
     * Compute weighted average x, y and z coordinates.
     */
    double x = xt / Totweight;
    double y = yt / Totweight;
    double z = zt / Totweight;

    /**
     * If abs(x) < 10-9 and abs(y) < 10-9 and abs(z) < 10-9 then the
     * geographic midpoint is the center of the earth.
     */
    double lat = -0.001944;
    double lon = -78.455833;
    if (Math.abs(x) < Math.pow(10, -9) && Math.abs(y) < Math.pow(10, -9) && Math.abs(z) < Math.pow(10, -9)) {
    } else {

        /**
         * Convert average x, y, z coordinate to latitude and longitude.
         * Note that in Excel and possibly some other applications, the
         * parameters need to be reversed in the atan2 function, for
         * example, use atan2(X,Y) instead of atan2(Y,X).
         */
        lon = Math.atan2(y, x);
        double hyp = Math.sqrt(x * x + y * y);
        lat = Math.atan2(z, hyp);

        /**
         * Convert lat and lon to degrees.
         */
        lat = lat * 180 / Math.PI;
        lon = lon * 180 / Math.PI;
    }
    LOG.log(Level.INFO, "MidPoint: {0}, {1}", new Object[]{lat, lon});
    return new Point2D.Double(lat, lon);
}