Google地图for iOS上的路线绘图不遵循街道线

时间:2014-03-20 07:47:24

标签: ios google-maps

我正在开发一款iOS应用,该应用使用Google Directions API在Google Maps SDK提供的地图上绘制路线。它适用于小距离,但是当我非常接近地缩放地图相机时,我看到路线折线经常走出街道。当距离较长时,这是一场真正的灾难,如果我放大,它就不会跟随街道曲线。我从Directions API获得的概览 - 折线得到了点,但似乎折线不是那么多边形我想要。在Android上它完美无缺。难道Google会向iOS发送与Android不同的指示吗?你们有些人和我有同样的问题吗?

修改

    -(int) requestDirecionsAndshowOnMap:(GMSMapView *)aMapView{


    NSArray* mode=[[NSArray alloc]initWithObjects:@"transit",@"bicycling",@"walking",@"driving", nil];
    NSString *depart=[[NSString alloc] initWithFormat:@""];
    NSString *origin=[[NSString alloc] initWithFormat:@""];
    NSString *destination=[[NSString alloc] initWithFormat:@""];

    if (self.setLanguage)
        self.setLanguage=[NSString stringWithFormat:@"language=%@",self.setLanguage];
    else self.setLanguage=@"language=en";

    if (searchModeOption==0) {
        if (self.departDate==nil) {
            self.departDate=[NSDate date];
        }

        depart=[NSString stringWithFormat:@"&departure_time=%i",(int)[self.departDate timeIntervalSince1970]];

    }

    if (self.origin) {
        origin=[NSString stringWithFormat:@"origin=%@",self.origin];
    }else if (self.originCoordinate.latitude && self.originCoordinate.longitude){
        origin=[NSString stringWithFormat:@"origin=%f,%f",self.originCoordinate.latitude,self.originCoordinate.longitude];
    }else{
        NSLog(@"No origin setted");
        return -1;
    }

    if (self.destination) {
        destination=[NSString stringWithFormat:@"destination=%@",self.destination];
    }else if (self.destinationCoordinate.latitude && self.destinationCoordinate.longitude){
        destination=[NSString stringWithFormat:@"destination=%f,%f",self.destinationCoordinate.latitude,self.destinationCoordinate.longitude];
    }else{
        NSLog(@"No destination setted");
        return -1;
    }

    NSString* URLforRequest=[[NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/directions/json?%@&%@&sensor=false&%@&alternative=false&mode=%@%@",origin,destination,self.setLanguage,[mode objectAtIndex:searchModeOption],depart] stringByAddingPercentEscapesUsingEncoding: NSASCIIStringEncoding];

    // NSLog(@"%@",URLforRequest);

    NSURLRequest *requests = [NSURLRequest requestWithURL:[NSURL URLWithString:URLforRequest]];

    [NSURLConnection sendAsynchronousRequest:requests queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){

        if (error==nil && data) {
            // NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
            directions = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];
            if (error) {
                NSLog(@"%@",error);
            }
            NSString* status=[directions objectForKey:@"status"];
            NSLog(@"Status: %@", status);

            if ([status isEqualToString:@"OK"]) {
                [self decodeResult];
                if (aMapView)
                    [self showOnMap:aMapView];
            }
        }else NSLog(@"%@",error);

        [[NSNotificationCenter defaultCenter] postNotificationName:@"Request Done" object:nil];


    }];


    return 0;
}

-(void) decodeResult{

    self.destination=[[[[[directions objectForKey:@"routes"] objectAtIndex:0] objectForKey:@"legs"] objectAtIndex:0] objectForKey:@"end_address"];

    self.distance=[[[[[[[directions objectForKey:@"routes"] objectAtIndex:0] objectForKey:@"legs"] objectAtIndex:0] objectForKey:@"distance"] objectForKey:@"text"] doubleValue];

    self.duration=[[[[[[directions objectForKey:@"routes"] objectAtIndex:0] objectForKey:@"legs"] objectAtIndex:0] objectForKey:@"duration"] objectForKey:@"text"];

    //Get Array of Instructions

    self.instrunctions=[[NSMutableArray alloc] init];

    for (int n=0; n<[[[[[[directions objectForKey:@"routes"] objectAtIndex:0] objectForKey:@"legs"] objectAtIndex:0] objectForKey:@"steps"]count]; n++) {
        [self.instrunctions addObject:[[[[[[[directions objectForKey:@"routes"] objectAtIndex:0] objectForKey:@"legs"] objectAtIndex:0] objectForKey:@"steps"] objectAtIndex:n] objectForKey:@"html_instructions"]];
    }

    //Get Overview Polyline

    NSString *polystring=[[[[directions objectForKey:@"routes"] objectAtIndex:0] objectForKey:@"overview_polyline"]  objectForKey:@"points"];
    NSMutableArray* decodedpolystring=[self decodePolyLine:polystring];

    int numberOfCC=[decodedpolystring count];
    GMSMutablePath *path = [GMSMutablePath path];
    for (int index = 0; index < numberOfCC; index++) {
        CLLocation *location = [decodedpolystring objectAtIndex:index];
        CLLocationCoordinate2D coordinate = location.coordinate;
        [path addLatitude:coordinate.latitude longitude:coordinate.longitude];
    }

    self.overviewPolilyne= [GMSPolyline polylineWithPath:path];

    //Get Coordinates of origin and destination to be displayed on a map
    float lat=[[[[[[[directions objectForKey:@"routes"] objectAtIndex:0] objectForKey:@"legs"]objectAtIndex:0] objectForKey:@"end_location"] objectForKey:@"lat"] floatValue];
    float lng=[[[[[[[directions objectForKey:@"routes"] objectAtIndex:0] objectForKey:@"legs"]objectAtIndex:0] objectForKey:@"end_location"] objectForKey:@"lng"] floatValue];
    CLLocationCoordinate2D tmp;
    tmp.latitude=lat;
    tmp.longitude=lng;
    self.destinationCoordinate=tmp;

    lat=[[[[[[[directions objectForKey:@"routes"] objectAtIndex:0] objectForKey:@"legs"]objectAtIndex:0] objectForKey:@"start_location"] objectForKey:@"lat"] floatValue];
    lng=[[[[[[[directions objectForKey:@"routes"] objectAtIndex:0] objectForKey:@"legs"]objectAtIndex:0] objectForKey:@"start_location"] objectForKey:@"lng"] floatValue];
    tmp.latitude=lat;
    tmp.longitude=lng;
    self.originCoordinate=tmp;

}



-(NSMutableArray *)decodePolyLine:(NSString *)encodedStr {
    NSMutableString *encoded = [[NSMutableString alloc] initWithCapacity:[encodedStr length]];
    [encoded appendString:encodedStr];
    [encoded replaceOccurrencesOfString:@"\\\\" withString:@"\\"
                                options:NSLiteralSearch
                                  range:NSMakeRange(0, [encoded length])];
    NSInteger len = [encoded length];
    NSInteger index = 0;
    NSMutableArray *array = [[NSMutableArray alloc] init];
    NSInteger lat=0;
    NSInteger lng=0;
    while (index < len) {
        NSInteger b;
        NSInteger shift = 0;
        NSInteger result = 0;
        do {
            b = [encoded characterAtIndex:index++] - 63;
            result |= (b & 0x1f) << shift;
            shift += 5;
        } while (b >= 0x20);
        NSInteger dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
        lat += dlat;
        shift = 0;
        result = 0;
        do {
            b = [encoded characterAtIndex:index++] - 63;
            result |= (b & 0x1f) << shift;
            shift += 5;
        } while (b >= 0x20);
        NSInteger dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
        lng += dlng;
        NSNumber *latitude = [[NSNumber alloc] initWithFloat:lat * 1e-5];
        NSNumber *longitude = [[NSNumber alloc] initWithFloat:lng * 1e-5];

        CLLocation *location = [[CLLocation alloc] initWithLatitude:[latitude floatValue] longitude:[longitude floatValue]];
        [array addObject:location];
    }

    return array;
}

-(void)showOnMap:(GMSMapView *)aMapView{
    GMSPolyline *polyline =self.overviewPolilyne;
    polyline.strokeColor = [UIColor blueColor];
    polyline.strokeWidth = 2.f;
    //polyline.geodesic = YES;
    polyline.map = aMapView; }

更新 我必须处理每一步的折线,而不仅仅是概览折线。现在它完美无缺。

这是我现在使用的代码:

// Get polyline
GMSMutablePath *path = [GMSMutablePath path];
NSMutableArray *polyLinesArray = [[NSMutableArray alloc] init];
int zero=0;
NSArray *steps = [[[[[directions objectForKey:@"routes"] objectAtIndex:zero] objectForKey:@"legs"] objectAtIndex:0] objectForKey:@"steps"];
for (int i=0; i<[[[[[[directions objectForKey:@"routes"] objectAtIndex:zero] objectForKey:@"legs"] objectAtIndex:0] objectForKey:@"steps"]count]; i++) {
    NSString* encodedPoints =[[[steps objectAtIndex:i]objectForKey:@"polyline"]valueForKey:@"points"];
    polyLinesArray = [self decodePolyLine:encodedPoints];
    NSUInteger numberOfCC=[polyLinesArray count];
    for (NSUInteger index = 0; index < numberOfCC; index++) {
        CLLocation *location = [polyLinesArray objectAtIndex:index];
        CLLocationCoordinate2D coordinate = location.coordinate;
        [path addLatitude:coordinate.latitude longitude:coordinate.longitude];
        if (index==0) {
            [self.coordinates addObject:location];
        }
    }
}
self.overviewPolilyne = [GMSPolyline polylineWithPath:path];

我之前基本上做过的是,我只使用routes中收到的信息,而如果您查看从Google Directions API收到的JSON文件,您会看到您在<legs><steps>中收到了更多信息。这是我们生成正确结果和正确折线所需的信息。 祝好运! :)

0 个答案:

没有答案