“移动”从 LatLonA 到 LatLonB (WGS84) # 米(地面以上)

发布于 2024-12-10 15:24:54 字数 467 浏览 0 评论 0原文

我需要 C# 中的一个函数来执行以下操作:从 GPS 点 A 向 GPS 点 B 的方向移动 50 米,并计算该点的 GPS 坐标。

例如,我有两个坐标:

LatLon LatLonA = new LatLon(51.83966, 5.04631); // Latitude 51.83966, Longitude 5.04631
LatLon LatLonB = new LatLon(51.84172, 5.01961); // Latitude 51.84172, Longitude 5.01961

我想要的是这样的函数:

function LatLon MoveTowards(LatLon A, LatLon B, double MetersOverGround) 
{
    //code here
}

该函数将返回在 B 方向上距 A x 米的坐标。

I need a function in C# to do the following: move 50 meters from gps-point A in the direction of gps-point B and calculate the GPS-coordinates for that point.

For instance I've got two coordinates:

LatLon LatLonA = new LatLon(51.83966, 5.04631); // Latitude 51.83966, Longitude 5.04631
LatLon LatLonB = new LatLon(51.84172, 5.01961); // Latitude 51.84172, Longitude 5.01961

What I would like is a function like this:

function LatLon MoveTowards(LatLon A, LatLon B, double MetersOverGround) 
{
    //code here
}

That function would return the coordinate which is x meters away from A in the direction of B.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

半世蒼涼 2024-12-17 15:24:54

地球不是球体,甚至也不是椭圆形。在不购买商业图书馆的情况下,您所能期望的最好结果就是一个近似值(对于大多数人来说这已经足够好了)。

您可以首先研究Haversine 公式,以及此页面将会有很大帮助。

或者,如果您想要一个商业库,我已经使用 ProLat 取得了巨大成功

The Earth is not a sphere, nor even an ellipse. The best you can hope for without purchasing a commercial library would be an approximation (which for most people is good enough).

You could start by looking into the Haversine formula, and this page will be of great help.

Or if you want a commercial library, I have used ProLat with great success

红ご颜醉 2024-12-17 15:24:54

这就是你想要的。只需使用 Math.Atan2 即可获取 A 到 B 向量的方位角并获取 bearing 参数。

    /// <summary>
    /// Calculates the end-point from a given source at a given range (meters) and bearing (degrees).
    /// This methods uses simple geometry equations to calculate the end-point.
    /// </summary>
    /// <param name="source">Point of origin</param>
    /// <param name="range">Range in meters</param>
    /// <param name="bearing">Bearing in degrees</param>
    /// <returns>End-point from the source given the desired range and bearing.</returns>
    public static PointLatLng CalculateDerivedPosition(PointLatLng source, double range, double bearing)
    {
        const double DEGREES_TO_RADIANS = Math.PI/180;
        const double EARTH_RADIUS_M = 6371000;
        double latA = source.Lat * DEGREES_TO_RADIANS;
        double lonA = source.Lng * DEGREES_TO_RADIANS;
        double angularDistance = range / EARTH_RADIUS_M;
        double trueCourse = bearing * DEGREES_TO_RADIANS;

        double lat = Math.Asin(
            Math.Sin(latA) * Math.Cos(angularDistance) +
            Math.Cos(latA) * Math.Sin(angularDistance) * Math.Cos(trueCourse));

        double dlon = Math.Atan2(
            Math.Sin(trueCourse) * Math.Sin(angularDistance) * Math.Cos(latA),
            Math.Cos(angularDistance) - Math.Sin(latA) * Math.Sin(lat));

        double lon = ((lonA + dlon + Math.PI) % (Math.PI * 2)) - Math.PI;

        return new PointLatLng(
            lat / DEGREES_TO_RADIANS,
            lon / DEGREES_TO_RADIANS);
    }

Here is what you want. Just use Math.Atan2 to obtain the bearing of your A-to-B vector and obtain the bearing parameter.

    /// <summary>
    /// Calculates the end-point from a given source at a given range (meters) and bearing (degrees).
    /// This methods uses simple geometry equations to calculate the end-point.
    /// </summary>
    /// <param name="source">Point of origin</param>
    /// <param name="range">Range in meters</param>
    /// <param name="bearing">Bearing in degrees</param>
    /// <returns>End-point from the source given the desired range and bearing.</returns>
    public static PointLatLng CalculateDerivedPosition(PointLatLng source, double range, double bearing)
    {
        const double DEGREES_TO_RADIANS = Math.PI/180;
        const double EARTH_RADIUS_M = 6371000;
        double latA = source.Lat * DEGREES_TO_RADIANS;
        double lonA = source.Lng * DEGREES_TO_RADIANS;
        double angularDistance = range / EARTH_RADIUS_M;
        double trueCourse = bearing * DEGREES_TO_RADIANS;

        double lat = Math.Asin(
            Math.Sin(latA) * Math.Cos(angularDistance) +
            Math.Cos(latA) * Math.Sin(angularDistance) * Math.Cos(trueCourse));

        double dlon = Math.Atan2(
            Math.Sin(trueCourse) * Math.Sin(angularDistance) * Math.Cos(latA),
            Math.Cos(angularDistance) - Math.Sin(latA) * Math.Sin(lat));

        double lon = ((lonA + dlon + Math.PI) % (Math.PI * 2)) - Math.PI;

        return new PointLatLng(
            lat / DEGREES_TO_RADIANS,
            lon / DEGREES_TO_RADIANS);
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文