Pergunta

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;
}
Foi útil?

Solução

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.

Outras dicas

Now you could use Google Maps SDK for iOS. That's the only legal option if you need to display Google Directions API under iOS6.

You can use Mapkit direction request API.

Direction request api has some limitation for consecutive calls made otherwise it works similar as google direction api.

There are ways to fetch direction for driving, walking and transit. Also there is a way to get alternate routes.

MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];

MKPlacemark *sourcePlacemark = [[MKPlacemark alloc] initWithCoordinate:SourceCLLocationCorodinate).coordinate addressDictionary:nil];
MKMapItem *sourceMapItem = [[MKMapItem alloc] initWithPlacemark:sourcePlacemark];
[request setSource:sourceMapItem];

MKPlacemark *destPlacemark = [[MKPlacemark alloc] initWithCoordinate:destCLLocationCoordinate addressDictionary:nil];
MKMapItem *destMapItem = [[MKMapItem alloc] initWithPlacemark:destPlacemark];
[request setDestination:destMapItem];
[request setTransportType:MKDirectionsTransportTypeAny];
request.requestsAlternateRoutes = NO;

MKDirections *directions = [[MKDirections alloc] initWithRequest:request];

if(![directions isCalculating])
{
    [directions calculateDirectionsWithCompletionHandler:
    ^(MKDirectionsResponse *response, NSError *error) {
     if (error)
     {
         // Handle Error
         NSLog(@"Error for this particular call");
     }
     else
     {
         for (MKRoute * route in response.routes)
         {
             //Add the route.polyline to the mapkit overlay
         }
     }];
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top