What Do Horizontalaccuracy and Verticalaccuracy of a Cllocation Refer To

What do horizontalAccuracy and verticalAccuracy of a CLLocation refer to?

The -1 for verticalAccuracy indicates that the altitude in the CLLocation is not valid. You only get altitude with a 3D GPS position.

The 1414 for horizontalAccuracy indicates that the horizontal (lat/lon) position could be up to 1414m off (this is just an estimated error). This is probably a location determined by cell tower triangulation or WiFi location data. GPS locations usually report 100m or better.

To get a higher accuracy location (300m or better) you need to set desiredAccuracy and wait for the GPS receiver to lock onto at least 3 satellites (or 4 for a 3D fix). Until that happens CLLocationManager will give you the best it has which is WiFi or Cell tower triangulation results.

CoreLocation current accuracy/range

When you get a location from the CLLocationManager you can read the effective accuracy using horizontalAccuracy and verticalAccuracy on CLLocation.

Creating a location based reminder: what to do with horizontal accuracy?

As pointed out by progmr, horizontalAccuracy is purely an estimate of the uncertainty in the location.

To back this up, I did a couple of real-world tests where:

  • I created a location-based reminder in the Reminders app, which has radius = 0 but also reports horizontalAccuracy = 0.
  • I created a reminder using the same location in my own code, setting radius = 0, but the return from CLGeocoder reporting horizontalAccuracy = 100

With each test, the reminders fired at exactly the same position. horizontalAccuracy is purely for information.

How accurate is CLLocation accuracy?

When you're using CoreLocation, you're getting back "answers" that get better and better. I've noticed that the "best" answer is almost always accurate to within 100m, so theoretically you could probably cut down on the "buffer" that you're normally given. The only way to really know, though, and this is what I would do, is to test test test. Find iphones and ipods from all generations and see what types of accuracies you're getting and what types of results you're getting. In a lot of ways, it depends on the type of app you're making, but if you want to deliver sensitive or important information based on where the user is, you should really wait for the framework to give you a nearly exact location.

Why is horizontalAccuracy = 0.00?

It seems you have found a bug.
There are some "secrets" in Gps application developpment:

1) if latitude and longitude both have the value 0 and if this location is marked as valid then this is always a programming error, on your or on API side, or some other place. Although (0,0) is theoretically possible practically it is reachable only via simulation. No ship or airplane can exactly navigate to (0,0) with a precision of 10cm.

2) same applies to some other values, like hdop or in your case horAcc.

So ignore this location!

iOS Location Accuracy

It's a limitation of the hardware, possible combined with your particular location. If you are indoors writing your code then GPS isn't going to work (try walking to a window), so you rely on WiFi which might just have very bad accuracy where you are, or on cell towers which isn't very accurate anywhere.

Can't get index in array of CLLocation Swift

A possible solution is to use reduce(into:). It's easier to play with "previous index".

func filterInvalidLocation(route: [CLLocation]) -> [CLLocation] {

let maxDistance = 500000.0
let minDistance = 10000.0
let reduced = route.reduce(into: [CLLocation]()) { (accumulated, currentLocation) in
// We don't add it if negative horizontal accuracy
guard currentLocation.horizontalAccuracy >= 0 else {
print("\(currentLocation) removed because of horizontalAccuracy being negative")
return
}
// We don't add it if Low Accuracy
guard currentLocation.horizontalAccuracy < 80 else {
print("\(currentLocation) removed because of horizontalAccuracy being > 80")
return
}
// We don't add it if not moving
guard currentLocation.speed > 1 else {
print("\(currentLocation) removed because of speed < 1")
return
}

guard let last = accumulated.last else {
//There is no valid one yet to compare, we consider this one as valid
accumulated.append(currentLocation)
return
}

//We check if there location is "newer"
guard last.timestamp < currentLocation.timestamp else {
print("\(currentLocation) removed because distance is older than previous one")
return
}

let distanceFromLast = currentLocation.distance(from: last)
print(distanceFromLast)
// We don't add it distance between last and current is too big
guard distanceFromLast < maxDistance else {
print("\(currentLocation) removed because distance is too big (\(distanceFromLast))")
return
}
// We don't add it distance between last and current is too low
guard distanceFromLast > minDistance else {
print("\(currentLocation) removed because distance is too small (\(distanceFromLast))")
return
}
//Current Location passed all test, we add it
accumulated.append(currentLocation)
}
return reduced
}

With sample:

let date = Date()

let locations: [CLLocation] = [CLLocation(coordinate: CLLocationCoordinate2D(latitude: 30.0, longitude: 45.0),
altitude: 30.0,
horizontalAccuracy: 0.1,
verticalAccuracy: 0.1,
course: 0.1,
speed: 2,
timestamp: date),
CLLocation(coordinate: CLLocationCoordinate2D(latitude: 30.0, longitude: 45.0),
altitude: 30.0,
horizontalAccuracy: -1.0,
verticalAccuracy: 0.1,
course: 0.1,
speed: 2,
timestamp: date),
CLLocation(coordinate: CLLocationCoordinate2D(latitude: 30.0, longitude: 45.0),
altitude: 30.0,
horizontalAccuracy: 90,
verticalAccuracy: 0.1,
course: 0.1,
speed: 2,
timestamp: date),
CLLocation(coordinate: CLLocationCoordinate2D(latitude: 30.0, longitude: 45.0),
altitude: 30.0,
horizontalAccuracy: 0.1,
verticalAccuracy: 0.1,
course: 0.1,
speed: 0.1,
timestamp: date),
CLLocation(coordinate: CLLocationCoordinate2D(latitude: 30.0, longitude: 45.0),
altitude: 30.0,
horizontalAccuracy: 0.1,
verticalAccuracy: 0.1,
course: 0.1,
speed: 2,
timestamp: date.addingTimeInterval(-1.0)),
CLLocation(coordinate: CLLocationCoordinate2D(latitude: 35.0, longitude: 50.0),
altitude: 30.0,
horizontalAccuracy: 0.1,
verticalAccuracy: 0.1,
course: 0.1,
speed: 2,
timestamp: date.addingTimeInterval(+1.0)),
CLLocation(coordinate: CLLocationCoordinate2D(latitude: 30.001, longitude: 45.0),
altitude: 30.0,
horizontalAccuracy: 0.1,
verticalAccuracy: 0.1,
course: 0.1,
speed: 2,
timestamp: date.addingTimeInterval(+2.0)),
CLLocation(coordinate: CLLocationCoordinate2D(latitude: 31.0, longitude: 45.0),
altitude: 30.0,
horizontalAccuracy: 0.1,
verticalAccuracy: 0.1,
course: 0.1,
speed: 2,
timestamp: date.addingTimeInterval(+1.0)),
]

This can be tested on playground, we should keep the first one and the one at index 7.



Related Topics



Leave a reply



Submit