Compare GPS points to the current location - iphone

I am using the instance method distanceFromLocation in order to compare my new location with const defined locations
I am giving CLLocation *bonuslocation an instant value which is one of the gps points i am interested in and then i compare it to the new location
if the distance is less than 20m from the point an audio file is played.
While this is working perfectly for one location it does not work at all
if i add locally into the updatelocationmanager function more than one..
The code:
CLLocation *bonuslocation = [.....]
CLLocationDistance distancea = [bonuslocation distanceFromLocation newlocation]
if (distancea <= 20)
{
//play an audio
}
Can i have some advice on how to do it for 10 gps points????
Today is my Birthday can you see that as a birthday present??
Thank you..

Why not just put it in a loop? Or just run the comparison on 10 locations? What exactly is it that isn't working?
EDIT:
You never mentioned where you're getting your other locations, so let's assume you make them somehow and store them in an array...
NSArray *locationArray;
I gathered from your comment that you have different sounds for each location? A simple way would be to store the sounds in a second array...
NSArray *soundsArray;
Then you can do the following in your locationManager:didUpdateToLocation:fromLocation:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
for(int i=0; i<[locationArray count]; i++){
CLLocation *location = (CLLocation *)[locationArray objectAtIndex:i];
if([newLocation distanceFromLocation:location] < 20.0){
//perform some action e.g.
//play sound at [soundArray objectAtIndex:i]
}
}
}
Although I don't recommend simply playing a sound, as this simple logic will cause the sound to be played once for every location within the threshold all at the same time.

Related

Can I get colocation data in underground area (like as subway, parking lot, etc..)?

I set up cllocation manage by following code. It work in the open area. However, my phone can't received any datas (all datas was 0) after I went into subway or underground area.
What should I do if I want to make app work in subway as well? Is it necessary to integrate startMonitoringSignificantLocationChanges/startMonitoringForRegion method with standard location update method together? If so, how do I make it?
In init method
locationManager=[[CLLocationManager alloc]init];
locationManager.desiredAccuracy=kCLLocationAccuracyBest;
locationManager.distanceFilter=kCLDistanceFilterNone;
locationManager.delegate=self;
[locationManager startUpdatingLocation];
In cllocation delegate method
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
NSLog(#"%#",newLocation);
NSDate*eventDate=newLocation.timestamp;
NSTimeInterval howRecent=abs([eventDate timeIntervalSinceNow]);
if ((newLocation.coordinate.latitude != oldLocation.coordinate.latitude)&&(newLocation.coordinate.longitude != oldLocation.coordinate.longitude)) {
locationChanged=YES;
}else{
locationChanged=NO;
}
if ((howRecent <5.0)&&
((newLocation.horizontalAccuracy<(oldLocation.horizontalAccuracy -10.0))||
(newLocation.horizontalAccuracy<50.0)||
((newLocation.horizontalAccuracy<=120)&& locationChanged))) {
self.myLocation=[newLocation copy];
// NSLog(#"mylocation==%#",[self.myLocation description]);
}
//location info draw from plist
CLLocation *targetLocation = [[CLLocation alloc] initWithLatitude:Target_LAT longitude:Target_LONG];
double distance = [self.myLocation distanceFromLocation:targetLocation]/1000;
NSString*distString=[NSString stringWithFormat:#"%0.2f km",distance];
[delegate getLocationUpdate:self.myLocation distanceUpdate:distString];
//In this testing app, I use delegate to take cllocation data. Then those datas display in view controller.
}
You can get location data for a mobile device In a Couple of ways. Device based (GPS, AGPS, WIFI etc when you are in GPS line of sight ) or CELLID based (off device - mobile number based whether you are in GPS line of sight or not as this is cellID based)..as you know your app can also get location information underground(out of line of sight) if it is using cellID Keep in mind that in underground situations if there is no wifi then you are out of luck.
I would love to say that you should use geoloqal.com (me) to locate mobile devices via cellID or GPS - however, unfortunately, in the subway we still will not be able to help you.

How can I calculate my speed with an iPhone? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to calculate speed of our car using iphone
How can I calculate my speed with an iPhone? For example, I might want to measure the speed of my car when driving. How can I implement this?
Try something like this:
- (id) init
{
self = [super init];
if (self != nil) {
self.manager = [[CLLocationManager alloc] init];
self.manager.delegate = self;
[self.manager startUpdatingLocation];
}
return self;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(#"Speed = %f", newLocation.speed);
}
1>You can use GPS
Use the location services to get the latitude and longitude at a particular point of time and the you can get the same after a certain period of time say t.You can get the distance traveled from Latitude and longitude and divide it by the taken to get the speed
See the Apple GPS Doc
2>You can use Accelerometer
if you start from a halt, you should be able to calculate the distance you travel
based off the acceleration over time of the device.
See the Apple Accelerometer Doc

Iphone core location

I have an application where I have to check that whether user's mobile location has changed or for 30 consecutive seconds or not?If it has not changed in 30 seconds then user will be navigated to the other view and if it has changed then user will have a message that your mobile location's coordinates have changed in these 30 seconds.
I am using these code but it does nothing ...
-(void)time
{
for(int i = 0; i<= timeremaining ;i++)
{
if (new1 == old)
{
if(timeremaining == 1)
{
Timer90 *timerview = [[Timer90 alloc] initWithNibName:#"Timer90" bundle:nil];
[self.navigationController pushViewController:timerview animated:YES];
}
}
else
{
[NSTimer cancelPreviousPerformRequestsWithTarget:self selector:#selector(time) object:nil];
}
timeleft.text = [NSString stringWithFormat:#"%d",timeremaining];
}
timeremaining--;
}
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
new1 = newLocation;
old=oldLocation;
latitude = [[NSString alloc]initWithFormat:#"%g",newLocation.coordinate.latitude];
longitude = [[NSString alloc]initWithFormat:#"%g",newLocation.coordinate.longitude];
accuracy = [[NSString alloc] initWithFormat:#"%g",newLocation.horizontalAccuracy];
if(oldLocation == NULL)
{
oldLocation == newLocation;
}
}
here timer90 is name of my view.Please help me out friends...Any help will be appreciated.
You could possibly do something like this (after adding counter and initialLocation to your properties) it will compare location after 30 seconds following the first update, but I think it would be helpful if you added an age check to the entire method so that you aren't comparing to some very old data point.
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
if(self.counter==0){
self.intialLocation=newLocation;
self.counter=1;
}
NSTimeInterval age = [initialLocation.timestamp timeIntervalSinceNow];
if(age>30)
{
self.counter=0;
if(newLocation.latitude==initialLocation.latitude&&newLocation.longitude==initialLocation.longitude){
Timer90 *timerview = [[Timer90 alloc] initWithNibName:#"Timer90" bundle:nil];
[self.navigationController pushViewController:timerview animated:YES];
}
}
}
Two things that I notice. May be the whole issue, or only part of it.
Number 1.
if(oldLocation == NULL)
{
oldLocation == newLocation;
}
oldLocation == newLocation will not set the two equal to each other (you need one equals sign) and your are assigning the parameter pointers to the same object, not your member pointers. For example, if oldLocation points to Object A and newLocation points to Object B at the start of didUpdateToLocation:fromLocation:, then:
new1 is set to point at Object B
old is set to point at Object A
if(Object A is NULL)
oldLocation and newLocation both point at Object B
The values of new1 and old are not set to the same object in the NULL case. Which is what you are checking for in time
Number 2.
In time you are checking if new1 and old are pointing at the same object. No necessarily if the two objects represent the same location. In the case where oldLocation is null and they are set together, this check may pass...however, it is more likely that CoreLocation will call the update method a few times while accuracy gets better, and you will have two separate objects that represent the same lat/long location.
You should compare these two locations for proximity using the CLLocation getDistanceFromLocation: method.
Hope that Helps!

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