已知经纬度 计算距离的原理和方法

网上有很多资料都只讲个大概,对于我这种数学渣渣来说比较难理解(曾经学校里的都还给老师了),现在把计算的原理梳理一下。

计算经纬度坐标距离的原理就是就算球面两点间的距离,经纬度表示法实际是用角度描述的坐标。纬度上下一共180度,经度360度。

假设地球是标准的球形,计算距离就等于计算一个截面圆的弧长。计算弧长的话需要先求出两点相对于球芯的夹角。然后根据半径就可以求出弧长了,也就是距离。

假设A点纬度lat1,精度lng1.B点纬度lat2, 经度lng2, 地球半径为R

求这个夹角之前,先把坐标转换为直角空间坐标系的点,并让地心为坐标中心点,即
A(Rcos(lat1)cos(lng1),  Rcos(lat1)sin(lng1), Rsin(lat1))
B(R
cos(lat2)cos(lng2),  Rcos(lat2)sin(lng2), Rsin(lat2))

然后算夹角,这里用向量的夹角计算方法,可以求出夹角余弦值,那么夹角COS为
COS = (向量A*向量B) / (向量A的模 * 向量B的模)

令A为(x,y,z),B(a,b,c)
COS = (xa+yb+zc)/[√(x2+y2+z2)*√(a2+b2+c2)]

把经纬度的坐标代进去
COS = cos(lat2) * cos(lat1) * cos(lng1-lng2) + sin(lat2)*sin(lat1)

得到夹角的余弦值可得角度,然后就可以算出弧长了,即得距离(arccos 为反余弦函数,这里反余弦的结果得到的是弧度)
d = 2PIR * (arccos(COS) / 2 * PI)
d = R * arccos(COS)
最终
d = R * arccos( cos(lat2) * cos(lat1) * cos(lng2-lng1) + sin(lat2)*sin(lat1))

嗯,那么就是半径乘以夹角的弧度值....弧度的定义好像这么来的哈

java代码

/**
     * 计算距离
     * @param lat1 纬度
     * @param lng1 经度
     * @param lat2 纬度
     * @param lng2 经度
     * @return 距离 KM
     */
    public static double distance(double lat1, double lng1, double lat2, double lng2) {

        //转弧度
        lat1 = lat1  * Math.PI / 180;
        lat2 = lat2  * Math.PI / 180;
        lng1 = lng1  * Math.PI / 180;
        lng2 = lng2  * Math.PI / 180;

        double cos = Math.cos(lat2) * Math.cos(lat1) * Math.cos(lng2 -lng1) + Math.sin(lat1) * Math.sin(lat2);
        return EARTH_R * Math.acos(cos);
    }

要注意经纬度是角度,而一些库API给的是弧度参数。

验证

public static void main(String[] args) {
        double lat1 = 23;
        double lng1 = 113;
        double lat2 = 25;
        double lng2 = 114;

        System.out.println(distance(lat1, lng1, lat2, lng2));
    }

输出为 244.48810435,和谷歌地球上的差不多

你可能感兴趣的:(已知经纬度 计算距离的原理和方法)