C# 获取地理位置上放置的对象之间的距离

C# 获取地理位置上放置的对象之间的距离,c#,C#,我有一个应用程序(类似cad的编辑器),用户可以在其中放置许多位置节点(由它们的纬度和经度定义)。应用程序需要告诉用户这些节点是否非常靠近—一个常见的设计错误是它们重叠。该应用程序所做的事情与ReSharper或CodeRush在IDE中所做的非常类似——解析项目并报告问题。一个项目可能有几千个这样的节点,因此随着数量的增加,测试重叠从理论上讲变得更加耗时。目前,我正在使用两个for循环来遍历列表 for (int i = 0; i < count - 1; i++) { for

我有一个应用程序(类似cad的编辑器),用户可以在其中放置许多位置节点(由它们的纬度和经度定义)。应用程序需要告诉用户这些节点是否非常靠近—一个常见的设计错误是它们重叠。该应用程序所做的事情与ReSharper或CodeRush在IDE中所做的非常类似——解析项目并报告问题。一个项目可能有几千个这样的节点,因此随着数量的增加,测试重叠从理论上讲变得更加耗时。目前,我正在使用两个for循环来遍历列表

for (int i = 0; i < count - 1; i++) {
     for (int j = i + 1; j < count; j++) {
         // check the distance between the i and j elements and if less than
         // a predetermined value report it
    }
}
for(int i=0;i
我想让识别过程进入“实时”状态,以便在发生重叠时立即告知用户。循环和测试节点之间的距离一样昂贵。当然,大多数比较都是白费力气

我只是想知道还有没有别的办法。我曾考虑过按lat和lon对列表进行排序,并比较相邻元素,但我怀疑这样做行不通,也不一定会更快

我的另一个想法是将活动移动到另一个线程(我确实没有使用多个线程的经验),以便更新值—例如,存储对每个对象中附近节点的引用。但是,我可以想象需要为后台线程克隆对象树,这样就不会与前台冲突。

您可以查看

在另一个线程上执行此操作是一个完全独立的问题,您可以使用嵌套循环以及更高效的算法来执行此操作。

您可以深入研究


在另一个线程上执行此操作是一个完全独立的问题,您可以使用嵌套循环以及更高效的算法来执行此操作。

由于用户正在放置这些位置,理想的解决方案是假设以前放置的所有点都不在附近,并且每个新点或移动的点,对照其余部分进行检查——这将成为一个单for循环,这应该是合理的

然而,另一个更理想的解决方案是:

Let position of A be lat, lng.
Convert both lat and lng to a fixed-length representation
    (truncating the degree of precision to a value below which 
    you are sure they will overlap)
Let xa = lat . lng (concatenate both)
Let ya = lng . lat

Given some position B, find xb, yb.

B is 'close' to A iff | xa - xb | < delta, | ya - yb | < delta.
让A的位置为lat,lng。
将lat和lng转换为固定长度表示形式
(将精度截断为低于
您确信它们会重叠)
设xa=lat。液化天然气(连接两者)
让ya=液化天然气。拉特
给定某个位置B,找到xb,yb。
B接近于iff | xa-xb |

你可以做的是把所有的输入点的席、夷的值分类。当您想检查是否有太近的点时,您需要遍历xi的列表以找到太近的点(线性时间,因为它们是相邻的),然后检查yi列表中的相同点是否太近。

因为用户正在放置这些位置,理想的解决方案是假设所有先前放置的点都不在附近,对于每个新点或移动的点,对照其他点进行检查——这将成为一个单独的for循环,这应该是合理的

然而,另一个更理想的解决方案是:

Let position of A be lat, lng.
Convert both lat and lng to a fixed-length representation
    (truncating the degree of precision to a value below which 
    you are sure they will overlap)
Let xa = lat . lng (concatenate both)
Let ya = lng . lat

Given some position B, find xb, yb.

B is 'close' to A iff | xa - xb | < delta, | ya - yb | < delta.
让A的位置为lat,lng。
将lat和lng转换为固定长度表示形式
(将精度截断为低于
您确信它们会重叠)
设xa=lat。液化天然气(连接两者)
让ya=液化天然气。拉特
给定某个位置B,找到xb,yb。
B接近于iff | xa-xb |

你可以做的是把所有的输入点的席、夷的值分类。如果要检查是否有太近的点,则需要遍历xi列表以查找太近的点(线性时间,因为它们将相邻)然后检查易建联列表中的相同点是否太接近。

多亏了这里给出的见解,我认为我找到了一个合理的方法来处理这个问题

*First to sort all the points in latitude order.
*Then loop through the sorted list. 
*For each entry in the list compare the latitude offset (distance in meters) to the entries below it.
*If the latitude offset is less than the test distance then check the actual distance from point to point and if it is inside the test radius report the issue.
*When the latitude offset exceeds the test distance move on to the next point in the list and repeat the tests.

我还没有写代码,但在我看来,如果没有重叠,那么我将只通过一次。由于重叠在实践中很少见,因此测试的总数可能很小。对于1000个点,当前方法进行500000次测试。新方法不太可能产生几千美元以上的收益。

多亏了这里给出的见解,我认为我找到了一个合理的方法来处理这个问题

*First to sort all the points in latitude order.
*Then loop through the sorted list. 
*For each entry in the list compare the latitude offset (distance in meters) to the entries below it.
*If the latitude offset is less than the test distance then check the actual distance from point to point and if it is inside the test radius report the issue.
*When the latitude offset exceeds the test distance move on to the next point in the list and repeat the tests.

我还没有写代码,但在我看来,如果没有重叠,那么我将只通过一次。由于重叠在实践中很少见,因此测试的总数可能很小。对于1000个点,当前方法进行500000次测试。新方法不太可能超过几千个。

我认为这是一个数学问题。试着问一下如何计算由经度和纬度标识的球体表面上两点之间的距离。两点之间的距离不是这里的问题,而是找到导致问题的所有对距离。没错。我的应用程序拥有计算距离、方位等所需的所有球形地理算法。我至少会使用某种空间索引来减少需要计算的距离数量。四索引网格应该不会太难实现,并且会减少所需的资源。我认为这是一个数学问题。试着问一下如何计算由经度和纬度标识的球体表面上两点之间的距离。两点之间的距离不是这里的问题,而是找到导致问题的所有对距离。没错。我的应用程序拥有计算距离、方位等所需的所有球形地理算法。我至少会使用某种空间索引来减少您需要的距离