How to store CLLocationCoordinate2D?

2019-02-07 03:37发布

I'm attempting to build an application that builds and saves routes similar to map my run. I'm using the Breadcrumb sample code, specifically the CrumbPath and CrumbPathView as the base of my routes, from Apple. Two questions:

  1. If I try to access the MKMapPoint *points object of the CrumbPath like so:

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

    my app crashes, saying:

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

    Which I have a hard time understanding, because within the CrumbPath.m file, the folks at apple write to the "array" by explicitly acquiring the write lock, and then unlocking it, but if I acquire the read lock and attempt to read from it, it crashes.

  2. The reason I attempt to access the points is in an attempt to get the MKMapPoints, convert them to CLLocationCoordinate2D objects, and save them so I can redraw the polyline at the user's request. Since I cannot get access to the points, I attempt to save the CLLocationCoordinate2D objects from my locationManager that I send to the _route in an array to upload to my Parse backend, but I always get an error saying:

    Sending 'CLLocationCoordinate2D' to parameter of incompatible type 'id'
    

    Which isn't making this any easier. Does anybody have any insight to why I'm getting these errors?

Location Manager Delegate

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

    //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条回答
做个烂人
2楼-- · 2019-02-07 04:14

Whatever api you're using to talk to parse is expecting an id which is a pointer to any object. A cllocationcoordinate2d is a c-struct of two doubles and not an object if I'm not mistaken. You should probably create a little wrapper object to save those two doubles and convert them to/from CLLocationCoordinate2d items.

查看更多
可以哭但决不认输i
3楼-- · 2019-02-07 04:23

Regarding your first issue, the crash was because of this:

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

It should be:

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

As mentioned in my comments, %d should be used for count and %@ will cause a crash.

Regarding your second issue, you cannot add a c struct to an NSArray. You should wrap it in NSValue before adding it to an array. CLLocationCoordinate2D is a c-struct. Check the documentation here.

Change this:

[_routePoints addObject:_userLocation];

to:

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

To get the coordinate back from NSValue, you can use,

[aValue MKCoordinateValue];

As mentioned in your error message, you were trying to add CLLocationCoordinate2D to an array which expects an object.

查看更多
叼着烟拽天下
4楼-- · 2019-02-07 04:36

1:

Line: NSLog(@"%@", _route.points); is wrong

_route.points is not a String, and you are using the NSStrig formating symbol "%@".

Further:

Since CLLocationCoordinate2D is a C-Sruct and not an Objective-C Object, you probaly want to create an own GeoPoint class.

查看更多
登录 后发表回答