【问题标题】:Can't get index in array of CLLocation Swift无法在 CLLocation Swift 数组中获取索引
【发布时间】:2019-12-03 12:37:45
【问题描述】:

我正在编写自己的位置过滤器功能,因为我真的发现LocationManager() 选项非常无用.. 非常不精确,并且我在帖子中遵循几十个指南尝试的任何设置总是导致非常糟糕的跟踪......我可怕的意思。。 我实际上是直接在didUpdateLocations 中实现了这个过滤,但是一旦你到达很远,那么后面的任何位置都会被丢弃。除了个人意见,我基本上接受除horizontal accuracy < 0 之外的每个传入位置,然后当我停止获取新位置时,我将数组过滤掉以下参数,如minDistancemaxDistance从以前保存的位置,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
    }

这是控制台打印:

加工位置 +/- 65.00m(速度 -1.00 mps / course -1.00) @ 03/12/19, 13:16:09 Ora 标准 dell'Europa centrale 指数为:9223372036854775807 处理 位置为 +/- 65.00m(速度 -1.00 mps / course -1.00) @ 03/12/19, 13:16:07 Ora standard dell'Europa centrale 索引是:9223372036854775807 处理位置是 +/- 65.00m(速度 -1.00 mps / 路线 -1.00) @ 03/12/19, 13:16:22 Ora standard dell'Europa centrale index is : 9223372036854775807 处理位置是 +/- 65.00m(速度 -1.00 mps / 路线 -1.00) @ 03/12/19, 13:16:37 Ora 标准 dell'Europa centrale 索引为:9223372036854775807 routeFiltered 为 [ +/- 65.00m(速度 -1.00 mps / 路线 -1.00)@ 03/12/19, 13:16:09 Ora standard dell'Europa centrale, +/- 65.00m (速度 -1.00 mps / 课程 -1.00)@ 03/12/19, 13:16:07 Ora 标准 dell'Europa centrale, +/- 65.00m(速度 -1.00 mps / course -1.00) @ 03/12/19, 13:16:22 Ora standard dell'Europa centrale, +/- 65.00m(速度 -1.00 mps / course -1.00) @ 03/12/19, 13:16:37 Ora standard dell'Europa centrale] MapArray.actualRouteInUseCoordinatesArray.count 是:4

【问题讨论】:

  • index 应该包含什么,调用index(ofAccessibilityElement: location) 的预期结果是什么?如果它应该是数组中的一个位置,那么index(ofAccessibilityElement: location) 与什么有什么关系?
  • @JoakimDanielson 是的,你是绝对正确的,这是错误的。我确实需要数组中的位置。
  • index(ofAccessibilityElement:)firstIndex(where:)?
  • @Larme 我试过 if let index = routeFiltered.firstIndex(where: { $0 == location })if let index = routeFiltered.index(where: { $0 === location }) 但索引打印 function 不是 Int.. 所以当我尝试读取以前的值时,它会与 Thread 1: Fatal error: Index out of range 一起崩溃。
  • 我不明白你为什么在routeFiltered[0]上搜索索引,然后直接在routeFiltered上应用/测试。

标签: ios arrays swift indexof


【解决方案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 的那个。

【讨论】:

  • 这一切都按预期工作并过滤掉不需要的位置,但我必须省略速度,因为它总是从实际的 iPhone 而不是模拟器读取 -1。但是通过正确的最小距离,我也可以摆脱那些错误的位置
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-10
  • 1970-01-01
  • 2019-03-14
  • 2019-05-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多