2014-09-22 104 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

相关问题