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

Posted

技术标签:

【中文标题】使用距位置的距离有效地计算最近的 5 个位置【英文标题】:using distanceFromLocation to calculate nearest 5 locations effeciently 【发布时间】:2013-01-02 17:08:26 【问题描述】:

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

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

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

编辑:

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

【问题讨论】:

你能缩小每个地区/州的搜索范围吗? 查看这个(有效的)答案和 Kenny Winker 的评论:***.com/a/6828849/1611723 好难啊,DB里的每条店铺记录都和一个区有关,全国分为主要区,但是无法知道当前用户现在在哪个区! 我会支持 Baptiste Alexandre 的建议;查询数据库非常快 @BaptisteAlexandre 这是数据库级别的一个很好的例子,但是,实现 Dave 的代码(在那个页面上)有很多问题,而且不像你想象的那么容易,因为他通过手动查询直接访问 SQLite。 【参考方案1】:

无论您想怎么做,为了避免阻塞 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"];

【讨论】:

【参考方案2】:

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

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

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

【讨论】:

以上是关于使用距位置的距离有效地计算最近的 5 个位置的主要内容,如果未能解决你的问题,请参考以下文章

如何在谷歌地图 api 中计算从 1 个位置到许多其他位置的距离? [复制]

2个位置之间的iOS GPS距离计算

查找超过 100K 个位置之间的距离

如何计算一个位置与另一个位置之间的距离/接近度(c#)

如何在Oracle中有效地计算坐标之间的距离

欧几里得距离(python3,sklearn):有效地计算最近的对及其对应的距离