地理网格搜索算法
Posted
技术标签:
【中文标题】地理网格搜索算法【英文标题】:Geographic grid search algorithm 【发布时间】:2010-07-01 06:36:51 【问题描述】:许多基于位置的服务都提供了用于查找给定纬度经度对周围的地点/地点/地点的 API。我正在研究如何在整个城市中搜索这些地点。
我可以通过从 Google 地图地理编码器获取城市的边界,然后增加纬度/经度以放置点以形成网格来为城市构建网格。我已经prototyped this grid (单击“填充网格”按钮查看所有点)来形象化这个想法。
// gather a collection of lat/long pairs that represents a grid of the city
var latIncrement = .04;
var lngIncrement = .04;
var newLat = nw.lat();
while(newLat >= sw.lat())
var newLng = nw.lng();
while(newLng <= ne.lng())
// western and northern border as well as grid infill
addMarker(new google.maps.LatLng(newLat, newLng));
newLng += lngIncrement;
// eastern border
addMarker(new google.maps.LatLng(newLat, ne.lng()));
newLat -= latIncrement;
// southern border
var newLng = sw.lng();
while(newLng <= se.lng())
addMarker(new google.maps.LatLng(sw.lat(), newLng));
newLng += lngIncrement;
addMarker(se);
然后我可以获取所有这些点并针对 LBS API 运行搜索。
我的问题是,有没有更科学的方法/算法来建立这个网格?我想了解更多关于他们的信息。我只是任意增加纬度/经度,直到到达网格的边界。地方的密度会因城市和城市面积而有很大差异,因此有时增量会太小,有时会太大。我正在寻找有关如何更好地调整它的想法?
【问题讨论】:
【参考方案1】:也许更有效/更干净的方法是找到城市的bounding rectangle,这是一个矩形,每条边都是城市边界点之间的极端基点,如果你能找到它们,然后填充它们在迭代中。但这基本上就是你已经在做的事情了。
至于位置密度,您是否有特定的 API 可以使用它?如果您在检测地点时知道 API 点的“范围”,那么您只需将网格点设置为与其半径一样近。
话虽如此,您是否考虑过 API 是否直接支持搜索边界内的地点?这可能是您最好和最干净的选择。
阅读您的评论后,这是一种可能效率低下的方法,我将在未来思考和完善,但它可能会帮助您入门。
在您的城市中心放置一个点,并观察检测到的所有位置。找到您的位置的convex hull,并在凸包上的每个位置上放置一个新点。然后,将这些新添加点范围内的所有位置添加到您的位置列表中。
然后,找到它们的凸包,并重复相同的过程。
这实际上可能会减少人口稀少城市的积分数量。对于密集的,它可能不是最佳的,但它可能会让你开始工作。
【讨论】:
我一直在研究foursquare、twitter、gowalla 和yelp API。半径(范围)是一个常见参数,但问题在于返回的结果数量(他们将每次搜索限制为少数几个),所以我无法通过一次搜索获得城市中的所有地方。好主意,感谢您的回答! 太好了,这给了我另一种解决方法。我喜欢它是如何从中心向外扩散的,所以它不那么浪费。使用网格搜索,许多搜索将在城市范围之外。感谢您对此进行讨论。【参考方案2】:当我面临同样的问题时。我想出了一个解决方案,您将以自上而下的递归方式进行网格搜索。如果该 API 支持边界框搜索,这将起作用。最初假设你的城市是一个正方形。现在在该正方形中使用 API 获取数据/位置(边界框查询)。现在,如果返回的地方的数量超过某个阈值,则将城市广场分成 4 个相等的方格,并对每个方格重复该过程。如果返回的位置数量较少,请不要拆分。这将防止网格搜索到非商业区域(广场),如森林、河流等。这是 Python 原型代码:
这里的fetch是基于边界框从API中获取结果的函数,sw为西南纬,logitude元组,ne为东北纬,logitude元组
allresults = []
def grid_search(sw,ne):
global results
results = fetch(sw,ne)
if len(results) <= 10:
return
allresults.append(results)
swlat,swlon = sw
nelat,nelon = ne
grid_search( (swlat + delta, swlon), (nelat, sw + delta) )
grid_search( (swlat + delta, swlon + delta), ne )
grid_search( sw, (swlat + delta, swlon + delta) )
grid_search( (swlat,swlon + delta), (swlat + delta, nelon) )
【讨论】:
以上是关于地理网格搜索算法的主要内容,如果未能解决你的问题,请参考以下文章