在 Google Maps SDK 中查找要路由的位置距离

Find distance of location to route in Google Maps SDK

我正在开发一个 iPhone 应用程序,在这个案例中我需要一些帮助:

我需要检查,如果用户离开 google 地图路线(GMSPolyline),并且从用户位置到路线最近点的距离是否超过 40 米——我需要重建路线。

我找不到正确的算法来检测用户到路线的距离是否超过 40 米。

我尝试使用此方法在路线上查找用户位置的投影(由 CGPointMake 转换为 CGPoint):

+ (CGPoint)projectionOfPoint:(CGPoint)origPoint toSegmentP1:(CGPoint)p1 p2:(CGPoint)p2 {
// for case line is parallel to x axis
if (p2.y == p1.y) {
    return CGPointMake(origPoint.x, p1.y);

// for case line is parallel to y axis
} else if (p2.x == p1.x) {
    return CGPointMake(p1.x, origPoint.y);
}

// line from segment
CGFloat kKoefLine1 = (p2.x - p1.x)/(p2.y - p1.y);
CGFloat bKoefLine1 = p1.y - kKoefLine1*p1.x;

// perpendicular line
CGFloat kKoefLine2 = -1/kKoefLine1;
CGFloat bKoefLine2 = origPoint.y - kKoefLine2*origPoint.x;

// cross point
CGFloat krossX     = (bKoefLine2 - bKoefLine1)/(kKoefLine1 - kKoefLine2);
CGFloat krossY     = kKoefLine2*krossX + bKoefLine2;

return CGPointMake(krossX, krossY);}

然后我从返回的投影(转换为 CLLocation)和用户位置计算距离,但它不起作用。

P.S.: 如果解决方案写在 swift.

上,我将不胜感激

虽然我不太记得 GMS SDK,但在我给你答案之前,我会说这里没有人会为你编写代码。那是你的工作,应该在你的时间完成。您没有提供任何关于您在计算路线方面取得了多大进展的背景,您是否已经弄清楚如何计算距离等等。

话虽如此,Google 地图上的路线由 "legs" 组成,表示在努力到达最终目的地之前要走的一条路。通过查询 "route" 词典,您可以提取一个词典数组,其中每个元素(这是一个词典)都包含关于 "leg" 的元数据。然后,您可以遍历该数组,遍历每个字典并提取 "distance" 值,然后将它们相加到一个 "distance" 变量中。

您可以根据需要经常重新计算,并使用条件检查腿距离总和是否 < 40M,否则重建。

link 到一篇应该有所帮助的文章(我没有时间为您完成整个事情,所以请尽职调查和研究)here.

在 Google Maps SDK 的 GMSGeometryUtils 模块中有一个 GMSGeometryIsLocationOnPath 函数。

您应该能够使用它来计算您需要的内容。

伪代码(未测试):

let currentLocation: CLLocationCoordinate2D = ...
let routePath: GMSPath = routePolyline.path
let geodesic = true
let tolerance: CLLocationDistance = 40

let within40Meters = GMSGeometryIsLocationOnPath(currentLocation, routePath, geodesic, tolerance)

对于 swift 5.0 并且基于@Arthur 的回答我写了以下分数

func isInRoute(posLL: CLLocationCoordinate2D, path: GMSPath) -> Bool
{

    let geodesic = true
    let tolerance: CLLocationDistance = 40

    let within40Meters = GMSGeometryIsLocationOnPathTolerance(posLL, path, geodesic, tolerance)
    return within40Meters

}