我列出了几百个城市的纬度/经度。给定另一个位置(也是经度/纬度),我需要找到最近的城市。
由于我不使用任何GIS,因此到目前为止,显而易见的算法是对所有城市进行循环,以计算点之间的距离。
建立循环对我来说是切实可行的,但是有一些易于实现的算法可以更有效地完成该任务吗?还是一些可以帮助解决该问题的轻量级Java库?
注意:我不需要/不需要完整的GIS解决方案或繁杂的库。我更喜欢一个不太好但最简单,更轻松的解决方案,因为这是我唯一需要解决的问题。
我列出了几百个城市的纬度/经度。给定另一个位置(也是经度/纬度),我需要找到最近的城市。
由于我不使用任何GIS,因此到目前为止,显而易见的算法是对所有城市进行循环,以计算点之间的距离。
建立循环对我来说是切实可行的,但是有一些易于实现的算法可以更有效地完成该任务吗?还是一些可以帮助解决该问题的轻量级Java库?
注意:我不需要/不需要完整的GIS解决方案或繁杂的库。我更喜欢一个不太好但最简单,更轻松的解决方案,因为这是我唯一需要解决的问题。
Answers:
我在20年前设计桌面GIS时就对这个问题进行了精确调查。我们需要交互地找到点到点的距离;我们的目标是在不到1/2秒的时间内完成数千个点的计算。测试(在25 MHz 486 PC上!)显示,我们可以完全按照您的描述(使用简单的简单算法)计算所有距离,以至于无法创建更复杂的解决方案(例如四叉树结构) 。
为了计算到单个“探针”点的距离,您可以选择(a)使用以探针点为中心的等距投影来投影所有点,或者(b)采用球形地球模型并使用Haversine公式。如果您需要椭圆模型的精度,则第一个方法是合适的。在这两种情况下,计算都相当快,大概只需不到1000个滴答声:您可以使用一个处理器每秒查询大约一百万点。
够快吗?如果不是这样,则蛮力方法可以很容易地进行并行化,并直接根据处理器的数量进行缩放:只需在处理器之间划分点,然后对每个处理器找到的最接近的像素进行最终比较。
如果需要走得更快,可以使用各种近似值来筛选点。例如,如果您的纬度在-88到+88之间,并且到目前为止找到的最近点是200公里,则任何纬度与探测点的纬度相差2度以上的点都不可能更近(因为在地球,一度的纬度超过约110公里)。在许多情况下,这种预筛选可以使您每秒处理数亿个点。
我同意其他人的看法,即简单的循环对于“几百个城市”应该有效。
在您的应用程序中,处理椭球距离可能是主要的矫kill过正-您可能正在处理位置几乎不超过几米的天气预报。球面几何非常简单,您可以轻松地在循环中完成。
它甚至可能更简单(例如,将delta lat用作y并将delta lon * cos(lat)用作x并找到最小值x ^ 2 + y ^ 2)。您正在使用目标纬度的余弦,而该余弦仅计算一次。对于遥远的城市,这将越来越不准确,但是无论如何它们都会被拒绝,所以不要紧。假设您最近的城市通常在几百公里之内,则使用此方法与使用更精确的公式得出不同结果(最近的城市)的可能性很小,并且只有当差异足够小而“哪个预测更大时”才会发生准确”可能仍然取决于其他因素(例如:在噪声中损失)。
除非您使用嵌入式系统或慢速解释器,否则您可能可以负担得起仅使用其他人建议的球形形式。