Detect if user enters or leaves a region - geocoding - iphone

I'm starting with geocoding. And I have a lot of doubts.
I'm able to do forward and reverse geocoding (I guess, its not perfect).
And now, I'm trying to detect if user (device) enters or leaves a region. For that, I picked up apple's sample code "Regions". The sample uses regionMonitoring. I already try it in a device, but its not working well. I set a region with 25 meters radius, and when I left the region (walking) doesn't happen anything.
My question is: there is another and better way of doing this, detect if user enters or leaves a region, than regionMonitoring?
Can someone help me here??
Thanks a lot.

you could keep the user-location tracking running in the background (here is a good tutorial) but keep in mind this can be heavier on battery use than regionMonitoring.

I found a solution to calculate the distance between two CLLocationCoordinate2D it is easier than I though:
- (CLLocationDistance) DistanceBetweenCoordinate:(CLLocationCoordinate2D)originCoordinate andCoordinate:(CLLocationCoordinate2D)destinationCoordinate {
CLLocation *originLocation = [[CLLocation alloc] initWithLatitude:originCoordinate.latitude longitude:originCoordinate.longitude];
CLLocation *destinationLocation = [[CLLocation alloc] initWithLatitude:destinationCoordinate.latitude longitude:destinationCoordinate.longitude];
CLLocationDistance distance = [originLocation distanceFromLocation:destinationLocation];
[originLocation release];
[destinationLocation release];
return distance;
}

Related

iOS GPS data issue

I'm trying to retrieve data from GPS, but it's not so accurate. Here is a screenshot :
It worked great with GPS emulation on the simulator. I want to know how to improve this.
Here is the code I tried :
UserLocation = [[CLLocationManager alloc] init];
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 60000
[UserLocation setPausesLocationUpdatesAutomatically:NO];
[UserLocation setActivityType:CLActivityTypeFitness];
#endif
UserLocation.delegate = self;
[UserLocation setDistanceFilter:kCLDistanceFilterNone];
[UserLocation setDesiredAccuracy:kCLLocationAccuracyBestForNavigation];
[UserLocation startUpdatingLocation];
and then I retrieve data every second and check if it's different than the previous one.
Ric Perrott is right about the GPS data never being 100% accurate all the time. I suggest you set your accuracy to kCLLocationAccuracyBest which according to Apple is the right setting for what you are trying to do.
To try and filter out some of the 'jumping' you are getting, I suggest taking an average reading. For example, take X number of GPS readings (5 or 10 or...) and then average out. This will eliminate the occasional incorrect reading your device might get.
I wrote a fitness walking app a while back and had similar issues. Averaging did not completely resolve the issue but it did smooth it out a lot.

in iphone is there any alternate way of CLLocation to find location

I am not getting accuracy by using CLLocation
CLLocation *locA = [[CLLocation alloc] initWithLatitude:CurrentUserLocationNow.latitude longitude:CurrentUserLocationNow.longitude];
locB = [[CLLocation alloc] initWithLatitude:newLocation.coordinate.latitude longitude:newLocation.coordinate.longitude];
distance = [locA distanceFromLocation:locB];
int feet = distance*3.28084;
if(feet >= 40)
{
[avaudioplayer stop];
}
but I am not getting perfect accuracy
CLLocation class method distanceFromLocation is the easiest way to find the distance between two points on map. Talking about your accuracy that you can set with the help of your CLLocationManager desiredAccuracy property to kCLLocationAccuracyBest.
But if you using the google direction api in your project you can do from by parsing the json.(Hectic task)
There is no way in iOS to garner location without using CLLocation. There may be 3rd party libraries that allow you to get location, but they would all just be wrappers for CLLocation. Apple does not allow access to the GPS hardware any other way. So if you need location, you are basically stuck with CLLocation.

How to calculate distance to locations

I've developed an iPhone application to parse data from an XML file. This data contains a set of longitudes and latitudes for different places.
How do I detect nearest of them according to my current location on the map and how do I set set a range to show places in this range?
CLLocation *myLocation = [[CLLocation alloc] initWithLatitude:myLatitude longitude:myLongitude];
CLLocation *myXmlLocation = [[CLLocation alloc] initWithLatitude:xmlLatitude longitude:xmlLongitude];
CLLocationDistance distance = [myLocation distanceFromLocation: myXmlLocation];
This is in meters, so you must do any converting from there. They are also linear, so these aren't driving direction lengths by any means. Good luck.
some trig, but really not too difficult.
this page has an example script, not in your language, but it contains explainations and the equations you need.
http://www.movable-type.co.uk/scripts/latlong.html
and also, please don't write run-on sentences, it took me a while to read your question.
#Vinnie said is absolutely right but these values is air distance.
Also this method is deprecated in iOS 3.2
- (CLLocationDistance)getDistanceFrom:(const CLLocation *)location Parameters
You can't find the distance based on roads with the Apple SDK. Try to use google APIs for finding distance between two points on earth on roads.

altitude property in location manager returning zero on Iphone when reading GPS Location

I am writing an app, that uses GPS. I can get successfully the latitude, longitude and other properties, but altitude seems to always return "0.00" i have the following code to test it in the most simplest way and still get 0.00. Code below:
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
// Stop updating location if renewed in less than 60 seconds
if ([self timeBetweenLocationandNow] < 60)
{
[locationManager stopUpdatingLocation];
NSLog(#"GPS Stopped");
}
NSLog(#"Altitude:%.2f m",newLocation.altitude);
}
Any ideas on what could be wrong ? also on an init method i have the following:
- (id)init
{
self = [super init];
if (self != nil)
{
// Create location manager Object
locationManager = [[CLLocationManager alloc] init];
// Set the delegate to this object
[locationManager setDelegate:self];
// Set distance filter and accuracy
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[locationManager startUpdatingLocation];
}
return self;
}
Will appreciate any insight. thank you
I'm no expert but this is how I understand it: The iPhone is quite different from other gps systems because of the multiple ways in which it goes about figuring out your location. The iPhone figures out the location in three ways: local wifi signals, cell towers, and/or gps chip. Using a gps satellite to find a position can be extremely slow and reception can be pretty much non-existent in populated cities. Therefore, iPhone generally looks to the first 2 options first.
Wifi positioning data comes from people driving around on the streets logging hotspots which obviously isn't going to give much of a hint of an altitude. I'm not sure if cell tower triangulation gives any altitude data but my guess is no. These two methods are extremely fast compared to gps but will yield an altitude of 0 as you have seen. If you are in a place where there is a decent gps satellite reception the iPhone may give you the altitude, but even then, it might not even find it till it has received the satellite signal a few times and called the location delegate multiple times, and even then altitude data for gps can be notoriously inaccurate.
Long story short, it's a bad idea to count on accurate altitude data from the iPhone.
i found the problem. As Deepmist suggested the delegate has to be called several times. I was stopping the GPS after the first fix. Which was giving me accurate data for coordinates but altitude remained # 0.00 until like 3 or so delegate calls. Now i get the altitude data, what is a good way to check for this ? so i can stop the location manager after i get the data ? i can check that altitude is a non-zero value, but was wondering if there are other properties that should be used instead to make sure that you have the highest accuracy possible making all of your location data valid (i.e non-zero on some properties). thank you

mapkit annotation error correction on iphone

i have 4 annotation with same lat/long as they are pointing some location in 1 building , since they share common lat/long so i can show only one of them on map?? so is there any way to use some error correction so that i can show them Lil side by side??
here is my annotation code
MKCoordinateRegion SecondRegiona;
SecondRegiona.center.latitude = 111.31888;
SecondRegiona.center.longitude = 203.861;
MyAnnotation *aSecondAnnotationa = [[[MyAnnotation alloc] init]autorelease];
aSecondAnnotationa.title = [listItems objectAtIndex:15];//#"3rd Annotation";
aSecondAnnotationa.subtitle = [listItems objectAtIndex:16];
aSecondAnnotationa.coordinate = SecondRegiona.center;
Why would you expect the platform to position something someplace different than where you told it to place it? That certainly sounds undesirable and not something that I would call "Error Correction"
You need to detect that state and do something reasonable like coalesce them into a single custom annotation or adjust the lat lngs to position them nearby according to your needs.
I would detect whether points are really close together (maybe use the distance formula to see how close points are?) and use - (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(UIView *)view to get CLLocationCoordinate2D of a point close to the original pin (say, 3 pixels to the right, 3 pixels down). You would use this CLLocationCoordinate2D to display the new, "adjacent" point.
As for what "coalesce" means, Nick means to merge points together -- take points that are really close to each other and display only one to represent the close points. I guess this isn't what you're looking for though.
Hope this helps!