4

Core Data に地理的な場所のリストがあります (エンティティ名は「Stops」です)。

現在の場所で並べ替えたいので、近くにある場所をユーザーに表示できます。結果をUITableViewに簡単に表示できるように、NSFetchedResultsControllerを使用しています。

このソートを試みるために、次のコードを使用しています。

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"stop_lat" ascending:YES comparator:^NSComparisonResult(Stops *obj1, Stops *obj2) {
    CLLocation *currentLocation = locationManager.location;

    CLLocation *obj1Location = [[CLLocation alloc]initWithLatitude:[obj1.stop_lat doubleValue] longitude:[obj1.stop_lon doubleValue]];
    CLLocation *obj2Location = [[CLLocation alloc]initWithLatitude:[obj2.stop_lat doubleValue] longitude:[obj2.stop_lon doubleValue]];

    CLLocationDistance obj1Distance = [obj1Location distanceFromLocation:currentLocation];
    CLLocationDistance obj2Distance = [obj2Location distanceFromLocation:currentLocation];

    NSLog(@"Comparing %@ to %@.\n  Obj1 Distance: %f\n  Obj2 Distance: %f",obj1.stop_name, obj2.stop_name, obj1Distance, obj2Distance);

    if (obj1Distance > obj2Distance) {
        return (NSComparisonResult)NSOrderedDescending;
    }

    if (obj1Distance < obj2Distance) {
        return (NSComparisonResult)NSOrderedAscending;
    }

    return (NSComparisonResult)NSOrderedSame;
}];

NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[fetchRequest setEntity:[NSEntityDescription entityForName:[Stops entityName] inManagedObjectContext:context]];

frcNearby = [[NSFetchedResultsController alloc]
          initWithFetchRequest:fetchRequest
          managedObjectContext:context
          sectionNameKeyPath:nil
          cacheName:nil];

NSError *error;
BOOL success = [frcNearby performFetch:&error];
if (error) NSLog(@"ERROR: %@ %@", error, [error userInfo]);

ただし、私の NSFetchedResultsController は、ユーザーの現在の場所で並べ替えるのではなく、指定したキー (「stop_lat」) で並べ替えたすべてのアイテムを返すだけです。

そこの NSLog が印刷されないため、コンパレータ ブロックが呼び出されないようです。

ここで何が欠けていますか?

4

4 に答える 4

6

Objective-C ベースのソート記述子は、フェッチ要求では使用できません。

「コアデータプログラミングガイド」から:

... 要約すると、ただし、フェッチを直接実行する場合は、通常、Objective-C ベースの述語またはソート記述子をフェッチ要求に追加しないでください。代わりに、これらをフェッチの結果に適用する必要があります。

于 2012-08-19T15:51:38.130 に答える
3

これに対する別の見方は、「Stop」managedObject に meanSquared (おそらく NSDecimalNumber) と呼ばれるプロパティを設定することです。

デバイスの緯度/経度が十分に移動して「最寄りのストップ」データが変更されたら、すべての「ストップ」オブジェクトを meanSquared 距離 (つまり、(yourLat-stopLat)^2+(yourLong-stopLong)^2) で更新します。 sortDescriptor で「meanSquared」を使用するだけです。

ユーザーの位置を更新する回数、ストップ間の距離、およびストップの数によっては、これが最適なソリューションになる場合があります。

于 2012-11-14T14:14:37.527 に答える
1

とにかく緯度/経度で並べ替えることはできません。各ポイントの距離を計算し、それで並べ替える必要があります。または、ユーザーの近くの緯度/経度値の範囲をフェッチし、そのサブセットをフェッチし、それらの距離を計算して表示します。フェッチの範囲は、ユーザーの緯度 +/- 0.1 度などになります。

于 2012-08-19T19:47:28.573 に答える