Compass Calibration problem - iphone

How to get the Direction from Compass Calibration,
i used core location framework and don't know how to get north direction from the function:
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading;
if anybody knows help me to get the solution.

the method is the right. You can chosse between magnetic and true heading.
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading{
float compassHeading_True = newHeading.trueHeading;
float compassHeading_Magnetic = newHeading.magneticHeading;
}
If you want allow compass calibration, you have to implement this method:
- (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager{
return YES;}

Related

How to calculate elevation like in runkeeper application

I have application that track user movement. And I store all relevant data lat/lng/alt etc.
I am trying add elevation like on runkeeper just without graphic I need just to get elevation value.
In my .h file:
#property (nonatomic) double netElevationLoss;
#property (nonatomic) double netElevationGain;
#property (nonatomic) double netElevationChange;
In my .m file:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
double elevationChange = oldLocation.altitude - newLocation.altitude;
if (elevationChange < 0)
{
netElevationLoss += fabs(elevationChange);
}
else
{
netElevationGain += elevationChange;
}
netElevationChange = netElevationGain - netElevationLoss;
...
I don't know is this correct way to calculate it.
I have tested it and alt is for example 182.53 and netElevationChange is -182.53.
Maybe it's good but maybe I am missing something any idea what I have done wrong here?
According to the Wikipedia article you posted, "cumulative elevation gain" is basically the sum of all increases in elevation.
So for example, say you hike 100 feet up, then 100 feet down, then 200 feet up, then 250 feet down (say, a valley), and then 100 feet up, your gain would be 100 + 200 + 150 = 450 feet. The last 150 is due to hiking to an elevation of -50 feet at some point, then 100 feet up again.
Now, what this means to you is that you simply need to take into account positive deltas of altitude, like so:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
double elevationChange = oldLocation.altitude - newLocation.altitude;
// Only take into account positive changes
if (elevationChange > 0)
{
netElevationGain += elevationChange;
}
}
You could even simplify it further:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
netElevationGain += MAX(0, oldLocation.altitude - newLocation.altitude);
}
This would take into account valleys and even "ups and downs" during ascent and descent (which should be counted according to the article).
At the end, the netElevationGain property will contain your gain.

How to make speed calculation accurate in iOS?

I use CLLocation with accuracy of kCLLocationAccuracyBestForNavigation. I am able to calculate the speed accurately. However, there is a 10sec delay in calculation...
For example, when I drive car at from 45mph to 55mph, the device shows 55mph around 10 secs later.
Is there a way we could make it a bit more precise?
Here is the code...
- (void)getSpeed
{
[self.locMgr startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations
{
double numericSpeed;
self.location = [locations lastObject];
numericSpeed = self.location.speed * 3.6 * 0.621371;
}

Store iPhone Location as NSString?

I am fairly new to Objective-c & currently building my first App. I am trying to output an iPhones location to a string to be used in a JSON request.
I have the request built but I am unsure how to get the iPhones location, let alone into a string & the apple Documentation i am finding difficult to follow.
How can I do this?
Edit: I've seen how to implement location like so:
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
CLLocationDegrees latitude = newLocation.coordinate.latitude;
CLLocationDegrees longitude = newLocation.coordinate.longitude;
}
However i am unsure where to put this, this isn't an object is it?
I don't need to initialize it?
I tried editing this to return the newLocation as a stirng instead of void, but how do I call it?
What input do I need into (CLLocationManager *)?
The CLLocationManager class allow you to track your current location.
If you want use it to find your location, that's what you need to do :
// Create an instance of CLLocationManager class :
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
// Set the delegate of your instance :
locationManager.delegate = self; // Set your controller as a <CLLocationManagerDelegate>.
// Now update your location :
[locationManager startUpdatingLocation];
Now, everytime a CLLocationManager instance did update, the delegate method is called :
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;
Which means everytime your locationManager update its location, this method is called.
Now you can overwrite the method by adding in your .m file :
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
// Do whatever you want here
}
For example, if you want to store your current coordinates you can do :
Declare in the .h :
float latitude;
float longitude;
Then complete the delegate method (write this in .m) :
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
latitude = [manager location].coordinate.latitude;
longitude = [manager location].coordinate.longitude;
}
Now you can store your values in NSString like #amar answered.
I have edited this answer like 6 times so I hope this will answer your question and help you :D.
All you need is [NSString stringWithFormat:#"%f",<your float>];

Small Location Change Detection

I'm need to detect small location change for the iphone , I tried the sample that's called Locate Me, but it doesn't recognize the small change in the location. Is there any way for doing this?
Thanks in Advance.
Best regards
John
How small is the change that you expected?
Maybe you should set the accuracy to it's maximum and calculate the displacement on the delegate method.
Configure the location manager to give you it's best.
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[locationManager setDistanceFilter:0.0];
And then on the delegate method:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
// Calculate the distance between the two locations
CGFloat distance = [newLocation distanceFromLocation:oldLocation];
if (distance >= MIN_DISPLACEMENT) {
// Do something
} else {
// Do something
}
}
To get more accurate data from the location manager, set the proper keys for UIRequiredDeviceCapabilities (location-services, gps) on the Info.plist.

CLLocation speed

I am developing GPS application.
Do you know about how to detect speed of mobile device ?
Actually, I need to detect the speed every 2 seconds.
I know didUpdateToLocation method is called when location changed.
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
But I think this method is not suitable for my issue.
So, Do I need to check speed of [CLLocationManager location] in 2 seconds ?
Any suggestion ?
Thanks in advance.
How about the code below which works from the delegate method.
Alternatively, if you did want to poll, then keep your previous location and check the distance changed from the last poll and use the manual method (also shown below) to calculate the speed.
Speed is calculated/provided in m/s so multiply by 3.6 for kmph or 2.23693629 for mph.
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
//simply get the speed provided by the phone from newLocation
double gpsSpeed = newLocation.speed;
// alternative manual method
if(oldLocation != nil)
{
CLLocationDistance distanceChange = [newLocation getDistanceFrom:oldLocation];
NSTimeInterval sinceLastUpdate = [newLocation.timestamp timeIntervalSinceDate:oldLocation.timestamp];
double calculatedSpeed = distanceChange / sinceLastUpdate;
}
}
You can only really use the delegate method you have suggested in your question.
Even if you access the [CLLocationManager location] every 2 seconds, you will only receive the coordinate you last received in the delegate method above.
Why the need to poll every two seconds? The iphone can update it's coordinates in less time on some cases.
HTH