2014-09-22 106 views
2

我想計算用戶和所有註釋之間的距離。
我的註釋來自一個被解析的csv文件。我的註釋位於Location類中。一切工作正常,除了距離計算。爲什麼MKUserLocation在我的註釋中?

計算距離,我發現這段代碼

-(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*之一,應用程序崩潰:

不正常(崩潰):
enter image description here

OK(無碰撞):
enter image description here

爲什麼會有MKUserLocationself.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

回答

2

MKUserLocation不是一個「奇怪」的註釋。

當您將showsUserLocation設置爲YES時,它是由地圖視圖添加的用戶位置(藍點)註釋的記錄類。

地圖視圖的annotations陣列包括所有註釋添加到地圖上 - 無論是由您或地圖視圖(也注意,這些將不會在任何特定的順序)。

爲了確保只處理類型Location的註釋,可以在使用isKindOfClass方法處理註釋對象之前檢查註解對象的類。

如果註釋不是那個類的,請跳過它(continue循環)。


你必須與排序陣列,因爲它會嘗試訪問該MKUserLocation註解distance屬性的代碼類似的問題。

,而不是試圖創建地圖視圖的annotations數組排序後的數組,我建議在創建只是Location註釋的一個單獨的數組的for循環(在您設置distance同一時間),然後排序該數組。使用isKindOfClass

舉例for循環和排序的變化:

-(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... 
    //... 
} 
+0

真棒,謝謝!但是我怎樣才能訪問LocAnnArray中的距離(以及註釋的其他信息)?我實際上正在尋找在屏幕上打印這些信息......希望我會很快找到:/我還有一個問題,可以肯定的是:如果循環執行時用戶位置發生了變化,該怎麼辦?在第一次調用結束之前,didUpdateUserLocation會再次調用嗎?對不起,我的問題,我是一個初學者。 – mexson 2014-09-22 17:49:08

相關問題