2个地理坐标之间的中点

本文关键字:之间 坐标 2个 | 更新日期: 2023-09-27 18:00:07

我正在尝试开发一种涉及归一化GPS坐标(纬度/经度)的算法。这意味着,在给定两个点A(lat1,lon1)和B(lat2,lon2)的情况下,我想插入一个与AB(同一弧)线性的点C,该点与A和B相距特定距离(例如:A到B的距离为0.5km,我希望点C与A相距0.1km,在AB弧上)。如何计算C点的坐标?就给定的目的而言,将地球近似为一个完美的球形物体就足够了。我找到了这篇文章,但它只给出了中点的公式(为了适应,我还没有完全理解它)。两个纬度和经度之间的中点非常感谢。

编辑:我试过这个,但它给出了错误的答案

public static void normalizedPoint(double lat1, double lon1, double lat2, double lon2, double dist){
        double constant=Math.PI/180;
        double angular = dist/6371;
        double a = Math.Sin( 0* angular )/Math.Sin(angular);
        double b = Math.Sin(1*angular)/Math.Sin(angular);
        double x = a * Math.Cos(lat1) * Math.Cos(lon1) + b * Math.Cos(lat2) * Math.Cos(lon2);
        double y = a * Math.Cos(lat1) * Math.Sin(lon1) + b * Math.Cos(lat2) * Math.Sin(lon2);
        double z = a * Math.Sin(lat1) + b * Math.Sin (lon2);
        double lat3 = Math.Atan2(z, Math.Sqrt( x*x + y*y ));
        double lon3 = Math.Atan2(y, x);
        Console.WriteLine(lat3/constant + " " + lon3/constant );
    }

就我对原始公式的理解而言,这应该返回2个原始点中的一个,但它没有(因为使用的分数是1)。此外,变量dist是与2个点的距离,并且是正确计算的(使用同一网站进行检查)。

编辑2:我提供2个地理点(lat1、lon1、lat2-lon2)的坐标以及它们之间的距离作为输入。我想找一个中介点(lat3,lon3)。

2个地理坐标之间的中点

正如我在链接到问题的答案中指出的,您需要将所有输入更改为使用弧度,而不是度数

我相信您在z中也有一个错误,您使用了lon2而不是lat2

通过这些更正,我得到了你想要的答案:

    public static void normalizedPoint(double lat1, double lon1,
                                       double lat2, double lon2,
                                       double dist)
    {
        double constant = Math.PI / 180;
        double angular = dist / 6371;
        double a = Math.Sin(0 * angular) / Math.Sin(angular);
        double b = Math.Sin(1 * angular) / Math.Sin(angular);
        double x = a * Math.Cos(lat1* constant) * Math.Cos(lon1* constant) + 
                   b * Math.Cos(lat2* constant) * Math.Cos(lon2* constant);
        double y = a * Math.Cos(lat1* constant) * Math.Sin(lon1* constant) + 
                   b * Math.Cos(lat2* constant) * Math.Sin(lon2* constant);
        double z = a * Math.Sin(lat1* constant) + b * Math.Sin(lat2* constant);
        double lat3 = Math.Atan2(z, Math.Sqrt(x * x + y * y));
        double lon3 = Math.Atan2(y, x);
        Console.WriteLine(lat3 / constant + " " + lon3 / constant);
    }

当然,通过仅转换角度、避免重复计算相同的Sin/Cos值等,可以极大地简化上述过程。

呼叫:

normalizedPoint(47.20761, 27.02185, 47.20754, 27.02177, 1);

我得到输出:

47.20754 27.02177

不确定原作者是否找到了答案,但由于我遇到了类似的问题,并开发了有效的解决方案,我认为将其发布在这里会很好。

问题

有两个地理点,A和B,找到中间点C,该点正好位于从A到B的直接道路上,距离A N公里(其中N小于A和B之间的距离,否则C=B)。

我的上下文

我正在开发基于微服务架构的小型pet项目。这个想法是从给定的部署平台(A点)向选定的目标位置(B点)发射导弹。我必须创建某种模拟器,在导弹发射后发送一些关于当前导弹地理位置的信息,所以我必须以某种方式找到A和B之间的中间点。

解决方案上下文

最终,我基于这个伟大的网页开发了基于C#的解决方案https://www.movable-type.co.uk/scripts/latlong.html.

该网页底部有所有的解释、公式和JavaScript代码。如果您不熟悉C#,可以使用它们的JavaScript实现。

我的C#实现

您的输入是位置A、位置B和距离。

  1. 你需要找到从A到B的方位(请参阅该网站的"方位"部分)
  2. 您需要从具有方位的A中找到位置C(请参阅该站点上的"给定距离的终点和起点方位")

代码

我有一个工作解决方案,作为我宠物项目的一部分,它可以在这里找到-https://github.com/kakarotto67/mlmc/blob/master/src/Services/MGCC.Api/ChipSimulation/CoordinatesHelper.cs.(由于原来的类别将来可能会发生变化,您可能需要参考以下要点-https://gist.github.com/kakarotto67/ef682bb5b3c8bd822c7f3cbce86ff372)

用法

// 1. Find bearing between A and B    
var bearing = CoordinatesHelper.FindInitialBearing(pointA, pointB);
// 2. Find intermediate point C having bearing (above) and any distance in km
var pointC = CoordinatesHelper.GetIntermediateLocation(pointA, bearing, distance);

我希望有人会觉得这很有帮助。

def get_intermediate_point(lat1 , lon1 , lat2 , lon2 , d):
    constant = np.pi / 180
    R = 6371
    φ1 = lat1 * constant
    λ1 = lon1 * constant
    φ2 = lat2 * constant
    λ2 = lon2 * constant
    y = np.sin(λ2-λ1) * np.cos(φ2);
    x = np.cos(φ1)*np.sin(φ2) -  np.sin(φ1)*np.cos(φ2)*np.cos(λ2-λ1)
    θ = np.arctan2(y, x)
    brng = (θ*180/np.pi + 360) % 360;  #in degrees
    brng = brng * constant
    φ3 = np.arcsin( np.sin(φ1)*np.cos(d/R ) + np.cos(φ1)*np.sin(d/R )*np.cos(brng) )
    λ3 = λ1 + np.arctan2(np.sin(brng)*np.sin(d/R )*np.cos(φ1),  np.cos(d/R )-np.sin(φ1)*np.sin(φ2));
    return φ3/constant , λ3/constant