【问题标题】:How to calculate coordinate X meters away from a point but towards another in C#如何在C#中计算远离一个点但朝向另一个点的坐标X米
【发布时间】:2019-08-10 04:26:23
【问题描述】:

假设我有两个相距约 222.33 米的坐标:

A: 49.25818, -123.20626
B: 49.25813, -123.2032

这两点构成一个片段。

我如何计算距离 A 或 B 距离 X 米但朝向另一点的 Z 点的坐标?

我已经使用System.Device.Location 库知道我的两点之间的距离。

GeoCoordinate A = new GeoCoordinate(49.25818, -123.20626);
GeoCoordinate B = new GeoCoordinate(49.25813, -123.2032);
var distanceInMeters = A.GetDistanceTo(B);
// distanceInMeters = 222.33039783713738

我正在寻找这样的东西:

GeoCoordinate GetPointTowards(GeoCoordinate fromPoint, GeoCoordinate towardPoint, double distanceInMeter) {
    [???]
}

我想我可能需要方位或其他东西才能获得新的点位置。

我发现的大多数示例都是针对具有特定库的 iOS、Android 或 GMaps..

【问题讨论】:

  • 也许这个 nuget 库可以提供帮助? numerics.mathdotnet.com
  • 能否请您提供另外两个带有正确仪表的坐标。在发布您可以传递的方法之前,需要测试我的逻辑。
  • @LevonRavel:{49.25835,-123.21894},{49.25837,-123.21989}。他们在 69.038124262531255 米之外。
  • 好的,我可以发布方程式
  • stackoverflow.com/questions/3225803/… 找到了这个答案,希望对您有所帮助。它以公里为单位,但我认为转换为米应该很容易。

标签: c# geospatial distance


【解决方案1】:

这是我将如何做的大纲。使用这种方法,不需要显式处理坐标和距离之间的单位差异,因为取目标与总距离的比率会消除单位。

totalDistance = distance in meters between point A and point B.
targetDistance = distance in meters to travel from point A to point B

ratio = targetDistance / totalDistance

diffX = B.X - A.X
diffY = B.Y - A.Y

targetX = A.X + (ratio * diffX)
targetY = A.Y + (ratio * diffY)

但这不能处理边缘情况,例如经度为 179 度并增加 3 度,这将使您处于 -178 经度。

【讨论】:

    【解决方案2】:

    这是我从http://www.movable-type.co.uk/scripts/latlong.html 转换为 C# 的代码。分数是从 0 到 1,是从第一个点到第二个点的距离输出位置的分数。您可以随时修改它以采用直线距离值。

    public static (double Lat, double Lon) IntermediatePoint((double Lat, double Lon) StartPoint, (double Lat, double Lon) EndPoint, double fraction)
        {
            if (fraction < 0 || fraction > 1)
                throw new ArgumentOutOfRangeException();
            double angDist = Distance(StartPoint, EndPoint) / radius;
            double lat1 = StartPoint.Lat * (Math.PI / 180);
            double lon1 = StartPoint.Lon * (Math.PI / 180);
            double lat2 = EndPoint.Lat * (Math.PI / 180);
            double lon2 = EndPoint.Lon * (Math.PI / 180);
            double a = Math.Sin((1 - fraction) * angDist) / Math.Sin(angDist);
            double b = Math.Sin(fraction * angDist) / Math.Sin(angDist);
            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(lat2);
            double lat3 = Math.Atan2(z, Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2)));
            double lon3 = Math.Atan2(y, x);
            return (lat3 * (180 / Math.PI), lon3 * (180 / Math.PI));
        }
    public static double Distance((double Lat, double Lon) point1, (double Lat, double Lon) point2)
        {
            double φ1 = point1.Lat * (Math.PI / 180.0);
            double φ2 = point2.Lat * (Math.PI / 180.0);
            double Δφ = (point2.Lat - point1.Lat) * (Math.PI / 180.0);
            double Δλ = (point2.Lon - point1.Lon) * (Math.PI / 180.0);
            double a = Math.Sin(Δφ / 2) * Math.Sin(Δφ / 2) + Math.Cos(φ1) * Math.Cos(φ2) * Math.Sin(Δλ / 2) * Math.Sin(Δλ / 2);
            double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
    
            return radius * c;
        }
    

    radius 是一个常数,以米为单位表示地球的半径。

    【讨论】:

      猜你喜欢
      • 2011-10-01
      • 2012-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-06
      • 1970-01-01
      相关资源
      最近更新 更多