【问题标题】:How to fetch managed objects sorted by calculated value如何获取按计算值排序的托管对象
【发布时间】:2010-05-07 11:53:12
【问题描述】:

我正在开发使用 CoreData 的应用程序。存在保存纬度和经度值的位置实体。我想获取那些按到用户位置的距离排序的实体。 我试图将排序描述符设置为距离公式 sqrt ((x1 - x2)^2 + (y1 - y2)^2),但它失败了,出现异常“... keypath ... not found in entity”。

NSString *distanceFormula = [NSString stringWithFormat:@"sqrt(((latitude - %f) * (latitude - %f)) + ((longitude - %f) * (longitude - %f)))", 
                            location.coordinate.latitude, 
                            location.coordinate.latitude, 
                            location.coordinate.longitude, 
                            location.coordinate.longitude];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:distanceFormula ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
NSError *error;
NSArray *result = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];

我想获取已经排序的对象,而不是全部获取它们然后在代码中排序。

感谢任何提示。

【问题讨论】:

    标签: iphone objective-c core-data nsfetchrequest


    【解决方案1】:

    NSSortDescriptor 应该使用对象属性的键字符串进行初始化,而不是查询字符串。这意味着您应该将距离公式实现为对象的方法。

    这样做之后,在获取之前还是之后排序并不重要:

    NSArray *result = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
    result = [result sortedArrayUsingSelector:@"compareDistance"];
    

    还有一点。你的距离公式不能正常工作,因为 lat。并且很长。没有相同的比例,除非你在赤道。使用这个:

    double latDiff = lat1-lat2;
    double longDiff = (long1-long2)*cos(lat1); //cos() assumes lat1 is in radians
    double distance = sqrt(latDiff*latDiff+longDiff*longDiff);
    

    如果距离超过几百公里,需要Spherical cosines law

    // assuming angles in radian,
    double separation = acos( sin(lat1)*sin(lat2) + cos(lat1)*cos(lat2)*cos(long1-long2) );
    double distance = separation*earthRadius;
    

    【讨论】:

    • 你能发布长距离的公式吗?提前谢谢你。
    • 感谢不可原谅。我在答案中添加了公式。
    猜你喜欢
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-30
    • 1970-01-01
    • 1970-01-01
    • 2011-01-02
    相关资源
    最近更新 更多