我正在编写自己的位置过滤器功能,因为我严重地发现LocationManager()
选项非常无用。.非常不精确,并且我在遵循数十篇指南后尝试进行的任何设置始终会导致跟踪效果非常差。我的意思是可怕的。
实际上,我实际上是在didUpdateLocations
中直接实现了此过滤,但是一旦您走到很远,随后的任何位置都会被丢弃。除了个人意见,我基本上接受horizontal accuracy < 0
之外的每个传入位置,然后当我停止获取新位置时,从先前保存的位置中过滤掉参数minDistance
和maxDistance
等数组,timestamp
和speed
。但是,当我在家里尝试稳定时,我发现面团循环良好,但打印出的图像并没有滤掉任何东西,因为我弄错了索引。您能看到我应该如何获取索引吗?一如既往,非常感谢您的帮助。
这是功能:
func filterInvalidLocation(route: [CLLocation]) -> [CLLocation] {
var routeFiltered = route
for location in routeFiltered {
print("processing location is \(location)")
let index = routeFiltered[0].index(ofAccessibilityElement: location)
print("index is : \(index)")
if index > 0 && index <= routeFiltered.capacity{
// invalid
if location.horizontalAccuracy < 0 {
routeFiltered.remove(at: index)
print("location removed : invalid")
}
// too low accuracy
if location.horizontalAccuracy > 80 {
routeFiltered.remove(at: index)
print("location removed : low accuracy")
}
// not sequential
if location.timestamp < routeFiltered[index - 1].timestamp {
routeFiltered.remove(at: index)
print("location removed : not sequential")
}
// too far
if location.distance(from: routeFiltered[index - 1]) > maxDistance {
routeFiltered.remove(at: index)
print("locatione removed : too far")
}
// too close
if location.distance(from: routeFiltered[index - 1]) < minDistance {
routeFiltered.remove(at: index)
print("location removed : too close")
}
// not mooving
if location.speed < 1 {
routeFiltered.remove(at: index)
print("location removed : not mooving")
}
}
}
print("routeFiltered is \(routeFiltered)")
return routeFiltered
}
这是控制台打印:
处理位置为<+ 44.50137329,+ 11.33594359> +/- 65.00m(速度 -1.00 mps / course -1.00)@ 03/12/19,13:16:09 Ora standard dell’Europa centrale index是:9223372036854775807处理 位置是<+ 44.50140045,+ 11.33594359> +/- 65.00m(速度-1.00 mps / 当然-1.00)@ 03/12/19,13:16:07 Ora standard dell’Europa centrale 索引是:9223372036854775807处理位置是 <+ 44.50140053,+ 11.33594337> +/- 65.00m(速度-1.00 mps /课程 -1.00)@ 03/12/19,13:16:22 Ora standard dell’Europa centrale index是:9223372036854775807处理位置是 <+ 44.50140056,+ 11.33594332> +/- 65.00m(速度-1.00 mps /课程 -1.00)@ 03/12/19,13:16:37 Ora标准Dell欧罗巴中央索引为:9223372036854775807 routeFiltered为[<+ 44.50137329,+ 11.33594359> +/- 65.00m(速度-1.00 mps /路线-1.00)@ 03/12/19,13:16:09 Ora standard dell’Europa centrale,<+ 44.50140045,+ 11.33594359> +/- 65.00m (速度-1.00 mps /课程-1.00)@ 19/3/12,13:16:07 Ora standard dell’Europa centrale,<+ 44.50140053,+ 11.33594337> +/- 65.00m(速度 -1.00 mps / course -1.00)@ 03/12/19,13:16:22 Ora standard dell’Europa centrale,<+ 44.50140056,+ 11.33594332> +/- 65.00m(速度 -1.00 mps / course -1.00)@ 03/12/19,13:16:37 Ora standard dell’Europa centrale] MapArray.actualRouteInUseCoordinatesArray.count 是:4
答案 0 :(得分:1)
可能的解决方案是使用reduce(into:)
。使用“上一个索引”更容易。
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
}
带有示例:
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)),
]
这可以在操场上进行测试,我们应该将第一个和第一个保留在索引7中。