gpt4 book ai didi

ios - 在谷歌路径中的坐标之间插入点的最佳方法是什么?这种方法正确吗?

转载 作者:行者123 更新时间:2023-11-28 13:49:01 25 4
gpt4 key购买 nike

我正在尝试在 Googlemap 上绘制折线,以向 Uber 中的用户显示司机/送货员的位置。

enter image description here

我使用谷歌 directions API获取概览折线并将其绘制在 map 上。现在我从我们自己的服务器获取驱动程序位置,为了更新 map 上的用户位置,我遍历 GMSPath 中的坐标,我通过将概览折线解码为

            if let jsonArray = jsonResult["routes"].array, jsonArray.count > 0 {
for json in jsonArray {
if let polyline = json["overview_polyline"]["points"].string {
self.possibleOverViewPolylines.append(polyline)
}
}
}
self.currentPolyline = self.possibleOverViewPolylines[0]
self.path = GMSMutablePath.init(fromEncodedPath: self.currentPolyline)
self.polyline = GMSPolyline(path: self.path)

Google 通常在发送 alternative=true 时返回多条路线,所以我缓存了所有 overview_polyline 并使用第一个作为当前路线。

现在,通过阅读和试错,我发现捕获的驱动程序的经纬度可能存在误差,范围可能在 5-50 米之间。因此,一旦获得驾驶员位置,我便遍历路径中的整个坐标以找到 map 中最近的点并将驾驶员捕捉到该位置

           var overallDistance: CLLocationDistance = 50
for index in 0 ..< strongSelf.path.count() {
let coordinate = strongSelf.path.coordinate(at: UInt(index))
let distance = location.distance(to: coordinate)
if distance < overallDistance {
foundIndex = Int(index)
overallDistance = distance
}
}
if overallDistance >= 50 {
debugPrint("\(location)")
evaluateAlternativeRoutes()
}
else {
updatepolyline(location: strongSelf.path.coordinate(at: UInt(foundIndex)))
}

将折线更新为

            self?.polyline.map = nil
while strongSelf.path.coordinate(at: UInt(0)).latitude != location.latitude && strongSelf.path.coordinate(at: UInt(0)).longitude != location.longitude {
self?.path.removeCoordinate(at: 0)
}
if strongSelf.path.coordinate(at: 0).latitude == location.latitude && strongSelf.path.coordinate(at: UInt(0)).longitude == location.longitude {
self?.path.removeCoordinate(at: 0)
}
self?.polyline = GMSPolyline(path: strongSelf.path)

最终替代路线被评估为

        var overallDistance: CLLocationDistance = 50
var foundIndex = -1

for (polylineIndex,polyline) in strongSelf.possibleOverViewPolylines.enumerated() {
if let path = GMSMutablePath.init(fromEncodedPath: polyline) {
for index in 0 ..< path.count() {
let coordinate = path.coordinate(at: UInt(index))
let distance = location.distance(to: coordinate)
if distance < overallDistance {
foundIndex = polylineIndex
overallDistance = distance
}
}
}
}
if foundIndex != -1 {
self?.path = GMSMutablePath.init(fromEncodedPath: strongSelf.possibleOverViewPolylines[foundIndex])
}
else {
//make routes API call again
}

如果没有可用的替代路线与司机位置相匹配,司机可能会选择一条完全不同的路线,所以我使用司机位置再次调用路线 API

为什么要进行这么多优化?

Google 的路由 API 成本高昂,不必要地调用 google routes API 会增加财务负担,并破坏整个用户体验,因此希望在本地进行大部分计算

但是上面的代码不是最理想的:(它有效但不是很好:|

这种方法的问题

问题 1:方法假设驾驶员位置的可能错误率最大为 50 米,当我评估到路径中所有点的距离时,都会根据这个 50 检查,但不幸的是,谷歌路径中的坐标分布不均,在一条漫长的直路上,2 之间的距离路径坐标中的后续点最长可达 200m。我测试了它

           for i in 0 ..< self.path.count() {
if i == 0 {
debugPrint(self.path.coordinate(at: i))
}
else {
debugPrint("distance between \(self.path.coordinate(at: (i - 1))) and \(self.path.coordinate(at: (i))) is \(self.path.coordinate(at: (i - 1)).distance(to: self.path.coordinate(at: (i))))")
}
}

因此,将司机位置与 50m 路径中的所有点进行比较的逻辑作为上限逻辑在那里失败。

我能想到的解决方案

如果我可以以 50m 的规则间隔在 google 路径中的任意两个坐标之间插入点,并将上限提高到 100m(路径中两点之间的距离为 50m,lat-long 中的误差为 50m)那应该相当我有更好的机会减少 API 调用次数

我尝试了什么?

我尝试使用线性插值法解决它

enter image description here

无需说结果是灾难性的,因为等式假定笛卡尔平面并且地球不平坦:|

最后你到底在问什么?

  1. 在谷歌路径的两个坐标之间插入点以实现我想要实现的目标是否是一种正确的方法?

  2. 如果是,我应该使用哪种更好的插值算法?显然线性没有多大意义:(

请帮助,在此先感谢

最佳答案

Google 本身已经提供了各种用于在 GMSGeometryUtils 模块中进行插值的方法。我认为您需要进行插值的可能是: https://developers.google.com/maps/documentation/ios-sdk/reference/group___geometry_utils.html#gad0c5870bd9d182d22310f84a77888124

GMSGeometryInterpolate 使用您在给定分数处提供的“从”和“到”坐标之间的最短路径,而 GMSPath 确实连接了您提供的每个子序列坐标之间的最短路径,因此它应该足够了。

关于ios - 在谷歌路径中的坐标之间插入点的最佳方法是什么?这种方法正确吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55011159/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com