经纬度和距离之间的计算

不是我写的, 也看不太懂, 备忘

package com.iwhere.easy.travel.tool;

import org.junit.Test;
import org.springframework.util.Assert;

/**
 */
public class GeoUtils {

    public final static float EARTH_RADIUS = 6378137; // 地球半径

    @Test
    public void test2() {
//        GeoUtils.getBoxByCoordinate(120.0, 40.0, 2000.0);
        Double distance = GeoUtils.getDistance(new Point(119.9765412051408, 39.98202952055585),
                new Point(120.0234587948592, 40.01797047944415));
        System.out.println(distance);
    }
    
    /**
     * 根据中心点获取box
     * 
     * @return
     */
    public static Double[] getBoxByCoordinate(Double longitude, Double latitude, Double raidusMile) {
        Assert.notNull(longitude);
        Assert.notNull(latitude);

        Double degree = (24901 * 1609) / 360.0; // 获取每度弧长

        Double mpdLng = Double.parseDouble((degree * Math.cos(latitude * (Math.PI / 180)) + "").replace("-", ""));
        Double dpmLng = 1 / mpdLng;
        Double radiusLng = dpmLng * raidusMile;
        // 获取最小经度
        Double minLat = longitude - radiusLng;
        // 获取最大经度
        Double maxLat = longitude + radiusLng;

        Double dpmLat = 1 / degree;
        Double radiusLat = dpmLat * raidusMile;
        // 获取最小纬度
        Double minLng = latitude - radiusLat;
        // 获取最大纬度
        Double maxLng = latitude + radiusLat;
        System.out.println(minLat + ": " + maxLat + ": " + minLng + ": " + maxLng);
        return null;
    }

    /**
     * 获取距离
     * 
     * @param from
     *            开始点
     * @param to
     *            结束点
     * @return
     */
    public static Double getDistance(Point from, Point to) {
        if (from == null || to == null || from.getLat() == null || from.getLng() == null || to.getLat() == null
                || to.getLng() == null) {
            return Double.NaN;
        } else {
            double lat1 = from.getLat() * Math.PI / 180.0;
            double lat2 = to.getLat() * Math.PI / 180.0;
            double a = lat1 - lat2;
            double b = (from.getLng() - to.getLng()) * Math.PI / 180.0;

            double sa2, sb2;
            sa2 = Math.sin(a / 2.0);
            sb2 = Math.sin(b / 2.0);
            return 2 * EARTH_RADIUS * Math.asin(Math.sqrt(sa2 * sa2 + Math.cos(lat1) * Math.cos(lat2) * sb2 * sb2));
        }
    }

    /**
     * 
     * ---------------------------------------------------------------------------
     * 点
     * ---------------------------------------------------------------------------
     * <strong>copyright</strong>: ©版权所有 成都都在哪网讯科技有限公司<br>
     * ----------------------------------------------------------------------------
     * 
     * @author: hewei
     * @time:2016年10月28日 下午6:29:22
     *                   ---------------------------------------------------------------------------
     */
    public static class Point {
        public Double lat; // 纬度
        public Double lng; // 经度

        /**
         * 
         */
        public Point() {
            super();
        }

        /**
         * @param lat
         * @param lng
         */
        public Point(Double lat, Double lng) {
            super();
            this.lat = lat;
            this.lng = lng;
        }

        /**
         * @return the lat
         */
        public Double getLat() {
            return lat;
        }

        /**
         * @param lat
         *            the lat to set
         */
        public void setLat(Double lat) {
            this.lat = lat;
        }

        /**
         * @return the lng
         */
        public Double getLng() {
            return lng;
        }

        /**
         * @param lng
         *            the lng to set
         */
        public void setLng(Double lng) {
            this.lng = lng;
        }
    }
}

角度计算: 

package com.iwhere.easy.travel.tool;

import org.junit.Test;

public class GeoTools {

    public static double getAngle(double lat1, double lng1, double lat2, double lng2) {
        double x1 = lng1;
        double y1 = lat1;
        double x2 = lng2;
        double y2 = lat2;
        double pi = Math.PI;
        double w1 = y1 / 180 * pi;
        double j1 = x1 / 180 * pi;
        double w2 = y2 / 180 * pi;
        double j2 = x2 / 180 * pi;
        double ret;
        if (j1 == j2) {
            if (w1 > w2)
                return 270; // 北半球的情况,南半球忽略
            else if (w1 < w2)
                return 90;
            else
                return -1;// 位置完全相同
        }
        ret = 4 * Math.pow(Math.sin((w1 - w2) / 2), 2)
                - Math.pow(Math.sin((j1 - j2) / 2) * (Math.cos(w1) - Math.cos(w2)), 2);
        ret = Math.sqrt(ret);
        double temp = (Math.sin(Math.abs(j1 - j2) / 2) * (Math.cos(w1) + Math.cos(w2)));
        ret = ret / temp;
        ret = Math.atan(ret) / pi * 180;
        if (j1 > j2) { // 1为参考点坐标
            if (w1 > w2)
                ret += 180;
            else
                ret = 180 - ret;
        } else if (w1 > w2)
            ret = 360 - ret;
        return ret;
    }

    /**
     * @param lat1
     *            纬度1,参考点
     * @param lng1
     *            经度1,参考点
     * @param lat2
     *            纬度2
     * @param lng2
     *            经度2
     * @return 方向
     */
    public static String getDirection(double lat1, double lng1, double lat2, double lng2) {
        double jiaodu = getAngle(lat1, lng1, lat2, lng2);
        if ((jiaodu <= 10) || (jiaodu > 350))
            return "正东方";
        if ((jiaodu > 10) && (jiaodu <= 80))
            return "东北方";
        if ((jiaodu > 80) && (jiaodu <= 100))
            return "正北方";
        if ((jiaodu > 100) && (jiaodu <= 170))
            return "西北方";
        if ((jiaodu > 170) && (jiaodu <= 190))
            return "正西方";
        if ((jiaodu > 190) && (jiaodu <= 260))
            return "西南方";
        if ((jiaodu > 260) && (jiaodu <= 280))
            return "正南方";
        if ((jiaodu > 280) && (jiaodu <= 350))
            return "东南方";
        return "";
    }

    /**
     * 获取方位角描述
     * 前一个点
     * 参照点
     * 目标点
     * @return
     */
    public static String getAzimuth(double preLng, double preLat, double referLng, double referLat, double poiLng,
            double poiLat) {
        double jiaodu1 = getAngle(preLat, preLng, referLat, referLng);
        double jiaodu2 = getAngle(referLat, referLng, poiLat, poiLng);
        double jiaodu = jiaodu2 - jiaodu1;
        if (((jiaodu <=10 && jiaodu > 0) || jiaodu > 350) || ((jiaodu >= -10 && jiaodu < 0) || jiaodu < -350)) {
            return "正前方";
        }else if ((jiaodu <= 80 && jiaodu > 10) || (jiaodu >= -350 && jiaodu < -280)) {
            return "左前方";
        }else if ((jiaodu <= 100 && jiaodu > 80) || (jiaodu >= -280 && jiaodu < -260)) {
            return "左侧";
        }else if ((jiaodu <= 170 && jiaodu > 100) || (jiaodu >= -260 && jiaodu < -190)) {
            return "左后方";
        }else if ((jiaodu <= 190 && jiaodu > 170) || (jiaodu >= -190 && jiaodu < -170)) {
            return "后方";
        }else if ((jiaodu <=260 && jiaodu > 190) || (jiaodu >= -170 && jiaodu < -100)) {
            return "右后方";
        }else if ((jiaodu <=280 && jiaodu > 260) || (jiaodu >= -100 && jiaodu < -80)) {
            return "右侧";
        }else if ((jiaodu <= 350 && jiaodu > 280) || (jiaodu >= -80 && jiaodu < -10)) {
            return "右前方";
        }
        return "";
    }
    
    @Test
    public void test() {
        String azimuth = GeoTools.getAzimuth(0d, 0d, -40d, 20d, 30d, 30d);
        System.out.println(azimuth);
    }

    public static void main(String[] args) {
        String str = getDirection(0, 0, -40, -34);
        System.out.println(str);
    }
}

参考: http://blog.csdn.net/koryako/article/details/51864161

原文地址:https://www.cnblogs.com/wenbronk/p/7221325.html