Как хранить CLLocationCoordinate2D?


Я пытаюсь создать приложение, которое строит и сохраняет маршруты, похожие на карту моего запуска. Я использую Breadcrumb пример кода, в частности CrumbPath и CrumbPathView в качестве основы моих маршрутов, от Apple. Два вопроса:

  1. Если я попытаюсь получить доступ к объекту MKMapPoint *points из CrumbPath следующим образом:

    [_route lockForReading];
    NSLog(@"%@", _route.points);
    NSLog(@"%d", _route.pointCount);
    [_route unlockForReading];
    

    Мое приложение вылетает, говоря:

    Thread 1: EXC_BAD_ACCESS (code: 1, address: 0x9450342d)
    

    Который мне трудно понять, потому что в файле CrumbPath.m люди из apple пишут в " массив" явно получив блокировку записи, а затем разблокировав ее, но если я получу блокировку чтения и попытаюсь прочитать из нее, она вылетит.

  2. Причина, по которой я пытаюсь получить доступ к points, заключается в попытке получить MKMapPoints, преобразовать их в объекты CLLocationCoordinate2D и сохранить их, чтобы я мог перерисовать polyline по запросу пользователя. Поскольку я не могу получить доступ к points, я пытаюсь сохранить объекты CLLocationCoordinate2D из моего locationManager, которые я отправляю в массив _route, чтобы загрузить в мой Парс бэкэнд, но я всегда получаю ошибку, говоря:

    Sending 'CLLocationCoordinate2D' to parameter of incompatible type 'id'
    
    Что отнюдь не облегчает ситуацию. Есть ли у кого-нибудь понимание, почему я получаю эти ошибки?

Делегат Менеджера Местоположения

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
    if (_userLocation.longitude != manager.location.coordinate.longitude
        && _userLocation.latitude != manager.location.coordinate.latitude) {
        _userLocation = manager.location.coordinate;
    }

    if (_isRecording) {
        if (!_route) {
            NSLog(@"lat: %f, lng: %f", _userLocation.latitude, _userLocation.longitude);
            _route = [[CrumbPath alloc] initWithCenterCoordinate:_userLocation];
            [_mapView addOverlay:_route];

            MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(_userLocation, 2000, 2000);
            [_mapView setRegion:region animated:YES];
        }else {
            MKMapRect updateRect = [_route addCoordinate:_userLocation];

            if (!MKMapRectIsNull(updateRect)) {
                MKZoomScale currentZoomScale = (CGFloat)(_mapView.bounds.size.width / _mapView.visibleMapRect.size.width);
                CGFloat lineWidth = MKRoadWidthAtZoomScale(currentZoomScale);
                updateRect = MKMapRectInset(updateRect, -lineWidth, -lineWidth);
                [_routeView setNeedsDisplayInMapRect:updateRect];
            }
        }
        [_routePoints addObject:_userLocation];

        [_route lockForReading];
        NSLog(@"%d", _route.pointCount);
        NSLog(@"%@", _route.points);
        [_route unlockForReading];
    }
}

Остановить Запись Логики

    //stop recording
    NSLog(@"STOP");
    if (_route) {
        NSLog(@"There is a route");
        //Show route options toolbar
        [_route lockForReading];

        NSLog(@"%@", _route);
        NSLog(@"%d", _route.pointCount);
        NSLog(@"%@", _route.points);

        PFObject *routeToSave = [PFObject objectWithClassName:@"Routes"];
        //[routeToSave setObject:_route forKey:@"routePoints"];

        [_route unlockForReading];

        [routeToSave saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
            if (!error) {
                NSLog(@"%c", succeeded);
            }else {
                NSLog(@"%@", error);
            }
        }];
    }
3 7

3 ответа:

Что касается вашего первого вопроса, сбой произошел из-за этого:

NSLog(@"%@", _route.pointCount);

Это должно быть:

NSLog(@"%d", _route.pointCount);

Как упоминалось в моих комментариях, %d следует использовать для подсчета и %@ вызовет сбой.

Что касается вашего второго вопроса, Вы не можете добавить структуру c к NSArray. Вы должны обернуть его в NSValue, прежде чем добавлять его в массив. CLLocationCoordinate2D-это c-структура. Проверьте документацию здесь.

Измените это:

[_routePoints addObject:_userLocation];

Кому:

NSValue *aValue = [NSValue valueWithMKCoordinate:_userLocation];
[_routePoints addObject:aValue];

Чтобы получить координаты назад от NSValue, вы можете использовать,

[aValue MKCoordinateValue];

Как указано в сообщении об ошибке, вы пытались добавить CLLocationCoordinate2D в массив, который ожидает объект.

Любой api, который вы используете для анализа, ожидает идентификатор, который является указателем на любой объект. Cllocationcoordinate2d-это c-структура из двух двойников, а не объект, если я не ошибаюсь. Вероятно, вам следует создать небольшой объект-оболочку, чтобы сохранить эти два двойника и преобразовать их в/из cllocationcoordinate2d элементов.

1:

Строка: NSLog(@"%@", _route.points); неверно

_route.points не является строкой, и вы используете формирующий символ NSStrig "%@".

Далее:

Поскольку CLLocationCoordinate2D является объектом C-SR, а не Objective-C, вы, вероятно, захотите создать собственный класс GeoPoint.