我在sqlite中有这个表
Locations
ID
Lat ( latitude)
Lon ( longitude)
Type
Name
City
我有100条记录 我需要的是(使用我自己的坐标)得到表格中最近的点。
我所做的是获得当前点与表中每个点之间的最短距离,并返回最短点,但我正在寻找更好的解决方案
由于
答案 0 :(得分:6)
一种可能的解决方案是为您感兴趣的整个地图使用网格,并将点预分配给特定的行/列。然后:
应该减少你需要做的计算次数。
如果您希望始终在X距离内找到位置,您可以查询x / y坐标,这些坐标将在您的坐标范围内+/- x KM(正方形),计算它们是否属于xKM圈内你的观点,然后选择最短的。
更新 - 网格选项
我假设你已经在两点计算之间做距离,并且不会描述它。
如果您有方便的地图集,您可以通过查看索引中的位置来查看示例。它将为您提供一个页面和网格位置,如M5。如果你去那个页面,它会有用数字和字母标记的行和列,如果你看到第M行和第5列相交的方块,你会在那里找到那个城市。要为您的系统执行此操作,您需要:
因此,如果用户是绿色标记,他将在C4中。您将搜索C4中的所有其他点并确定最接近的是#2。然后你还必须检查一个网格,以确保没有比你找到的更近的项目,所以这包括正方形:B3,B4,B5,C3,C5,D3,D4,D5 。当你这样做时,你将从C3中选择#3并完成。
如果用户在方形D2中没有其他分数,那么你会在C2中找到你的第一场比赛。检查C1,C2,C3,D1,D3,E1,E2,E3时。一旦找到,你将再次需要检查另一个半径,这将是:B0-4,C0,C4,D0,D4,E0,E4,F0-4。您可以看到网格选择对于尽可能提高效率非常重要。
另请注意,假设您的网格与我的手绘示例不同。
选项2:
如果您希望X km内的结果,并且您希望数据库能够快速计算出来,那么您可以这样做:
LatMin = currentLatCoord-radiusValInDegrees
LatMax = currentLatCoord+radiusValInDegrees
LonMin = currentLonCoord-radiusValInDegrees
LonMax = currentLonCoord+radiusValInDegrees
SELECT *
From Locations
WHERE Lat BETWEEN LatMin AND LatMax
AND Lon BETWEEN LonMin AND LonMax
现在,这将为您提供正方形的所有结果。重要的是,然后检查它们实际上是在圆圈中 - 您需要在角落中放下任何角落,因为实际上可能存在比圆圈边缘更近的坐标。因此,对于每个点,检查它是否首先在圆圈内(Equation for testing if a point is inside a circle),然后计算距离并保持最近的距离。如果没有得到结果,请加宽圆圈。
同样,选择良好的半径取决于您的数据。
答案 1 :(得分:4)
您是否在本网站上查看了如何计算distance between two points on Earth?
但请记住,它根据地球表面给出的距离不是基于到达该位置的实际路径。因此,如果您想根据实际路径计算距离以达到该位置,那么您可以使用Google MAP API获取该距离。
Google Maps API根据实际路径给出两点之间的距离。
希望这些信息对您有所帮助。
享受编码......:)
答案 2 :(得分:2)
两点之间的距离:((x1 - x2) ^ 2 + (y1 - y2) ^ 2) ^ 0.5
。但是,这些点之间的距离是直线。最有可能的是,有一些变量,如本地和高速公路,更不用说单行道和水道,你需要找到最近的桥梁。因此,我建议使用谷歌和Bing地图api。对于有限数量的搜索是免费的。
答案 3 :(得分:2)
在Query to get records based on Radius in SQLite?处有一个相当聪明的解决方案 基于在插入行时预先计算每个位置的一些三角函数值,然后只允许使用算术函数计算查询中的距离。
我在自己的代码中非常成功地使用了它
答案 4 :(得分:1)
让我确保这是正确的:您有点a
和点a[]
表。目前,您执行以下操作:
- 循环
b[]
- 从
distance
获取b[i]
到a
- 如果
distance
小于minimumDistance
- 设置
minimumDistance = distance
- 设置
closestPoint = i
- return
closestPoint
如果是这样,你会在O(n)
时间内找到它,但实际上并没有真正得到改善。您必须检查所有点以查看哪个点最近。
然而,正如Matthew所指出的那样,你可以通过为网格分配点来修剪n
。这可以大大减少比较所需的点数。费用是预处理的一点时间,逻辑稍微复杂一些。如果你有一长串的积分(或distance()
函数需要很长时间),你肯定会想做这样的事情。
答案 5 :(得分:1)
取决于你在靠近两极时对你的正确程度的关注
如果最近的毕达哥拉斯距离足够好你可以按照sql的顺序使用它
例如。 SELECT * FROM locations ORDERBY (Lat-myLat)*(Lat-myLat) + (Lon-myLon)*(Lon-myLon) LIMIT 1
从技术上讲,它不是最正确的,但保存从数据库中获取所有位置并循环遍历它们,让sqlite为您执行此操作
答案 6 :(得分:1)
你可以使用我的php类hilbert curve @ phpclasses.org。它使用怪物曲线和四核来找到最短距离。要搜索四核,您可以使用任何深度。
答案 7 :(得分:1)
虽然这不是最佳选择
让你试图找出 N 英里/公里的最短距离,对于固定的位置/您的位置表数据没有定期更改。
添加另一列 Distance_Index(DI)自我多引用键ArrayType。一旦运行程序并根据与DI的距离按升序更新DI。
现在从下一次开始,你就可以了。只需查询数据库并使用它
现在,在你的问题中,没有位置在N之内,DI不会太长。只是一个意见。