0

我的SQLite数据库中有大约 2500 条记录,每条记录代表我国一家知名商店的分店,我distanceFromLocation用来比较当前用户位置与给定位置之间的距离,如下所示:

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

如何使用这段代码(通过一种不会冻结 UIlat/lon的有效方式)在存储在本地SQLite数据库中的2500 对中找到最近的 5 个分支?

编辑 :

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

4

2 回答 2

3

无论您想这样做,为了避免阻塞 UI,您必须在另一个线程中执行此操作。您可以通过多种方式实现这一目标。以下是 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"];
}
于 2013-01-02T17:24:30.390 回答
1

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

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

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

于 2013-01-04T16:14:47.530 回答