Minimum accuracy of startMonitoringForRegion in meters - iphone

I've encountered problem with startMonitoringForRegion method in iOS 5. Documentation says that method is taking parameter "accuracy":
- (void)startMonitoringForRegion:(CLRegion *)region desiredAccuracy:(CLLocationAccuracy)accuracy
I'm currently developing an app that should notify user when he's in 25 meters radius from monitored point. App uses GPS with kCLLocationAccuracyBestForNavigation setting. I'm creating (CLRegion *)region like this:
CLRegion *pointRegion = [[CLRegion alloc] initCircularRegionWithCenter:pointLocation radius:25.0 identifier:identifier];
and setting accuracy parameter in startMonitoringForRegion for kCLLocationAccuracyBestForNavigation.
Region monitoring works well in my app, however didEnterRegion method fires when user is around 100 meters from monitored region, not 25 meters.
Is there minimum value of radius in startMonitoringForRegion that is not described in Apple's documentation or am I doing something wrong? Is it possible to set region monitoring to relatively small values (like 5-25 meters)?

You cannot set iOS Region Monitoring to lower values unless turning on significantLocationChanges. It's only working in US in bigger cities because region monitoring is based on cellular network.

Related

Geo Fencing functionality iOS 11

I am working on Geo fence with Google map. My question is about the minimum radius for CLCircularRegion. As I want to work with the region for 30 meters. But the functionality works for the 100 meters. I have searched a lot and found that Apple needs minimum radius 100 to create a region, no matter I have set 30 meters or 50 meters.
Here is the link -
Geofencing iOS 6
Moreover, didEnterRegion call at 100 meters and didExitRegion works very oddly and took much time.
I have also read, that it depends upon tower cells etc according to that these methods call.
Here is the link -
What is the maximum and minimum radius that can be set for regions in iOS geofencing.
I want to know if I have set the region for 50 meters. Why it is not working as per required region radius. In fact, I observe that it is working for the radius 100 meters.
Here is the code:
func createRegion(lat : CLLocationDegrees,lng : CLLocationDegrees) -> CLCircularRegion?
{
let latitude = lat
let longitude = lng
var radius = CLLocationDistance(50)
if radius > locationManager.maximumRegionMonitoringDistance
{
radius = locationManager.maximumRegionMonitoringDistance
}
let region = CLCircularRegion(center: CLLocationCoordinate2DMake(latitude, longitude), radius: radius, identifier: "TEST")
region.notifyOnEntry = true
region.notifyOnExit = true
return region
}
Or also can anyone refer a good app that has Geo fence functionality. So that I can compare my app's accuracy with it.
Question: I have selected 50 meters radius and 'upon exit' notification should come. But I am getting a notification on/around 250 meters and some time more than this. Please help me out
Thanks!
Take a look at Apple`s developer documentation:
Article Apple
Official Documentation
When testing your region monitoring code in iOS Simulator or on a device, realize that region events may not happen immediately after a region boundary is crossed. To prevent spurious notifications, iOS doesn’t deliver region notifications until certain threshold conditions are met. Specifically, the user’s location must cross the region boundary, move away from the boundary by a minimum distance, and remain at that minimum distance for at least 20 seconds before the notifications are reported.
The specific threshold distances are determined by the hardware and the location technologies that are currently available. For example, if Wi-Fi is disabled, region monitoring is significantly less accurate. However, for testing purposes, you can assume that the minimum distance is approximately 200 meters.
And remind that if the Wi-Fi is disabled, then it will be less accurate.
I think you can reverse engineer the minimum radius on your device by looking at the device logs in Console. For example, if I set a radius of less than 100m on my iPhone 8 with iOS 14.7, I get the following log statement:
Fence:Start Started monitoring fence myapp/<private> (<<private>,<private>>, radius 100.000, active tech <private>)...
So, 100m seems to be the minimum in my case.

Geo Fencing Identifier

How to specify the entire country as a region in region identifier.Wether it will accept the
identifier as :#"Uk"
here the code to reo identifier.How can i specify England or UK.Please help me to sort out
CLLocationCoordinate2D location2D = mapView.region.center;
CLRegion *regionForMonitoring = [[CLRegion alloc] initCircularRegionWithCenter:location2D radius:1 identifier:#"RegionIdentifier"];
[[Utils getLocationManager] startMonitoringForRegion:regionForMonitoring];
CLRegions are totally unsuitable for this purpose.
First of all, the radius specified is the distance in meters that the region covers - so in your case you are asking the system to monitor a region at a specific lat/long with a radius of 1 meter!
Also, system regions have a maximum number of regions that can be monitored (around 10 or so), and a maximum radius that can be used of around 400 meters after which the region will not work.
You really need to read the "Monitoring Shape Based Regions" section of this Apple document:
http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html
There are two other possible approaches to what you are trying to do:
1) Use Significant Location Updates, and test on each update if you are in an area with a shape you specify.
2) Use CoreTelephony to look up the cell carrier your device is on and see if the carrier number matches one in the country of interest. Of course, this will not work on some iPads or other iOS devices with no cell connection.
Neither of those approaches will be exact around the edges, but will also not consume nearly as much battery life as using the GPS.

CLLocationManager error margin

Im developing a location based application for a football stadium.
I must pre define several locations on the map for the user and guide the user to that location.
Do anyone know what is the error margin in CLLocationManager current use location
It depends on the Accuracy Constant you set. From the docs:
kCLLocationAccuracyBestForNavigation
Use the highest possible accuracy and combine it with additional
sensor data. This level of accuracy is intended for use in navigation
applications that require precise position information at all times
and are intended to be used only while the device is plugged in.
Available in OS X v10.7 and later. Declared in CLLocation.h.
kCLLocationAccuracyBest
Use the highest-level of accuracy. Available in OS X v10.6 and later.
Declared in CLLocation.h.
kCLLocationAccuracyNearestTenMeters
Accurate to within ten meters of the desired target. Available in OS X
v10.6 and later. Declared in CLLocation.h.
kCLLocationAccuracyHundredMeters
Accurate to within one hundred meters. Available in OS X v10.6 and
later. Declared in CLLocation.h.
kCLLocationAccuracyKilometer
Accurate to the nearest kilometer. Available in OS X v10.6 and later.
Declared in CLLocation.h.
kCLLocationAccuracyThreeKilometers
Accurate to the nearest three kilometers. Available in OS X v10.6 and
later. Declared in CLLocation.h.
UPDATE:
Here is a bit more information about its accuracity
if you use kCLLOcationAccuracyBest and you have a good view to open sky, you will get 3-6m positional accuracy in 95% of measures. if you have bad view, up to 30m can happen.
This is the best what you can achieve. The iphone has one of the best GPS modules (if not the best at all in consumer devices). But best is to try it out. I am not sure if the GPS receives good signals through the partial roof of the stadium. the bigger the stadium the better the view to sky which gives better accuracy.
Use a GPS App which supports waypoints, and set some waypoints.
Do the same 1 hour later, and compare the distance error. (or try to view in google maps)

Location.HorizontalAccuracy too bad when getting location from background

I'm writing an app that monitors the user's location. I have a CLLocationManager object that uses startMonitoringSignificantLocationChanges, so I can get locations updates from the background when the app is not running. I have setup my application didFinishLaunchingWithOptions so if I get a location key I fire up my manager to get the user's location. Everything works fine but the problem is that every time I get a location from the background, the Horizontal Accuracy of this location is very bad. In most of the cases it is 1414 m.
Does anybody know why the horizontal accuracy is so bad when the location comes from the background?
Is there anything I can do to get locations with better accuracy in the background?
When the app is running all the locations I get are very accurate, this only happens when the location comes from the background. Does that have anything to do with the number of cell towers I have in my city? I was thinking maybe the device doesn't use gps of wifi nodes to get locations in the background.
Anyways, Any help here is appreciated.
Please share your thoughts.
Thanks!
The accuracy of locations returned by CLLocationManager is determined by the desiredAccuracy, which is by default, kCLLocationAccuracyBest, and by the available accuracy of the device. For instance, you may get less accurate locations if the device's battery is low, or you may get more accurate locations if they are still cached from another app.
However, getting you incredibly accurate coordinates drains a significant amount of power from the battery and will drain the device. Applications in the background are probably limited to a much lower resolution of accuracy to improve battery performance.
Accurate locations require a lot of power to use the GPS radio while less accurate locations can rely on nearby wifi hotspots and the cell towers within range of the phone.
As your application resumes from the background, the system will try to improve the accuracy of the results you get. It's a tricky concept, but take a look at the Maps application on your phone. At first, the circle representing your location is very large; as the system gets a more accurate sense of your location, the circle becomes smaller. This visualization represents the phone using more power to get a more precise location.
You'll see a similar phenomenon with CLLocationManager as your app resumes from the background: you'll get an inaccurate location and receive subsequent, more accurate updates.
It's a compromise between convenience and battery life that Apple had to make when designing their APIs. The first update to a user's location probably won't be that accurate unless they were just using the Maps application and the location is cached.
The best advice I can give you is to listen for subsequent updates from the location manager and update your UI accordingly. Good luck!
As the name states: The startMonitoringSignificantLocationChanges notification is only there to let you know that a the the user's location significantly different from the last one checked. It's your job when you receive that Notification to update your location according to the desired accuracy you want.The notification won't do that for you. It is only going to let you know the location has change so you can deal with the situation accordingly. If you don't know how to get a better accuracy you may want to check out the Apple sample code for LocateMe.Here's a snippet that stores the accuracy(bestEffortAtLocation) then tests the accuracy each time the delegate is called until a better result comes in or a time-out occurs.:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
// store all of the measurements, just so we can see what kind of data we might receive
[locationMeasurements addObject:newLocation];
// test the age of the location measurement to determine if the measurement is cached
// in most cases you will not want to rely on cached measurements
NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
if (locationAge > 5.0) return;
// test that the horizontal accuracy does not indicate an invalid measurement
if (newLocation.horizontalAccuracy < 0) return;
// test the measurement to see if it is more accurate than the previous measurement
if (bestEffortAtLocation == nil || bestEffortAtLocation.horizontalAccuracy > newLocation.horizontalAccuracy) {
// store the location as the "best effort"
self.bestEffortAtLocation = newLocation;
// test the measurement to see if it meets the desired accuracy
//
// IMPORTANT!!! kCLLocationAccuracyBest should not be used for comparison with location coordinate or altitidue
// accuracy because it is a negative value. Instead, compare against some predetermined "real" measure of
// acceptable accuracy, or depend on the timeout to stop updating. This sample depends on the timeout.
//
if (newLocation.horizontalAccuracy <= locationManager.desiredAccuracy) {
// we have a measurement that meets our requirements, so we can stop updating the location
//
// IMPORTANT!!! Minimize power usage by stopping the location manager as soon as possible.
//
[self stopUpdatingLocation:NSLocalizedString(#"Acquired Location", #"Acquired Location")];
// we can also cancel our previous performSelector:withObject:afterDelay: - it's no longer necessary
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(stopUpdatingLocation:) object:nil];
}
}
// update the display with the new location data
}
The credit goes to Apple because this is a snippet straight from their sample code LocateMe:
http://developer.apple.com/library/ios/#samplecode/LocateMe/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007801-Intro-DontLinkElementID_2
So when you get the notification and need to get a better result you'll need to update the accuracy and see if that gives you a better result.

difference between desiredAccuracy and distanceFilter

Sorry for being a noob here. I am not able to clearly differentiate between CLLocationManager's properties distanceFilter and desiredAccuracy.
If I want my application to give different coordinates for even small distances (say 100-200 metres) what values should i set for these properties.
Help would be greatly appreciated.
According to developer.apple.com
distanceFilter
The minimum distance (measured in meters) a device must move laterally
before an update event is generated.
That means, based on previous location event, another location update will only be received after exceeding distanceFilter value distance.
desiredAccuracy refers to how accurate your location data should be.
For example if you wish to see the exact street you're on you a high accuracy value for this parameter. (kCLLocationAccuracyBest)
If you only wish to see the approximate area (such as in which neighbourhood you're in) you'd set a lower accuracy value for this param. (kCLLocationAccuracyThreeKilometers)
Choose this to suit your needs, however be aware that the more precise you wish to be and the more often you request updates, the more power it will drain from your device.
Hope this helps,
Vlad
distanceFilter - this is minimal distance which device should pass from previous location which was passed to delegate with ...didUpdateToLocation:... method. And as soon as distance reached location service will invoke ...didUpdateToLocation... again and so on.
desiredAccuracy - tells to location service how accurate coordinate you want and this is minimal location error radius. If value is very low (ex. 5) radio will try to use GPS hardware and will keep powering it up hardly to make it give most accurate location. If value is large,than system may decide to use data which was retrieved from WiFi hotspots location triangulation.