【发布时间】:2021-08-20 15:47:59
【问题描述】:
我有一系列纬度和经度构成从起点到目的地的整条路线,但我真的很难计算整条铁路路线的所有曲率,包括将左转作为负值,将右转作为正值(或反之亦然,以较容易者为准)。
我也有代码可以给我一个轴承以及两个轴承之间的差异,但这是我所掌握的(代码如下)。
从下图中的绿色标记出发,向西(左)行进,有:
- 向右轻微弯曲
- 向右急转
- 向左转
- 向左小转
- 大部分是直的
- 急左
- 有点直
- 紧随其后的是一个急右
本质上,它正在计算上述列表/图片中每个转弯的转弯半径。
所需的输出对象
public EdgeCurve[] Curves {get; set;}
public class EdgeCurve
{
public double StartLatitude {get;s et;}
public double StartLongitude {get; set;}
public double EndLatitude {get; set;}
public double EndLongitude {get; set;}
public double Curve {get; set;}
//Optional
public double Distance {get;set;}
}
轴承代号
public static class BearingHelper
{
/// <summary>
/// Angle between two points, where North is 0 and South is 180.
/// </summary>
/// <param name="lat0">Latitude for point A.</param>
/// <param name="lon0">Longitude for point A.</param>
/// <param name="lat1">Latitude for point B.</param>
/// <param name="lon1">Longitude for point B.</param>
/// <returns>Angle between points A and B, in degrees.</returns>
public static double Degrees(double lat0, double lon0, double lat1, double lon1)
{
var dlon = (lon1 - lon0).ToRadians();
var dphi = Math.Log(Math.Tan(lat1.ToRadians() / 2 + PI_d4) / Math.Tan(lat0.ToRadians() / 2 + PI_d4));
if (Math.Abs(dlon) > Math.PI)
{
dlon = dlon > 0 ? -(PI_m2 - dlon) : (PI_m2 + dlon);
}
return (Math.Atan2(dlon, dphi).ToDegrees() + 360) % 360;
}
public static double AbsDifference(double bearing0, double bearing1)
{
double diff = Math.Abs(bearing0 - bearing1);
if (diff > 180)
diff -= 360;
return Math.Abs(diff);
}
}
public static class CoordinateMath
{
/// <summary>
/// PI multiplied by 2.
/// </summary>
public const double PI_m2 = 6.28318530718;
/// <summary>
/// PI divided by 4.
/// </summary>
public const double PI_d4 = 0.78539816339;
/// <summary>
/// Convert degrees to radians.
/// </summary>
public static double ToRadians(this double deg) => deg * 0.01745329252;
/// <summary>
/// Convert radians to degrees.
/// </summary>
public static double ToDegrees(this double rad) => rad * 57.295779513;
}
纬度/经度数组
[
{
"Latitude": 53.743647,
"Longitude": -0.347531
},
{
"Latitude": 53.743635,
"Longitude": -0.348089
},
{
"Latitude": 53.74365,
"Longitude": -0.348648
},
{
"Latitude": 53.74369,
"Longitude": -0.349114
},
{
"Latitude": 53.743754,
"Longitude": -0.3496
},
{
"Latitude": 53.743867,
"Longitude": -0.35029
},
{
"Latitude": 53.743941,
"Longitude": -0.350679
},
{
"Latitude": 53.744063,
"Longitude": -0.351096
},
{
"Latitude": 53.744518,
"Longitude": -0.352272
},
{
"Latitude": 53.744557,
"Longitude": -0.352369
},
{
"Latitude": 53.744888,
"Longitude": -0.353199
},
{
"Latitude": 53.744925,
"Longitude": -0.353296
},
{
"Latitude": 53.745078,
"Longitude": -0.353724
},
{
"Latitude": 53.745176,
"Longitude": -0.354035
},
{
"Latitude": 53.745339,
"Longitude": -0.354672
},
{
"Latitude": 53.745494,
"Longitude": -0.355461
},
{
"Latitude": 53.745591,
"Longitude": -0.356196
},
{
"Latitude": 53.745644,
"Longitude": -0.356898
},
{
"Latitude": 53.74566,
"Longitude": -0.357678
},
{
"Latitude": 53.745633,
"Longitude": -0.358616
},
{
"Latitude": 53.745577,
"Longitude": -0.359361
},
{
"Latitude": 53.745521,
"Longitude": -0.359924
},
{
"Latitude": 53.745439,
"Longitude": -0.360563
},
{
"Latitude": 53.745344,
"Longitude": -0.361198
},
{
"Latitude": 53.745192,
"Longitude": -0.362056
},
{
"Latitude": 53.745051,
"Longitude": -0.362748
},
{
"Latitude": 53.744811,
"Longitude": -0.363821
},
{
"Latitude": 53.744539,
"Longitude": -0.364885
},
{
"Latitude": 53.74428,
"Longitude": -0.365809
},
{
"Latitude": 53.744023,
"Longitude": -0.366656
},
{
"Latitude": 53.743862,
"Longitude": -0.367141
},
{
"Latitude": 53.743723,
"Longitude": -0.367545
},
{
"Latitude": 53.7434,
"Longitude": -0.368412
},
{
"Latitude": 53.743096,
"Longitude": -0.369159
},
{
"Latitude": 53.742528,
"Longitude": -0.370427
},
{
"Latitude": 53.742197,
"Longitude": -0.371099
},
{
"Latitude": 53.741909,
"Longitude": -0.371663
},
{
"Latitude": 53.741679,
"Longitude": -0.372077
},
{
"Latitude": 53.741462,
"Longitude": -0.372498
},
{
"Latitude": 53.74131,
"Longitude": -0.372765
},
{
"Latitude": 53.737842,
"Longitude": -0.379223
},
{
"Latitude": 53.737396,
"Longitude": -0.380011
},
{
"Latitude": 53.737152,
"Longitude": -0.380388
},
{
"Latitude": 53.737006,
"Longitude": -0.380587
},
{
"Latitude": 53.736736,
"Longitude": -0.380912
},
{
"Latitude": 53.736466,
"Longitude": -0.381183
},
{
"Latitude": 53.736294,
"Longitude": -0.381331
},
{
"Latitude": 53.736187,
"Longitude": -0.381417
},
{
"Latitude": 53.735827,
"Longitude": -0.381659
},
{
"Latitude": 53.735664,
"Longitude": -0.381751
},
{
"Latitude": 53.735378,
"Longitude": -0.381882
},
{
"Latitude": 53.735185,
"Longitude": -0.381952
},
{
"Latitude": 53.734976,
"Longitude": -0.382014
},
{
"Latitude": 53.734575,
"Longitude": -0.382077
},
{
"Latitude": 53.734372,
"Longitude": -0.382083
},
{
"Latitude": 53.734044,
"Longitude": -0.382055
},
{
"Latitude": 53.733148,
"Longitude": -0.381884
},
{
"Latitude": 53.732913,
"Longitude": -0.381838
},
{
"Latitude": 53.732526,
"Longitude": -0.381762
},
{
"Latitude": 53.732156,
"Longitude": -0.381722
},
{
"Latitude": 53.731976,
"Longitude": -0.381718
},
{
"Latitude": 53.731854,
"Longitude": -0.381728
}
]
【问题讨论】:
-
例如曲线的作用是什么? 2.0 或 -5.7 是什么意思?你本质上是吗?你要求类似stackoverflow.com/questions/7811761/…
-
嗨,如果节点太靠近,该链接是关于平滑线的,这是完全不同的。 2.0 表示它朝一个方向转动,-5.7 表示它朝另一个方向转动。我上传了一张更好的照片。
-
但是量级有什么意义呢?如果我编写了一个代码,将您的曲线声明为 -2312375.234234,这是什么意思?照原样,我认为您的问题不能(或不应该)得到回答,因为它基本上是“这是一个不完整的规范,请为我做我的工作”。将一组线段平滑成一组曲线并不是“完全不同”,这实际上是您显然要求的
-
当你说线条的平滑时,我会想到 Douglas-Peucker 算法,在该算法中删除数组中的冗余节点。我要问的是..如果火车沿着轨道行驶并开始右转,它开始右转与再次直行或左转之间的角度是多少。我只是不知道所需的数学或伪代码,没有这些,有人怎么知道在哪里看。我是软件开发人员而不是数学家,因此编写需求更加困难。
-
我想,从算法上讲,如果你站在任何给定的 N 点,那么你应该参考从前一个点 N-1 到当前的。然后,您将知道几件事:下一点是否是航向变化 - 如果不是,那么您处于恒定曲线上,如果是,那么 b) 变化是更靠右还是更靠左,因此(基于无论您已经向右还是向左)它是否更陡或更小,以及它是否代表从右向左的翻转。然后也许只是折叠你的序列
标签: c# geolocation geometry geospatial curve