Search code examples
objective-cios6google-apimkmapviewdirections

Trouble to show route between points Google Directions API. iOS 6


I have a problem when displaying a route in MapView if route has waypoints. I use DIRECTIONS GOOGLE API:

https://developers.google.com/maps/documentation/directions/

The route is not drawn using the road.

Any help? Thanks!!

The trouble images: enter image description here

enter image description here

The code:

reponse = [self getRouteFromGoogleApiWithPoints:arrayOfCoords andMode:@"driving" error:error];

if(reponse == nil)
{
   UIAlertView *succes= [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"txtError", nil) message:NSLocalizedString(@"ServerError", nil) delegate: self cancelButtonTitle: @"OK" otherButtonTitles: nil];
        [succes show];
}
else
{
        NSArray *routes = [reponse objectForKey:@"routes"];
        NSDictionary *route = [routes objectAtIndex:0];
        NSDictionary *polylineOverview = [route objectForKey:@"overview_polyline"];

        NSString *polylinePoints = [polylineOverview objectForKey:@"points"];
        NSArray *decodedPolyline = [self decodePolyLine:polylinePoints];

        CLLocationCoordinate2D coords[[decodedPolyline count]];
        int i=0;
        for(CLLocation* loc in decodedPolyline)
        {
            CLLocationCoordinate2D c;
            c.latitude = loc.coordinate.latitude;
            c.longitude = loc.coordinate.longitude;

            coords[i]=c;
            i++;

        }

        MKPolyline *line = [MKPolyline polylineWithCoordinates:(CLLocationCoordinate2D*)coords count:decodedPolyline.count];

        [mapview addOverlay:line];
        [mapview setNeedsDisplay];
    }
}
}

+ (NSMutableArray *)decodePolyLine: (NSString *)encoded {

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 *loc = [[CLLocation alloc] initWithLatitude:[latitude floatValue] longitude:[longitude floatValue]];
    [array addObject:loc];
}

return array;
}

+(NSDictionary*)getRouteFromGoogleApiWithPoints:(NSArray*)arrayOfPoints andMode:(NSString*)mode error:(NSError **)error
{
NSDictionary *result = nil;

NSString *waypoints = @"";

CLLocation* origin = [arrayOfPoints objectAtIndex:0];
CLLocation* destination = [arrayOfPoints objectAtIndex:arrayOfPoints.count - 1];

// Create the waypoints
for(int i = 1; i < arrayOfPoints.count - 2; i++)
{
    CLLocation* current = [arrayOfPoints objectAtIndex:i];
    waypoints = [waypoints stringByAppendingString:[NSString stringWithFormat:@"%f,%f%%7C",current.coordinate.latitude,current.coordinate.longitude]];
}

CLLocation* lastWaypoint = [arrayOfPoints objectAtIndex:arrayOfPoints.count - 2];
waypoints = [waypoints stringByAppendingString:[NSString stringWithFormat:@"%f,%f",lastWaypoint.coordinate.latitude,lastWaypoint.coordinate.longitude]];

NSString *urlString =[NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/directions/json?origin=%f,%f&destination=%f,%f&waypoints=%@&sensor=true&mode=%@",origin.coordinate.latitude,origin.coordinate.longitude,destination.coordinate.latitude,destination.coordinate.longitude,waypoints,mode];

NSDictionary* response = [self getDictionaryFromURLString:urlString withParameters:nil error:error];

if (response != nil)
{
    if ([[response objectForKey:@"status"] isEqualToString:@"OK"])
    {
        result = response;
        NSLog(@"%@",response);

    }
    else
    {
        if (error)
        {
            NSMutableDictionary* details = [NSMutableDictionary dictionary];
            [details setValue:[response objectForKey:@"status"] forKey:NSLocalizedDescriptionKey];
            *error = [[NSError alloc] initWithDomain:@"AppName" code:2 userInfo:details];
        }
    }
}
else
{
    if(error)
    {
        NSMutableDictionary* details = [NSMutableDictionary dictionary];
        [details setValue:NSLocalizedString(@"ErrorServidor", nil) forKey:NSLocalizedDescriptionKey];
        *error = [NSError errorWithDomain:@"AppName" code:1 userInfo:details];
        return nil;
    }
}

return result;
}

Solution

  • First off, according to the Google Terms & Conditions you're not allowed to use their directions/data on someone else's maps.

    Secondly, the first is partly imposed because people have different data, place roads in different spots, break the roads into different segments etc etc and thus instructions don't line up.

    If you want to show directions in your map you'll have to find another source. Maybe you should consider the CloudMade API.