CoreData + Magical Record运行选择查询

时间:2013-12-20 15:07:09

标签: objective-c core-data nspredicate magicalrecord magicalrecord-2.2

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

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

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

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数据库,我可以很容易地创建一个查询,但是当涉及到核心数据时,我就没有想法了。

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

我是否过度思考这个问题,并错过了一个简单的解决方案?

3 个答案:

答案 0 :(得分:1)

这与关于核心数据的常见问题直接相关。

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

计算您需要的点周围的边界框(最小纬度/长度最大纬度/长度)然后对这些值使用NSPredicate来查找框内的所有内容。从那里,您可以对返回的结果进行距离计算并对其进行排序。

我建议设置它以便它可以在多个距离搜索,然后你可以看到一个城市是否在10英里,100英里等之内。慢慢增加边界框,直到你得到一个或多个结果。

答案 1 :(得分:1)

如果我正确理解您的问题,您可能希望找到距您当前所在地最近的“n”城市。

我有类似的东西,这就是我接触它的方式。

从本质上讲,你可能需要把每个城市的纬度/经度拿到一些索引中。我们使用墨卡托投影将纬度/经度转换为x / y,然后以类似于Google / Bing / Apple Maps散列其地图图块的方式散列该值。幸运的是,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
}

现在,你得到当前位置的lat / lon,哈希进入索引,如上所述,只需针对这个CityHashIndex表写一个查询。

所以说,为简单起见,您当前的位置已编入1000, 1000的索引。因此,要在城市附近找到,也许您会搜索索引范围为“900-1100,900-1100”的城市。

从那里开始,你现在只能吸引更少的城市,并且处理你的斜边公式的记忆要求并不是那么糟糕。

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

答案 2 :(得分:0)

我会使用NSPredicate定义我的搜索条件,它将充当过滤器。我不确定它是如何优化的,如果它会拉出你的所有寄存器但是我假设coreData有某种索引机制可以优化搜索。

您可以查看此文档

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

检查名为

的部分

检索特定对象