地理网格搜索算法

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) )

【讨论】:

以上是关于地理网格搜索算法的主要内容,如果未能解决你的问题,请参考以下文章

K-近邻算法交叉验证,网格搜索

Lesson 9.3 集成算法的参数空间与网格优化和使用网格搜索在随机森林上进行调参

KNN算法网格搜索最优参数

优化地理位置搜索

算法导论22.3深度优先搜索 练习总结 (转载)

79. 单词搜索-回溯算法(leetcode)