如何计算几个纬度和经度点之间的平均值?
我应该只计算lat和lng的算术平均值吗?
如何计算几个纬度和经度点之间的平均值?
我应该只计算lat和lng的算术平均值吗?
Answers:
简单来说,您不希望平均经度和纬度坐标。这在较低的纬度下可能效果很好,但是在较高的纬度下,它将开始产生较差的结果,并在两极附近完全崩溃。
我用于此类事物的方法是将经度/纬度坐标转换为3d笛卡尔坐标(x,y,z)。平均这些(以给出笛卡尔向量),然后再次转换回去。请注意,您可能不需要对向量进行归一化,因此实际平均过程可能只是一个简单的总和。
编辑,这是我的C#代码:
以下将笛卡尔坐标转换为纬度/经度(以度RAD2DEG
为单位):删除弧度的常数。
Latitude = MPUtility.RAD2DEG * Math.Atan2(z, Math.Sqrt(x * x + y * y));
Longitude = MPUtility.RAD2DEG * Math.Atan2(-y, x);
在这里,我们根据纬度/经度(以弧度为单位)计算笛卡尔坐标:
private void CalcCartesianCoord()
{
_x = Math.Sin(LatitudeRadians) * Math.Cos(LongitudeRadians);
_y = Math.Sin(LatitudeRadians) * Math.Sin(LongitudeRadians);
_z = Math.Cos(LatitudeRadians);
}
两者都是从真实代码中剪切和粘贴的,因此是度数和弧度的混合。这里有一些执行某些转换LatitudeRadians
的属性(例如,是一个返回弧度值的属性)。
请注意,可以进行优化:例如,重复正弦计算。如果您经常调用它们,trig计算也可能是可缓存的。
集群选项:我认为涵盖此类操作的概念性时髦词是“集群”。到目前为止,平均是最简单的实施方法,并且可以很好地用于大多数目的。我唯一会使用其他方法的情况是,如果您担心异常值[Edit]->或极点或国际日期变更线。[编辑]->也可以取平均值,尽管它会给您看起来接近群集中心的位置,但由于度数并不总是相同而导致投影不准确,因此会有些偏离相隔公里/英里。您平均的面积越大,失真越大。
这是一些群集选项的比较
平均值(简单,快速,不准确): 只需将纬度值相加并除以计数,然后对lng值进行相同的处理。如果您使用的是Int32,请务必注意是否有溢出,某些系统(特别是c#)将悄无声息地回到低位。您可以通过对总和累加器使用浮点精度来避免这些错误。这种方法的一个问题是离群值可能会使您的位置偏斜。[编辑]->另一个问题是,极点和国际日期界线附近的数学平均值不佳,并且会严重歪斜位置。
最近的邻居(更难,更慢,没有异常的偏向) 与其求平均,不如使用实际的纬度位置,到所有邻居的平均距离最小。这有点像采用“中位数”。不利的一面是,这在计算上是昂贵的,因为您将每个点与每个其他点进行比较并计算它们之间的距离。例如,对10,000个点进行聚类将需要进行1亿个距离计算..并不是那么慢,但是它肯定不能很好地扩展。
网格单元(需要一些额外的设置,速度更快,没有异常偏斜)这类似于最近的邻居,但是速度更快。您可以选择任意精度,例如0.01纬度(在人口纬度大约为1公里),然后将各个点归为0.01 x .01度的水桶。然后,您可以选择其中包含最多点的存储桶,然后取这些点的平均值,或者仅对那些点进行最近的邻居分析。我在大型数据集(数千亿条记录)中经常使用此方法,并发现它在精度和速度之间达到了很好的平衡。
凸壳质心(硬,慢,整洁的结果): 您还可以在点周围画一条带以定义一个覆盖所有点的形状(请参阅Wikipedia),然后计算该形状的中心点。典型的质心函数不是中心加权的,因此您需要使用形状内的采样点进行某种逆最近邻分析,直到找到距离边缘最远的一个。由于凸包本身而不是既不快速也不精确的实际中心查找算法,因此该方法确实更有趣。
不确定要达到的目标,但是纬度为原始点集的平均纬度和经度为原始点集的平均经度的点将是原始点集的平均点。[更新]:在上面,avg是算术平均值。