检查用户是否遵循路线(iphone) [英] Check user is following the route or not (iphone)

查看:155
本文介绍了检查用户是否遵循路线(iphone)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作基于导航的应用程序。在这个应用程序中,我正在从用户选择的点绘制路线。如果用户没有遵循路线,我需要重新计算路线。

i am making an navigation based application. In this application i am drawing a route from points selected by the user. I have requirement of recalculating route if user is not following the route.

用于计算我使用的路线 Google方向API 。并且用于绘制我已使用此代码的路线

for Calculating the route i have used Google direction API. and for drawing the route i have used this code

- (void) drawRoute:(NSArray *) path
{
    NSInteger numberOfSteps = path.count;
    [self.objMapView removeOverlays: self.objMapView.overlays];

    CLLocationCoordinate2D coordinates[numberOfSteps];
    for (NSInteger index = 0; index < numberOfSteps; index++)
    {
        CLLocation *location = [path objectAtIndex:index];
        CLLocationCoordinate2D coordinate = location.coordinate;

        coordinates[index] = coordinate;
    }

    for( id <MKOverlay> ovr in [self.objMapView overlays])
    {
        MKPolylineView *polylineView = [[MKPolylineView alloc] initWithPolyline:ovr];


        if (polylineView.tag == 22)
        {
            [self.objMapView removeOverlay:ovr];
        }
        [polylineView release];
    }

    MKPolyline *polyLine = [MKPolyline polylineWithCoordinates:coordinates count:numberOfSteps];
    [self.objMapView addOverlay:polyLine];


}

到目前为止,每件事都很好。

Till now every thing is okey.

现在,如果用户不在路线(超过100米),我想要通知。我也可以收到通知

Now, i want a notification if user is out of route (more than 100 meters).and i can get the notification also

问题:〜如果道路是直的(超过100吨),那么我不能在路上获得积分。为了解释我附加图像的问题......

PROBLEM:~ if road is straight (more than 100mt) then i cant get points on the road. To explain the problem i have attached the image...

在此图像中,假设黑线是我的路径(折线),红色圆圈是我从google apis获得的点数。但是在显示为蓝色圆圈的直线路径中,我无法获得要比较的点,并且在此路径中调用重新计算功能。

In this image suppose black line is my path (polyline) and red circles are the points i got form google apis. but in the straight path shown as blue circle i cant get points to compare and in this path recalculation function is called.

任何人都可以告诉我解决方案,我可以得到所有路线,即使它是直路。

Can any one tell me the solution from which i can get all points of route even if it is a straight road.

推荐答案

我知道这是一个旧线程,但最近遇到了同样的问题,找到了一个好的解决方案。
概念是您不计算到每个线段的距离,而只计算连接到最近点的两个段。

I know this is an old thread, but recently ran into the same problem and found an OK solution. The concept is that you don't calculate the distance to EACH line segment but only to the TWO segments connected to the closest point.


  1. 计算当前位置到
    MKPolyline中所有点的距离,并从中获取最小值。 (可能有一些很好的方法来优化它。就像没有迭代每个位置更新的所有点,但现在没有时间去挖掘它。)

  2. 你现在知道了到最近的折线点的距离。然而,当折线本身(连接此点与前一点或下一点)可能更接近时,该点可能仍然很远。因此,计算当前位置与这两个线段之间的距离,并且距离最近。

现在,这不是防水。虽然它最小化了api调用的nr,但在某些情况下(如果你在MKPolyline中有疯狂的弯曲和曲线)它可能在不需要的时候调用api,但是嘿,那么同一行将被再次绘制,没有造成损坏。在我的测试中它工作正常,你也可以调整准确性。我在下面的代码中将它设置为200米(0.2公里)。

Now, this is not waterproof. While it minimizes the nr of api calls, on some occasions (If you have crazy bends and curves in the MKPolyline) it might call the api while not needed, but hey, then the same line will be drawn again, no damage done. In my tests it worked fine and you can also adjust the accuracy. I've set it to 200m (0.2km) in the code below.

//Get Coordinates of points in MKPolyline
NSUInteger pointCount = routeLineGuidanceTurn.pointCount;
CLLocationCoordinate2D *routeCoordinates = malloc(pointCount * sizeof(CLLocationCoordinate2D));
[routeLineGuidanceTurn getCoordinates:routeCoordinates
                         range:NSMakeRange(0, pointCount)];
NSLog(@"route pointCount = %d", pointCount);


//Determine Minimum Distance and GuidancePoints from
double MinDistanceFromGuidanceInKM = 1000;
CLLocationCoordinate2D prevPoint;
CLLocationCoordinate2D pointWithMinDistance;
CLLocationCoordinate2D nextPoint;

for (int c=0; c < pointCount; c++)
{
    double newDistanceInKM = [self distanceBetweentwoPoints:Currentcordinate.latitude longitude:Currentcordinate.longitude Old:routeCoordinates[c].latitude longitude:routeCoordinates[c].longitude];
    if (newDistanceInKM < MinDistanceFromGuidanceInKM) {
        MinDistanceFromGuidanceInKM = newDistanceInKM;
        prevPoint = routeCoordinates[MAX(c-1,0)];
        pointWithMinDistance = routeCoordinates[c];
        nextPoint = routeCoordinates[MIN(c+1,pointCount-1)];
    }
}
free(routeCoordinates);


NSLog(@"MinDistanceBefore: %f",MinDistanceFromGuidanceInKM);

//If minimum distance > 200m we might have to recalc GuidanceLine.
//To be sure we take the two linesegments connected to the point with the shortest distance and calculate the distance from our current position to that linedistance.
if (MinDistanceFromGuidanceInKM > 0.2) {
    MinDistanceFromGuidanceInKM = MIN(MIN([self lineSegmentDistanceFromOrigin:Currentcordinate onLineSegmentPointA:prevPoint pointB:pointWithMinDistance], [self lineSegmentDistanceFromOrigin:Currentcordinate onLineSegmentPointA:pointWithMinDistance pointB:nextPoint]),MinDistanceFromGuidanceInKM);

    if (MinDistanceFromGuidanceInKM > 0.2) {
        // Call the API and redraw the polyline.
    }
}

这是计算两点之间距离的乐趣。我知道它有一个内置函数,但已经在我的代码中了。

Here's the fun that calculate sthe distance between two points. I know there is a built in function for it, but had it in my code already.

-(double)distanceBetweentwoPoints:(double)Nlat longitude:(double)Nlon Old:(double)Olat longitude:(double)Olon  {
    //NSLog(@"distanceBetweentwoPoints");
    double Math=3.14159265;
    double radlat1 = Math* Nlat/180;
    double radlat2 = Math * Olat/180;
    double theta = Nlon-Olon;
    double radtheta = Math * theta/180;
    double dist = sin(radlat1) * sin(radlat2) + cos(radlat1) * cos(radlat2) * cos(radtheta);
    if (dist>1) {dist=1;} else if (dist<-1) {dist=-1;}
    dist = acos(dist);
    dist = dist * 180/Math;
    dist = dist * 60 * 1.1515;
    return dist * 1.609344;
}

这是计算点与线段之间距离的位另外两点。我从这里得到了这个: https://stackoverflow.com/a/28028023/3139134 修改了一下以便与之合作CLLocationCoordinate2D并返回距离。

And here's the bit that calculates the distance between a point and a line segment between two other points. I got this from here: https://stackoverflow.com/a/28028023/3139134 Modified it a bit to work with CLLocationCoordinate2D and return the distance.

- (CGFloat)lineSegmentDistanceFromOrigin:(CLLocationCoordinate2D)origin onLineSegmentPointA:(CLLocationCoordinate2D)pointA pointB:(CLLocationCoordinate2D)pointB {

    CGPoint dAP = CGPointMake(origin.longitude - pointA.longitude, origin.latitude - pointA.latitude);
    CGPoint dAB = CGPointMake(pointB.longitude - pointA.longitude, pointB.latitude - pointA.latitude);
    CGFloat dot = dAP.x * dAB.x + dAP.y * dAB.y;
    CGFloat squareLength = dAB.x * dAB.x + dAB.y * dAB.y;
    CGFloat param = dot / squareLength;

    CGPoint nearestPoint;
    if (param < 0 || (pointA.longitude == pointB.longitude && pointA.latitude == pointB.latitude)) {
        nearestPoint.x = pointA.longitude;
        nearestPoint.y = pointA.latitude;
    } else if (param > 1) {
        nearestPoint.x = pointB.longitude;
        nearestPoint.y = pointB.latitude;
    } else {
        nearestPoint.x = pointA.longitude + param * dAB.x;
        nearestPoint.y = pointA.latitude + param * dAB.y;
    }

    CGFloat dx = origin.longitude - nearestPoint.x;
    CGFloat dy = origin.latitude - nearestPoint.y;
    return sqrtf(dx * dx + dy * dy) * 100;

}

这篇关于检查用户是否遵循路线(iphone)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆