CoreData + Magical Record 运行选择查询

Posted

技术标签:

【中文标题】CoreData + Magical Record 运行选择查询【英文标题】:CoreData + Magical Record running select query 【发布时间】:2013-12-20 15:07:08 【问题描述】:

我有一个带有 sqlite 数据库的应用程序,其中包含 7000 多条记录,其中包含城市名称、经度和纬度。这些“城市”也连接到数据库中的相关城市字段。

我的应用程序所做的是,使用核心位置查询当前位置,获取 lon 和 lat 值,然后从数据库中找到最近的位置。

结果不必非常准确(我只想匹配城市),所以我想使用 Hypotenuse 公式来找到最近的点:

closest city in db: min((x1-x2)^2 +(y1-y2)^2)^(1/2)

x1, y1: lon and lat for user
x2, y2: lon and lat for points in database. 

如果我使用的是 ms-sql 或 sqlite 数据库,我可以轻松地创建一个查询,但是当涉及到核心数据时,我就没有主意了。

我不想获取所有数据(并填充内存)然后在所有字段上聚合这个公式,那么有没有办法创建查询并从数据库中获取结果?

我是不是想多了这个问题,错过了一个简单的解决方案?

【问题讨论】:

【参考方案1】:

如果我对您的问题的理解正确,您希望找到离您当前位置最近的“n”个城市。

我有类似的东西,这就是我的处理方法。

本质上,您可能需要获取每个城市的纬度/经度并将其散列到某个索引中。我们使用墨卡托投影将纬度/经度转换为 x/y,然后以类似于 Google/Bing/Apple 地图散列其地图图块的方式散列该值。幸运的是,MapKit 有一个内置的墨卡托投影功能。

在伪代码中:

for each city's lat/lon 
    CLLocationCoordinate2D coordinate = (CLLocationCoordinate2D)lat, lon;
    MKMapPoint point = MKMapPointForCoordinate(coordinate);
    //256 represents the size of a map tile at zoomLevel 20.  You can use whatever zoomLevel 
    //you want here, but we need something to quickly lookup close-by cities.
    //this is the formula you can use to determine how granular your index is
    //(256 * pow(2, (20 - zoomLevel)))
    NSInteger x = point.x/256.0;
    NSInteger y = point.y/256.0;
    save x & y in a CityHashIndex table

现在,您获取当前位置的纬度/经度,将其哈希到上面的索引中,然后简单地针对这个 CityHashIndex 表编写一个查询。

这么说,为简单起见,您当前的位置索引为1000, 1000。因此,要查找附近的城市,也许您搜索索引范围为 `900-1100, 900-1100' 的城市。

从那里开始,您现在只需要拉入小得多的城市集,并且处理您的斜边公式所需的内存还不错。

如果你有兴趣,我可以详细说明。

【讨论】:

这似乎很有趣.. 好吧,我只想找到 1 个城市.. 你能解释一下“散列 x/y”的更多信息吗?为什么我需要散列这些值? 好的,我做了一些研究,这似乎是最好的答案。我会试试这个 coe 并告诉你结果:)【参考方案2】:

这与一个关于 Core Data 的常见问题直接相关。

Searching for surrounding suburbs based on latitude & longitude using Objective C

围绕您需要的点计算一个边界框(min lat/long max lat/long),然后针对这些值使用 NSPredicate 来查找框内的所有内容。从那里您可以对返回的结果进行距离计算并对它们进行排序。

我建议将其设置为可以搜索多个距离,然后您可以查看一个城市是否在 10 英里、100 英里等范围内。慢慢增加边界框,直到获得一个或多个结果。

【讨论】:

【参考方案3】:

我会使用 NSPredicate 来定义我的搜索条件,它将充当过滤器。我不确定这是如何优化的,以及它是否会提取所有寄存器,但我假设 coreData 具有某种可以优化搜索的索引机制。

你可以看看这个文件

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdFetching.html

检查名为的部分

检索特定对象

【讨论】:

我已经在很多地方使用 nspredicate,我的问题是如何将上述公式合并到 nspredicate..(如果可能的话)

以上是关于CoreData + Magical Record 运行选择查询的主要内容,如果未能解决你的问题,请参考以下文章

Magical Record,CoreData,删除一条记录并重新编号

使用 Magical Record 将对象数组插入 Core Data

导入与 Core Data 和 Magical Record 的关系

如何在 Core Data 和 Magical Record 中存储一系列电子邮件

使用 Kiwi、Core Data 和 Magical Record 进行单元测试

Plain Core Data vs Core Data + Magical Record