How do I calculate velocity with Core Location? - iphone

i need to get the speed of my device (meters per seconds) and this is my code the speed is always 0 i don't understand.
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
double gpsSpeed2 = newLocation.speed;
labelm.text = [NSString stringWithFormat:#"%f",gpsSpeed2];
}
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
thanks

I never tried it before but probably its better if you set the distanceFilter in the location manager to a number like 1 meter and calculate the time. then calculate the speed.

You need to do the calculation yourself. Something like this:
if (oldLocation != nil)
{
CLLocationDistance distance = [newLocation getDistanceFrom:oldLocation];
NSTimeInterval timeElapsed = [newLocation.timestamp timeIntervalSinceDate:oldLocation.timestamp];
// Use distance and timeElapsed to calculate speed
}
else {
// We don't have and old time, so can't calculate speed
}
oldLocation = [newLocation retain];

Related

How can i achieve the accurate and same lat long even when i revisit the same place

I want this functionality to achieve, that when the user repeats the visit to same place suppose a person moves one meter forward then one meter back. He should get the same lat long value what he gets his previous time. I mean to accuracy for every footstep the user takes with device. How can i achieve this. Currently i am using CLLocationManager but it is giving the difference of 20 to 30 points at last in lat long when i moves at same place again.
Please help. Thanks in advance.
locationManager = [[CLLocationManager alloc] init];
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyBest; // 100 m
locationManager.distanceFilter = 0.1f;
locationManager.delegate = self;
[locationManager startUpdatingLocation];
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSDate *locationTimeStamp = newLocation.timestamp;
NSTimeInterval delta = [locationTimeStamp timeIntervalSinceNow];
NSLog(#"The location timestamp interval was %f seconds.", delta);
_latitude.text = [NSString stringWithFormat:#"%f",newLocation.coordinate.latitude];
_longitude.text = [NSString stringWithFormat:#"%f",newLocation.coordinate.longitude];
_time.text = [NSString stringWithFormat:#"%f",delta];
}

Incorrect distance and route found in my walking/running app

I am working on this walking/running app which calculates distance in meters and records lat-long for further use. Now when I calculate distance I get incorrect distance every time. I have compared it with other running apps and they generally show different distance than my distance.
Here is the code that I am using:
#define kDesiredAccuracy 5.0f
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
self.locationManager.distanceFilter = kDesiredAccuracy;
_routes = [[NSMutableArray alloc] init];
lastKnownLocation = nil;
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
// return if accuracy is less than 0 or is greater than desired accuracy.
if (newLocation.horizontalAccuracy < 0)
{
return;
}
if(newLocation.horizontalAccuracy > kDesiredAccuracy)
{
return;
}
NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
CLLocationSpeed speed = [newLocation speed];
// return if stale data or user is not moving
if (locationAge > 5.0 || speed <= 0) return;
//return if first location is found
if(lastKnownLocation == nil)
{
lastKnownLocation = newLocation;
return;
}
CLLocationDistance distance = [newLocation distanceFromLocation:(self.pramDistance > 0)?lastKnownLocation:oldLocation];
if(distance > 0)
{
// save distance for future use
NSMutableDictionary *dict=[[NSMutableDictionary alloc] init];
[dict setObject:[NSString stringWithFormat:#"%g", newLocation.coordinate.latitude] forKey:#"latitude"];
[dict setObject:[NSString stringWithFormat:#"%g", newLocation.coordinate.longitude] forKey:#"longtitude"];
[dict setObject:[NSString stringWithFormat:#"%f",distance] forKey:#"distance"];
[_routes addObject:dict];
// add distance to total distance.
self.pramDistance += distance;
}
}
Once user finishes walking/running I draw rout of walk/run on map view. For this purpose I simply draw a ploy line over MKMapView using all the recorded locations.
The map view shows zig-zag line for route and distance is always incorrect. Please suggest me where I am doing wrong and what should I amend to make it work proper?
Here is the comparison (left one is other's app and right one is mine):
Try this,
Import CLLocationManagerDelegate,
CLLocation *currentLocation = self.currentLocation;
float distanceMile = [currentLocation distanceFromLocation:[[CLLocation alloc] initWithLatitude:latitude longitude:longitude]]/1609.34;
-(void)postCurrentLocationOfDevice
{
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
self.locationManager.delegate = self;
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
self.currentLocation = [locations objectAtIndex:0];
[self.locationManager stopUpdatingLocation];
}
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
self.currentLocation = newLocation;
[self.locationManager stopUpdatingLocation];
}
Though I didn't get much of the help here, I found some help and idea in this question: Corelocation incorrect distances
What I did to fix the problem is:
I stored recent 5 locations in an array.
Once 5 items are stored in the array, I checked for the nearest location.
After getting nearest location I calculated distance between last best location and stored new location in last best location.
P.S.: My code is messy and naming conventions are not that generic, that's why I am not posting my code here.

How to get Latitude-Longitude Bounds in iPhone?

How to create Latitude-Longitude bounds in iPhone using two NE and SW latitude longitude coordinates and I want to check whether my current latitude longitude is in within my latitude longitude bound.
I created a bound using following latitude longitude coordinates:
double minLng = 7.880571
double maxLng = 8.357336
double minLat = 49.108775
double maxLat = 49.288638
I want to check my other latitude longitude is within this bound or not.
Try like this,
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
if(newLocation.coordinate.latitude>=49.108775 && newLocation.coordinate.latitude<=49.288638 && newLocation.coordinate.longitude>=7.880571 && newLocation.coordinate.longitude<=8.357336 ) {
// It is in the bounds
}
}
If by current you mean the device's current location, you need to look into the CLLocationManager class and its delegate methods, namely the location property which contains the information about current latitude and longitude. The rest is pretty straightforward.

How to get device current latitude and longitude for IPhone device

I'm developing an app were I would like to get device current latitude and longitude for IPhone. Is it possible to obtain this information without using GPS.
Thanks
you can use CoreLocation framework
The Core Location framework has one important class CLLocationManager.
The CLLocationManager class handles sending out updates to a delegate anytime the location is changed. it uses the delegate CLLocationManagerDelegate protocol.
you can use it like
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController
<CLLocationManagerDelegate>
{
CLLocationManager *locationManager;
}
set up locationManager like this in viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
[locationManager startUpdatingLocation];
}
implement the below delegate mehod for getting changed location
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
NSInteger degrees = newLocation.coordinate.latitude;
double decimal = fabs(newLocation.coordinate.latitude - degrees);
int minutes = decimal * 60;
double seconds = decimal * 3600 - minutes * 60;
NSString *lattitudeStr = [NSString stringWithFormat:#"%d° %d' %1.4f\"",
degrees, minutes, seconds];
lattitudeLabel.text = lattitudeStr;
degrees = newLocation.coordinate.longitude;
decimal = fabs(newLocation.coordinate.longitude - degrees);
minutes = decimal * 60;
seconds = decimal * 3600 - minutes * 60;
NSString *longitudeStr = [NSString stringWithFormat:#"%d° %d' %1.4f\"",
degrees, minutes, seconds];
longitudeLabel.text = longitudeStr;
}
You can use CLLocationManager to get current lat and long.
create an iVar of CLLocationManager and use it.
Here is the code:
- (void)viewDidLoad
{
[super viewDidLoad];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSLog(#"OldLocation %f %f", oldLocation.coordinate.latitude, oldLocation.coordinate.longitude);
NSLog(#"NewLocation %f %f", newLocation.coordinate.latitude, newLocation.coordinate.longitude);
currentLat = [NSString stringWithFormat:#"%f",newLocation.coordinate.latitude];
currentLong = [NSString stringWithFormat:#"%f",newLocation.coordinate.longitude];
}
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
CLLocation* currentLocation = [locationManager location];
NSString *loc = [NSString stringWithFormat:#"%f,%f",currentLocation.coordinate.latitude, currentLocation.coordinate.longitude];
NSLog(#"location:%#", loc);
You can get current location without GPS by using CLLocationManager if the device has WiFi or cellular data service. The location will not be as accurate as you would get from GPS but you get a result faster than from GPS.
You can request a non-GPS location from CLLocationManager by setting the desiredAccuracy property to kCLLocationAccuracyKilometer.
Using Swift
import CoreLocation
Get current location
let locationManager = CLLocationManager()
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.desiredAccuracy = kCLLocationAccuracyBest
//get the most recently retrieved user location
if let currentLocation = locationManager.location {
let longitude = currentLocation.coordinate.longitude
let latitude = currentLocation.coordinate.latitude
//work with the received data
}
Note that locationManager.location is an optional and hence should be safely unwrapped.

CLLocationManager issue

I want to get a single location and then stop getting notification from CLLocationManager.
I do it with this:
-(id)initWithDelegate:(id <GPSLocationDelegate>)aDelegate{
self = [super init];
if(self != nil) {
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
delegate = aDelegate;
}
return self;
}
-(void)startUpdating{
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
[locationManager stopUpdatingLocation];
[delegate locationUpdate:newLocation];
}
The issue is that even when I do [locationManager stopUpdatingLocation];
in - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:
I still get notification, any idea why it happen?
Maybe try my solution. I'm build two functionals for handling LocationManger Obj.
The first function is startUpdates for handle start update location. Code look like this :
- (void)startUpdate
{
if ([self locationManager])
{
[[self locationManager] stopUpdatingLocation];
}
else
{
self.locationManager = [[CLLocationManager alloc] init];
[[self locationManager] setDelegate:self];
[[self locationManager] setDesiredAccuracy:kCLLocationAccuracyBestForNavigation];
[[self locationManager] setDistanceFilter:10.0];
}
[[self locationManager] startUpdatingLocation];
}
The second function is stopUpdate for handle CLLocationDelegate to stop update location. Code look like this :
- (void)stopUpdate
{
if ([self locationManager])
{
[[self locationManager] stopUpdatingLocation];
}
}
So, for CLLocationManagerDelegate should be look like this :
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
NSDate* eventDate = newLocation.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
self.attempts++;
if(firstPosition == NO)
{
if((howRecent < -2.0 || newLocation.horizontalAccuracy > 50.0) && ([self attempts] < 5))
{
// force an update, value is not good enough for starting Point
[self startUpdates];
return;
}
else
{
firstPosition = YES;
isReadyForReload = YES;
tempNewLocation = newLocation;
NSLog(#"## Latitude : %f", tempNewLocation.coordinate.latitude);
NSLog(#"## Longitude : %f", tempNewLocation.coordinate.longitude);
[self stopUpdate];
}
}
}
Inside this function above, i'm correct only the best location for update location. I hope my answer will help, Cheers.
I think that the reason of your problem is in distance filter. As docs say:
Use the value kCLDistanceFilterNone to be notified of all movements. The default value of this property is kCLDistanceFilterNone.
So you just have what you've set - continuous updates.