求解两个经纬点之间的距离和角度(mm级精度)

  

Distances and bearings between points on an ellipsoidal-model earth

Vincenty 对椭球体地球模型上点之间距离的解精确到0.5 mm距离,0.000015〃度。

基于球面地球模型的计算,例如(更简单的)哈弗斯线,精确到0.3%左右。

  We can use live examples at Vincenty’s solution 在线计算

  You can git the Matlab Version at git@github.com:Jason-Yoo/Vincenty-solutions.git

70%
% Author :  doudouyoutang                                                      
% Contact:  jiduocaiyang@gmail.com 
% Adress: NUAA
% License:  Copyright (c) 2020 Jiduocai Yang, All rights reserved 
% This programe is implemented in matlab 2019a
% Function: Vincenty Formula
% point[latitude  longitude ]
% distance between two points  Unit: meter
function [distance,Alpha1,Alpha2]=vincenty_inverse(point1, point2)
 
% WGS 84
a = 6378137;  % meters
f = 1 / 298.257223563;
b = 6356752.314245;  % meters; b = (1 - f)a

%MILES_PER_KILOMETER = 0.621371; 
MILES_PER_KILOMETER = 1;
MAX_ITERATIONS = 300;
CONVERGENCE_THRESHOLD = 1e-12;  % .000,000,000,001
convergenceFlag = 0;

% short-circuit coincident points
if (point1(1) == point2(1) && point1(2) == point2(2))
    distance = 0;
    Alpha1 = 0;
    Alpha2 = 0;
    return;
end
U1 = atan((1 - f) * tan(deg2rad(point1(1))));
U2 = atan((1 - f) * tan(deg2rad(point2(1))));
L = deg2rad(point2(2) - point1(2));
Lambda = L;

sinU1 = sin(U1);
cosU1 = cos(U1);
sinU2 = sin(U2);
cosU2 = cos(U2);

    while (--MAX_ITERATIONS>0)
        sinLambda = sin(Lambda);
        cosLambda = cos(Lambda);
        sinSigma = sqrt((cosU2 * sinLambda) ^ 2 + (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda) ^ 2);
        if(sinSigma == 0)
             break;  % coincident points
        end
        cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
        sigma = atan2(sinSigma, cosSigma);
        sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;
        cosSqAlpha = 1 - sinAlpha ^ 2;

        cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha;
        if (isnan(cos2SigmaM))
            cos2SigmaM = 0;
        end
        C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha));
        LambdaPrev = Lambda;
        Lambda = L + (1 - C) * f * sinAlpha * (sigma + C * sinSigma *(cos2SigmaM + C * cosSigma *(-1 + 2 * cos2SigmaM ^ 2)));
        if (abs(Lambda - LambdaPrev) < CONVERGENCE_THRESHOLD)
            convergenceFlag = 1;
            break  % successful convergence
        end

    end
    if(convergenceFlag == 1)
        uSq = cosSqAlpha * (a ^ 2 - b ^ 2) / (b ^ 2);
        A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
        B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
        deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma *(-1 + 2 * cos2SigmaM ^ 2) - B / 6 * cos2SigmaM *(-3 + 4 * sinSigma ^ 2) * (-3 + 4 * cos2SigmaM ^ 2)));
        s = b * A * (sigma - deltaSigma);
        Alpha1 = atan2(cosU2 * sinLambda,  cosU1*sinU2-sinU1*cosU2*cosLambda);
        Alpha1 = Alpha1*180/pi;
        if (0 >= Alpha1 || Alpha1 > 360)
             Alpha1 = mod(mod(Alpha1,360)+360,360); 
        end
        Alpha2 = atan2(cosU1 * sinLambda,  -sinU1*cosU2+cosU1*sinU2*cosLambda);
        distance = s * MILES_PER_KILOMETER;  % kilometers to miles
    else
        distance = 0;
        Alpha1 = 0;
        Alpha2 = 0;
    end

end

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Reign_Man/article/details/111511409

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值