Search code examples
iphonecompass-geolocationdirectionheadingbearing

Using Compass to point to actual coordinate location instead of just North


I have seen a few examples of this but am not sure exactly how to implement it, (such as iPhone Compass GPS Direction) in do I need to call calcBearingWithLatitude in (void)startup?

All I am trying to do is have the compass pull a point from memory and use that point as its "north" so to speak and point to it, no need for distance or anything like that.

My implementation file as of now looks like

@implementation TrackerViewController

@synthesize locationManager; 
@synthesize compass; 
@synthesize headingLabel;

- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];

if ([CLLocationManager headingAvailable]) {

} else {
    [[[[UIAlertView alloc] initWithTitle:@"Error" 
                                 message:@"Device doesn't support heading updates" 
                                delegate:nil 
                       cancelButtonTitle:@"OK" 
                       otherButtonTitles:nil] autorelease] show];   
}
}

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {
double heading = [newHeading magneticHeading] * M_PI / 180.0;
self.compass.transform = CGAffineTransformMakeRotation(-heading);
self.headingLabel.text = [NSString stringWithFormat:@"%d°", (int)[newHeading magneticHeading]];
NSLog(@"%d", (int)[newHeading magneticHeading]);
}


- (void)locationManager:(CLLocationManager *)manager 
   didFailWithError:(NSError *)error {

//  NSLog(@"Error!");

if (error.code == kCLErrorDenied) {
    [[[[UIAlertView alloc] initWithTitle:@"Error" 
                                 message:@"User didn't allow heading updates" 
                                delegate:nil 
                       cancelButtonTitle:@"OK" 
                       otherButtonTitles:nil] autorelease] show];
    [self.locationManager stopUpdatingHeading];
}
}

 - (void)viewDidLoad {
 locationManager=[[CLLocationManager alloc] init];
 locationManager.desiredAccuracy = kCLLocationAccuracyBest;
 locationManager.delegate=self;
 //Start the compass updates.
 [locationManager startUpdatingHeading];
 [super viewDidLoad];
 }

- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

// Release any cached data, images, etc that aren't in use.
}

- (void)dealloc {
self.locationManager = nil;
self.compass = nil;
self.headingLabel = nil;
[super dealloc];
}

@end

Solution

  • I would find the bearing from coordinate A to coordinate B and then use that bearing as an offset for the compass bearing from coordinate A to coordinate B.

    Here are two links for finding a bearing to a coordinate

    Calculating bearing between two CLLocationCoordinate2Ds

    http://shawnsbits.com/blog/2011/07/07/calculating-heading-with-corelocation/

    If you want the compass bearing to update as you move so it always points to coordinate B, then you probably want to recalculate whenever you get a new bearing or location.