搜索NSDictionary获取具有一定距离的纬度经度

时间:2014-01-19 14:02:41

标签: mkmapview nsdictionary nspredicate

我有一个大约2000个位置的NSDictionary,有lat和long,我根据它们是否在可见的地图区域中丢弃地图上的引脚。

目前,每次平移地图时,我只需循环浏览字典并计算距离,看看该位置是否可见,如果是这样的话,请放下一个图钉。

CLLocationCoordinate2D centre = [self.map centerCoordinate];
CLLocation *mapCenter =[[CLLocation alloc] initWithLatitude: centre.latitude  longitude: centre.longitude];

        for (int i=0; i < [self.dealersSource count]; i++) {

            CLLocation *d = [[CLLocation alloc] initWithLatitude: [[[self.dealersSource objectAtIndex:i] valueForKey:@"lat"] floatValue]
                                                           longitude: [[[self.dealersSource objectAtIndex:i] valueForKey:@"long"] floatValue]];

                CLLocationDistance distance = [d distanceFromLocation:mapCenter];
                float dist =(distance/1609.344);

            if (dist <= radius && dist !=0) {
               // this will be visible on the map, add to list of annotations
            }
}

这可行,但看起来非常低效,并且在较旧的iPad上可能会很慢 - 特别是如果越来越多的地点被添加到此列表中。在开始循环之前,我希望能够使用某种NSPredicate来过滤我的初始列表。

1 个答案:

答案 0 :(得分:0)

实际上没有任何标准的Objective-C结构非常适合查找范围内的值 - 您几乎必须逐个搜索(尽管您可以使用“谓词”来“隐藏”在filteredArray...运算等内部进行搜索,从而编写更少的代码行。

有效地在一行上的边界之间查找值的最佳结构可能是一个按二进制搜索算法搜索的值排序的数组。你需要对下限进行一次二进制搜索,然后为上限进行另一次二进制搜索。这是log(n)的复杂性,因此对于大型列表非常有效(如果您不必经常对列表进行排序)。

准确地说,如何对二维表面进行此操作更难以确定。也许首先使用上述技术在X方向上找到“候选”,然后检查它们的Y坐标。但不会是log(n)。