2013-03-01 1 views
2

iOS 응용 프로그램을 작성하여 여행 경로를 기록한 다음 나중에 검색 할 수 있도록 저장합니다. 경로를 그리기위한 대부분의 코드는 샘플 코드 Breadcrumb을 기반으로합니다.나중에 검색 할 파일에 MKOverlay 개체를 저장하는 방법

이제 그려진 오버레이를 저장하는 기능을 추가하고 있습니다. 가장 좋은 방법은 무엇입니까? CoreData을 사용할 수는 있지만 나중에 다시 가져 오는 대신 그리기 오버레이를 많이 수행하지 않을 것입니다. 나는 현재 간단한 시도를했습니다 NSArray. CrumbPath 객체를 NSData으로 변환하여 배열에 저장합니다. 나중에 그것을 검색하여 다시 CrumbPath로 변환합니다. 그러나, 나는 뭔가 잘못하고있는 것 같습니다.

NSData *pointData = [NSData dataWithBytes:crumbs.points length:crumbs.pointCount * sizeof(MKMapPoint)]; 
[patternArray addObject:pointData]; 
[timeArray addObject:date]; 

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; 
// Create the full file path by appending the desired file name 
NSString *patternFile = [documentsDirectory stringByAppendingPathComponent:@"patterns.dat"]; 
NSString *timeFile = [documentsDirectory stringByAppendingPathComponent:@"times.dat"]; 

//Save the array 
[patternArray writeToFile:patternFile atomically:YES]; 
[timeArray writeToFile:timeFile atomically:YES]; 

을 그리고 테이블에 표시 나중에이 같은를 검색 :

@interface CrumbPath : NSObject <MKOverlay> 
{ 
    MKMapPoint *points; 
    NSUInteger pointCount; 
    NSUInteger pointSpace; 

    MKMapRect boundingMapRect; 

    pthread_rwlock_t rwLock; 
} 

- (id)initWithCenterCoordinate:(CLLocationCoordinate2D)coord; 
- (MKMapRect)addCoordinate:(CLLocationCoordinate2D)coord; 

@property (readonly) MKMapPoint *points; 
@property (readonly) NSUInteger pointCount; 

@end 

나는이 같은 CrumbPath 객체 "부스러기"를 저장

NSData *pointData = [appDelegate.patternArray objectAtIndex:indexPath.row]; 
MKMapPoint *points = malloc(pointData.length); 
(void)memcpy([pointData bytes], points, sizeof(pointData)); 

그리고 다시 경로를 구성 :

crumbs = [[CrumbPath alloc] initWithCenterCoordinate:MKCoordinateForMapPoint(points[0])]; 
for (int i = 1; i <= pointCount; i++) { 
    [crumbs addCoordinate:MKCoordinateForMapPoint(points[i])]; 
}  
[map addOverlay:crumbs]; 

그러나 오류 얻을 : 다음과 같이 개인적으로 'NSInvalidArgumentException', reason: '-[NSConcreteData isEqualToString:]: unrecognized selector sent to instance

+0

귀하의 예외와 관련없이, 귀하는 'malloc'에 대한 귀하의 전화를 보여 주지만 해당 '무료'전화는 아닙니다. 나는 당신이 어딘가에 있다고 가정하지만, 너 자신을 깨끗이 청소해야한다. 또는'malloc'과'memcpy'에 대한 호출을 피할 수 있습니다 (아래 코드 샘플처럼). 걱정할 필요가 없습니다. – Rob

답변

2

을, 내가 할 의향이 될 것입니다 :

  1. 첫째, 내가 CLLocationCoordinate2D의 C 배열을 저장하는 경향 거라고 내가 MKPolygon 인스턴스에 전달할 것을 좌표 메서드 polygonWithCoordinates (MKMapPoint C 배열 대신). MKMapPoints을 사용하려는 경우이 코드를 적용 할 수 있지만 외부에서 조사하여 이해할 수있는 형식 (즉, 위도 및 경도 값 CLLocationCoordinate2D)을 선호합니다.

    MKPolygon* poly = [MKPolygon polygonWithCoordinates:coordinates count:count]; 
    

    당신은, 그러므로과 같이 좌표를 구할 수 :

    [self writeCoordinates:coordinates count:count file:filename]; 
    

    writeCoordinates:count:filename: 다음과 같이 정의된다 : 그래서, 그래서 같은 코드의 라인과 함께 당신의 MKPolygon 만드는 것이 가정하자

    :
    - (void)writeCoordinates:(CLLocationCoordinate2D *)coordinates count:(NSUInteger)count file:(NSString *)filename 
    { 
        NSData *data = [NSData dataWithBytes:coordinates length:count * sizeof(CLLocationCoordinate2D)]; 
        [data writeToFile:filename atomically:NO]; 
    } 
    

    그 다음으로 파일에서 MKPolygon을 만들 수 polygonWithContentsOfFile 같이 정의된다

    :

    - (MKPolygon *)polygonWithContentsOfFile:(NSString *)filename 
    { 
        NSData *data = [NSData dataWithContentsOfFile:filename]; 
        NSUInteger count = data.length/sizeof(CLLocationCoordinate2D); 
        CLLocationCoordinate2D *coordinates = (CLLocationCoordinate2D *)data.bytes; 
    
        return [MKPolygon polygonWithCoordinates:coordinates count:count]; 
    } 
    
  2. 또는, 읽고 위의 두 가지 방법을 대체하여, (사람이 읽을 수있는 포맷으로 렌더링되는)을 PLIST 형식 CLLocationCoordinate2D 배열을 작성할 수있다 로 : 분명히

    const NSString *kLatitudeKey = @"latitude"; 
    const NSString *kLongitudeKey = @"longitude"; 
    
    - (void)writeCoordinates:(CLLocationCoordinate2D *)coordinates count:(NSUInteger)count file:(NSString *)filename 
    { 
        NSMutableArray *array = [NSMutableArray arrayWithCapacity:count]; 
    
        for (NSUInteger i = 0; i < count; i++) 
        { 
         CLLocationCoordinate2D coordinate = coordinates[i]; 
         [array addObject:@{kLatitudeKey:@(coordinate.latitude), kLongitudeKey:@(coordinate.longitude)}]; 
        } 
    
        [array writeToFile:filename atomically:NO]; 
    } 
    
    - (MKPolygon *)polygonWithContentsOfFile:(NSString *)filename 
    {   
        NSArray *array = [NSArray arrayWithContentsOfFile:filename]; 
        NSUInteger count = [array count]; 
        CLLocationCoordinate2D coordinates[count]; 
    
        for (NSUInteger i = 0; i < count; i++) 
        { 
         NSDictionary *dictionary = array[i]; 
         coordinates[i].latitude = [dictionary[kLatitudeKey] doubleValue]; 
         coordinates[i].longitude = [dictionary[kLongitudeKey] doubleValue]; 
        } 
    
        return [MKPolygon polygonWithCoordinates:coordinates count:count]; 
    } 
    

당신이 있는지 확인하는 코드 오류 검사를 추가 할 것입니다 그 writeToFiledataWithContentsOfFile (또는 arrayWithContentsOfFile)이 성공했지만 잘하면이 아이디어를 제공합니다.

+0

감사합니다. Rob. 나는이 두 가지 방법을 시도 할 것이다. 그러나 그 오류가 왜 나는지 알 수 있습니까? – Sap

+0

@Sap 나는이 오류가 여러분의 질문에서 나온 코드가 아니라'isEqualToString'을 호출하고있는 곳에서 의심 스럽지만 의심되는 객체는 NSString이 아니라 NSString이라고 생각합니다. 코드에서 isEqualToString의 발생을 검색하는 것이 좋습니다. 결론적으로, 당신은 실제로 그 예외를 생성하는 정확한 코드 행을 식별해야한다. 코드를 단계별로 실행하거나 [예외 브레이크 포인트] (http://developer.apple.com/library/mac/#recipes/xcode_help-breakpoint_navigator/articles/adding_an_exception_breakpoint.html)를 추가하여 문제가되는 코드를 식별 할 수 있습니다. – Rob

+0

처음 MKMapPoints에 대한 코드를 수정하려고했습니다. 여전히 파일을 저장하는 데 문제가있었습니다. 그러나 당신이 제안한대로 나는 포기하고 좌표를 저장했습니다. 그것은 작동합니다. 감사! – Sap

관련 문제