Here is my location manager delegate code.
It is not giving speed when we move using car so at least speed value should change.
It always gives constant value -1.00.
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *crnLoc = [locations lastObject];
self.speedometerCurrentValue=crnLoc.speed;
self.lblSpeed.text=[NSString stringWithFormat:#"%f",crnLoc.speed];
}
Please check this screenshot from apple explanations. Your speed is invalid.
Related
I am new in location services. I have used startMonitoringSignificantLocationChanges and (void)locationManager:(CLLocationManager *)manager didUpdateToLocation: (CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation method but it is not getting called as I change location value. I want to fetch location value whenever user change its location.How should i achieve this? Please help me to resolve. Thanks in advance.
You need to implement "didUpdateLocations" delegate method . Here is sample
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(#"locations : %#",locations.description);
CLLocation *currentLocation = [locations lastObject];
NSLog(#"current location : %f %f",currentLocation.coordinate.latitude,currentLocation.coordinate.longitude);
}
In iOS 8 you need to do two extra things to get location working:
1. add one or both of the following keys to your Info.plist file:
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
Next you need to request authorization for the corresponding location method, WhenInUse or Background. Use one of these calls:
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
For details refer following link. http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/
I need to calculate ALL gps parameters in my program so I use this piece of code:
(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLLocation* loc = [locations lastObject];
which collects all the gps measurements (altitude, speed, etc) in loc object and I have the lat/long info (loc.coordinate.lattitude and loc.coordinate.longitude) but these are the NEW measured coordinates.
As I also want to calculate distance between measurements how can I retrieve both the "new" coordinates and the "old" coordinates from the didUpdateLocations method?
If I add another locationManager call with the didUpdateToLocation method in the program (which will give old and new coordinates):
(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
the initial locationManager method (didUpdateLocations) is not called at all, so I cannot calculate all gps data plus distance...
After succeeding with the property copy I have this working code but I cannot make sense of:
(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
_locManagerIteration++;
NSLog(#"Location manager iteration = %ld", _locManagerIteration);
CLLocation* loc = [locations lastObject]; // locations is guaranteed to have at least one object
if (_locManagerIteration == 1) { //INITIALIZE THE FIRST PAST COORDINATE OBJECT
self.pastCoordinate = [locations lastObject];
} else {
CLLocationDistance _pointDistance = [self.pastCoordinate distanceFromLocation:loc];
NSLog(#"POINT TO POINT DISTANCE = %f", _pointDistance);
self.pastCoordinate = [locations lastObject];
}
NSLog(#"POINT TO POINT DISTANCE = %f", _pointDistance);
_totalDistance = _totalDistance + _pointDistance; //COMPUTE TOTAL DISTANCE
_totalDistance = _totalDistance / 1000; //TRANSLATE TOTAL DISTANCE IN KILOMETERS
In the above section, CLLocationDistance call correctly places the distance in meters in my global variable _pointDistance. I print the _pointDistance variable and see the number (NSLog...). HOWEVER, when I again print the same global variable outside the if-then statement the value is always zero...
Within the else bracket the _pointDistance variable has a black color in XCODE (and prints the value) and outside the else bracket is showed with green color and the value is zeroed.... Can't make any sense out of it...
I'm using the delegate method:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
To get the current and old location, I used:
CLLocation *newLocation = [locations lastObject];
self.currentUserLocation = newLocation;
if(self.oldLocation == nil)
{
self.oldLocation = newLocation;
return;
}
EDIT 1: I can get the old location now.
But I always have a negative speed when I use [newLocation speed]; = -1
The device used is an iPhone 4s. Do you have an idea ?
Also, for the locationManager, I used kCLLocationAccuracyBestForNavigation and kCLDistanceFilterNone. I can see on the map my current location moving.
EDIT 2:
I finally achieve the issue with the speed using this method:
- (CLLocationSpeed)speedTravelledFromLocation:(CLLocation*)fromLocation;
{
NSTimeInterval tInterval = [self.timestamp timeIntervalSinceDate:fromLocation.timestamp];
double distance = [self distanceFromLocation:fromLocation];
double speed = (distance / tInterval);
return speed;
}
This method returns the speed calculated from the distance and time deltas between self and fromLocation.
I found this method in this repository: https://github.com/100grams/CoreLocationUtils
Hope it will help someone ;)
EDIT 3
Got it! It was because I'm testing on simulator! I tested on a device and the speed using [newLocation speed] is correct!
Thank you for your help.
Regards,
Lapinou.
Negative speed usually means you don't have a GPS signal.
Why are you expecting the location callback to have 2 or more locations?
This method:
(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
Usually delivers you just one location, except if for some reason multiple locations arrived before that method was called, but you usually will get just one location.
The problem is that you are assuming that that method gives you your previous location along with the new one, and it's not like that.
I use this code to get the longitude and latitude.
(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
NSLog(#"%f",newLocation.coordinate.latitude);
self.location = newLocation;
}
But the longitude and latitude which i got has the excursion with the actual geographical position. How to solve this problem?
You should be testing the accuracy of the CLLocation object that is returned, and making sure it meets your location accuracy criteria.
if (newLocation.horizontalAccuracy > 1000) {
// Throw away this location and wait for another one as this is over 1km away
}
Also, the locationManager:didUpdateToLocation:fromLocation: method has been deprecated in iOS6 so you should use locationManager:didUpdateLocations: if you're targetting iOS6+.
I'm in the process of writing an application that shows the user's distance from a fixed point as the user walks around (i.e. the label showing the distance from the user to the point is updated every time the user moves). I use a CLLocationManager with the code shown below:
- (void)viewDidLoad
{
locationManager=[[CLLocationManager alloc]init];
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
CLLocationDistance meters = [newLocation distanceFromLocation:fixedPoint];
self.distanceLabel.text = [[NSString alloc] initWithFormat:#"Distance: %.1f feet", meters*3.2808399];
}
The label that is supposed to show the distance from the user to the point isn't updated constantly and when it is updated, it doesn't usually show the correct distance from the user to the fixed point. I was wondering if there is a better way for me to try and do this, or do the fundamental limitations of the core location framework make this impossible. Any help will be greatly appreciated.
Are you filtering out old (cached) positions? You should also filter based on accuracy, you probably don't want low accuracy locations.
You won't get continous or periodic update, the callback only occurs when the location has changed.
Assuming the device has GPS and can see enough GPS satellites to get a good position, this works fine.
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
NSTimeInterval age = -[newLocation.timestamp timeIntervalSinceNow];
if (age > 120) return; // ignore old (cached) updates
if (newLocation.horizontalAccuracy < 0) return; // ignore invalid udpates
...
}