GeoUtils.java 1.88 KB
package com.bsth.util;

import com.bsth.entity.Point;

/**
 * Created by panzhao on 2016/12/23.
 */
public class GeoUtils {

    private final static double EARTH_RADIUS = 6378137;

    public static double getDistance(Point p1, Point p2) {
        double lng1 = getLoop(p1.getLon(), -180, 180), lat1 = getRange(
                p1.getLat(), -74, 74);
        double lng2 = getLoop(p2.getLon(), -180, 180), lat2 = getRange(
                p2.getLat(), -74, 74);

        double x1, x2, y1, y2;
        x1 = degreeToRad(lng1);
        y1 = degreeToRad(lat1);
        x2 = degreeToRad(lng2);
        y2 = degreeToRad(lat2);
        return EARTH_RADIUS
                * Math.acos((Math.sin(y1) * Math.sin(y2) + Math.cos(y1)
                * Math.cos(y2) * Math.cos(x2 - x1)));
    }

    private static double getLoop(double v, double a, double b) {
        while (v > b) {
            v -= b - a;
        }
        while (v < a) {
            v += b - a;
        }
        return v;
    }

    private static double getRange(double v, double a, double b) {
        v = Math.min(Math.max(v, a), b);
        return v;
    }

    private static double degreeToRad(double degree) {
        return Math.PI * degree / 180;
    }

    /**
     * 计算点 到 线的距离
     * @param line
     * @param p
     * @return
     */
    public static double getDistanceFromLine(Point s, Point e, Point p){
        double d1 = getDistance(s, p);
        double d2 = getDistance(p, e);
        double d3 = getDistance(s, e);
        double distance = 0;

        double alpha = Math.acos((d1*d1 + d3*d3 - d2*d2)/(2*d1*d3));
        double beta = Math.acos((d2*d2 + d3*d3 - d1*d1)/(2*d2*d3));

        if(alpha>Math.PI/2) {
            distance = d1;
        }
        else if(beta > Math.PI/2) {
            distance = d2;
        }
        else {
            distance = Math.sin(alpha) * d1;
        }
        return distance;
    }
}