2014-09-22 10 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]; 
}]; 

그러나 내 응용 프로그램 충돌 루프의 전에 말 :

이 거리를 계산하기 위해, 나는 이 코드 발견했다. 중단 점과 함께 이상한 주석 ( Location* 대신 MKUserLocation*)이 있음을 발견했습니다.

확인되지 않음 (충돌) :
enter image description here

OK (NO 충돌) :
enter image description here

self.mapView.annotations 거기 MKUserLocation 인이 MKUserLocation* 하나, 응용 프로그램 충돌 후 ? 그것을 무시하는 방법?

로그 :

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) 

: http://blog.smartfrog.fr/post/32123941502/tutorial-ios-mapkit

답변

2

MKUserLocation : 내가 CSV 파일을 구문 분석이 페이지의 코드를 사용하고, 그 문제 생각하지 않습니다 "이상한"주석이 아닙니다.

showsUserLocationYES으로 설정하면 맵보기에서 추가 한 사용자 위치 (파란색 점) 주석의 문서화 된 클래스입니다.

지도보기의 annotations 배열에는 모두 개의 주석이지도에 추가되어 있습니다 (지도보기 또는 사용자가 특정 순서로 표시하지 않음).

Location 유형의 주석 만 처리하려면 isKindOfClass 메소드를 사용하여 처리하기 전에 주석 객체의 클래스를 확인할 수 있습니다.

주석이 해당 클래스가 아닌 경우 건너 뜁니다 (continue 루프).


당신은 그것이 MKUserLocation 주석에 distance 속성에 액세스하려고하기 때문에 배열을 정렬 코드와 유사한 문제가 있습니다. 대신지도보기의 annotations 배열에서 정렬 된 배열을 만들려고의

, 나는 단지 Location 주석의 별도의 배열을 생성 제언에 대한 루프와 그 배열을 정렬 (당신이 distance 설정 같은 시간에).에 isKindOfClass를 사용

예는 대한 루프 및 정렬 변경 :

-(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