使用距离从位置有效地计算最近的5个位置

时间:2013-01-02 17:08:26

标签: iphone objective-c ios mapkit cllocationmanager

我的SQLite数据库中有大约2500条记录,每条记录代表我们国家知名商店的一个分支,我使用distanceFromLocation来比较当前用户的位置之间的距离和这样的给定地点:

CLLocation* storeLocation = [[CLLocation alloc] initWithLatitude:lat longitude:lon];
double distance = [userLocation distanceFromLocation:storeLocation]; 

如何使用这段代码(以高效的方式解冻用户界面)找到当地lat/lon对中最近的5个SQLite对分支{{ 1}}数据库?

编辑:

the code here是如何计算数据库级别上两点之间距离的一个很好的例子,所以它非常有效,但是,这些代码很难实现。因为它可以访问SQLite并手动创建查询,任何人都会为我提供该代码的工作示例,我将非常感激。

2 个答案:

答案 0 :(得分:3)

但是你想要这样做,为了避免阻止你必须在另一个线程中执行此操作。您可以通过多种方式实现这一目标。这是GCD的一个例子:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    NSArray *closestFive = [self closestFive];
    dispatch_async(dispatch_get_main_queue(), ^{
         //Tell yourself something when the process finished
         [self closestAre:closestFive];
    }
});

[self nearestFive]可以通过循环遍历位置,计算距离,使用包含在NSValue中的CLLocation作为关键字将它们存储在字典中来天真地实现。对其进行排序,并返回该数组的subarrayWithRange :.可能有更好的实现,但对于2500个元素,这并不是很多,这种做法就足够了,只要你在后台线程中做到这一点

这可能是它的实现:

- (NSArray *)closestFive:(CLLocation *)location from:(NSArray *)locations
{
    NSMutableArray *distances = [NSMutableArray arrayWithCapacity:locations.count];

    for (CLLocation *l in locations) {
        NSDictionary *d = @{
            @"location" : l,
            @"distance" : @([location distanceFromLocation:l])
        };
        [distances addObject:d];
    }
    [distances sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        double d1 = [obj1[@"distance"] doubleValue];
        double d2 = [obj1[@"distance"] doubleValue];

        if (d1 > d2) {
            return NSOrderedDescending;
        }
        else if (d1 < d2) {
            return NSOrderedAscending;
        }
        return NSOrderedSame;
    }];
    return [[distances subarrayWithRange:NSMakeRange(0, 5)] valueForKey:@"location"];
}

答案 1 :(得分:1)

查看这个(有效的)答案和Kenny Winker的评论:

https://stackoverflow.com/a/6828849/1611723

这是一个类似的问题,会帮助你。