2

ユーザーとすべての注釈の間の距離を計算したい。
私の注釈は、解析された csv ファイルから取得されます。私の注釈はLocationクラスにあります。距離の計算以外はすべて正常に機能します。

距離を計算するために、次のコードを見つけました。

-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)newLocation
{

    for (Location *annotation in self.mapView.annotations) {
    CLLocationCoordinate2D coord = [annotation coordinate];
    CLLocationCoordinate2D userCoordinate = [[[self.mapView userLocation] location] coordinate];
    CLLocation *myLoc = [[CLLocation alloc] initWithLatitude:coord.latitude longitude:coord.longitude];
    CLLocation *userLoc = [[CLLocation alloc] initWithLatitude:userCoordinate.latitude longitude:userCoordinate.longitude];

     annotation.distance = [myLoc distanceFromLocation:userLoc];


        NSLog(@"Distance is = %f", annotation.distance);
} // ! CRASH !

NSArray *sortedArray;
sortedArray = [self.mapView.annotations sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
    NSNumber *first = [NSNumber numberWithDouble:[(Location*)a distance]];
    NSNumber *second = [NSNumber numberWithDouble:[(Location*)b distance]];
    return [first compare:second];
}];

しかし、ループの終了にアプリがクラッシュします。ブレークポイントを使用して、奇妙な注釈 (MKUserLocation*の代わりにLocation*) があることを発見しました。この後MKUserLocation*、アプリがクラッシュします。

OK ではありません (クラッシュ):
ここに画像の説明を入力

OK (クラッシュなし):
ここに画像の説明を入力

なぜMKUserLocation私の中にあるのself.mapView.annotationsですか?それを無視する方法は?

ログ:

2014-09-22 06:01:47.965 MyFirstGPS2[472:60b] -[MKUserLocation setDistance:]: unrecognized selector sent to instance 0x9db0bb0
2014-09-22 06:01:48.030 MyFirstGPS2[472:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MKUserLocation setDistance:]: unrecognized selector sent to instance 0x9db0bb0'
*** First throw call stack:
(
    0   CoreFoundation                      0x01d971e4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x01b168e5 objc_exception_throw + 44
    2   CoreFoundation                      0x01e34243 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
    3   CoreFoundation                      0x01d8750b ___forwarding___ + 1019
    4   CoreFoundation                      0x01d870ee _CF_forwarding_prep_0 + 14
    5   MyFirstGPS2                         0x00005043 -[HPViewController mapView:didUpdateUserLocation:] + 1203
    6   MapKit                              0x006825e6 -[MKMapView(MKHeadingAdditions) _stopTrackingHeading] + 469
    7   MapKit                              0x00666a92 -[MKMapView _setUserTrackingMode:animated:fromTrackingButton:] + 301
    8   MapKit                              0x00666960 -[MKMapView setUserTrackingMode:animated:] + 56
    9   MapKit                              0x00682176 -[MKMapView(MKHeadingAdditions) disableHeadingTracking:] + 65
    10  MapKit                              0x00669524 -[MKMapView _didChangeRegionMidstream:] + 672
    11  MapKit                              0x00671fbd -[MKMapView mapLayerDidChangeVisibleRegion:] + 66
    12  VectorKit                           0x0407a15e -[VKMapView mapDidChangeVisibleRegion:] + 78
    13  VectorKit                           0x040821fe -[VKMapCanvas cameraControllerDidChangeCameraState:] + 46
    14  VectorKit                           0x0409f1f7 -[VKMapCameraController updatePanWithTranslation:] + 231
    15  VectorKit                           0x0408268f -[VKMapCanvas updatePanWithTranslation:] + 63
    16  VectorKit                           0x0407aca9 -[VKMapView updatePanWithTranslation:] + 73
    17  MapKit                              0x0069e30b -[MKMapGestureController handlePan:] + 530
    18  UIKit                               0x00b724f4 _UIGestureRecognizerSendActions + 230
    19  UIKit                               0x00b71168 -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 383
    20  UIKit                               0x00b72bdd -[UIGestureRecognizer _delayedUpdateGesture] + 60
    21  UIKit                               0x00b7613d ___UIGestureRecognizerUpdate_block_invoke + 57
    22  UIKit                               0x00b760be _UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks + 317
    23  UIKit                               0x00b6c7ac _UIGestureRecognizerUpdate + 199
    24  UIKit                               0x00817a5a -[UIWindow _sendGesturesForEvent:] + 1291
    25  UIKit                               0x00818971 -[UIWindow sendEvent:] + 1021
    26  UIKit                               0x007ea5f2 -[UIApplication sendEvent:] + 242
    27  UIKit                               0x007d4353 _UIApplicationHandleEventQueue + 11455
    28  CoreFoundation                      0x01d2077f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
    29  CoreFoundation                      0x01d2010b __CFRunLoopDoSources0 + 235
    30  CoreFoundation                      0x01d3d1ae __CFRunLoopRun + 910
    31  CoreFoundation                      0x01d3c9d3 CFRunLoopRunSpecific + 467
    32  CoreFoundation                      0x01d3c7eb CFRunLoopRunInMode + 123
    33  GraphicsServices                    0x03acf5ee GSEventRunModal + 192
    34  GraphicsServices                    0x03acf42b GSEventRun + 104
    35  UIKit                               0x007d6f9b UIApplicationMain + 1225
    36  MyFirstGPS2                         0x00013592 main + 130
    37  libdyld.dylib                       0x0258a701 start + 1
    38  ???                                 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

: このページのコードを使用して csv ファイルを解析していますが、それが問題だとは思いません: http://blog.smartfrog.fr/post/32123941502/tutorial-ios-mapkit

4

1 に答える 1

2

MKUserLocation「奇妙な」注釈ではありません。

showsUserLocationこれは、 に設定したときにマップ ビューによって追加されるユーザー位置 (青い点) 注釈の文書化されたクラスですYES

マップ ビューのannotations配列には、ユーザーまたはマップ ビューによってマップに追加されたすべての注釈が含まれます (これらは特定の順序ではないことに注意してください)。

type の注釈のみを処理するようにするLocationには、メソッドを使用して処理する前に、注釈オブジェクトのクラスを確認しますisKindOfClass

注釈がそのクラスのものでない場合は、スキップします (continueループ)。


アノテーション のdistanceプロパティに アクセスしようとするため、配列をソートするコードでも同様の問題が発生します。MKUserLocation

マップ ビューの配列から並べ替えられた配列を作成しようとする代わりに、for ループで注釈annotationsだけの別の配列を作成しLocation(同時に を設定distance)、その配列を並べ替えることをお勧めします。

isKindOfClassfor ループと並べ替えの変更で使用する例:

-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)newLocation
{
    if (newLocation == nil) {
        //can happen if still waiting for user permission
        return;
    }
    if (!CLLocationCoordinate2DIsValid(newLocation.coordinate)) {
        //can happen if just resumed from some time in the background
        return;
    }

    //Declare and set user location variables outside the for-loop
    //since they won't be changing during the loop...
    CLLocationCoordinate2D userCoordinate = [[[self.mapView userLocation] location] coordinate];
    CLLocation *userLoc = [[CLLocation alloc] initWithLatitude:userCoordinate.latitude longitude:userCoordinate.longitude];

    //declare array in which you will put your Location annotations for sorting later...
    NSMutableArray *locAnnArray = [NSMutableArray array];

    //Declare the loop variable as a generic id<MKAnnotation>   
    for (id<MKAnnotation> annotation in self.mapView.annotations) {
        //Before processing the annotation, check it it's of type Location...
        if (! [annotation isKindOfClass:[Location class]]) {
            continue;
        }

        //Cast annotation to Location so we can see the distance property...
        Location *locAnn = (Location *)annotation;

        CLLocationCoordinate2D coord = [locAnn coordinate];
        CLLocation *myLoc = [[CLLocation alloc] initWithLatitude:coord.latitude longitude:coord.longitude];

        locAnn.distance = [myLoc distanceFromLocation:userLoc];

        NSLog(@"Distance is = %f", locAnn.distance);

        //Add Location annotation to local array for later sorting...   
        [locAnnArray addObject:locAnn];
    }

    //Sort our array of Location annotations...
    [locAnnArray sortUsingComparator:^NSComparisonResult(id a, id b) {
        NSNumber *first = [NSNumber numberWithDouble:[(Location*)a distance]];
        NSNumber *second = [NSNumber numberWithDouble:[(Location*)b distance]];
        return [first compare:second];
    }];

    //do something with the sorted array...
    //...
}
于 2014-09-22T16:21:40.040 に答える