Google Maps Directions url error when adding multiple waypoints

1.9k views Asked by At

I am trying to add multiple waypoints to my google directions request.

When I add a single waypoint like

https://maps.googleapis.com/maps/api/directions/json?&origin=51.507679,-0.125004&waypoints=51.524151,-0.123174&destination=51.495777,-0.108642&mode=walking

it works fine but when I try to add multiple waypoints like

https://maps.googleapis.com/maps/api/directions/json?&origin=51.606502,0.527309&waypoints=51.507679,-0.125004|51.524151,-0.123174&destination=51.495777,-0.108642&mode=walking

i receive a 'unsupported URL' error. What is the correct way to add multiple waypoints? Thanks

2

There are 2 answers

0
user3182143 On

I give you the solution step by step

First we should get the Google Map SDK

Drag the following bundles into your project (when prompted, select Copy items if needed):

Subspecs/Base/Frameworks/GoogleMapsBase.framework
Subspecs/Maps/Frameworks/GoogleMaps.framework
Subspecs/Maps/Frameworks/GoogleMapsCore.framework

Right-click GoogleMaps.framework in your project, and select Show In Finder.

Drag the GoogleMaps.bundle from the Resources folder into your project. When prompted, ensure Copy items into destination group's folder is not selected.

Select your project from the Project Navigator, and choose your application's target.

Open the Build Phases tab, and within Link Binary with Libraries, add the following frameworks:

GoogleMapsBase.framework
GoogleMaps.framework
GoogleMapsCore.framework
GoogleMapsM4B.framework (Premium Plan customers only)
Accelerate.framework
CoreData.framework
CoreGraphics.framework
CoreLocation.framework
CoreText.framework
GLKit.framework
ImageIO.framework
libc++.tbd
libz.tbd
OpenGLES.framework
QuartzCore.framework
SystemConfiguration.framework
UIKit.framework

Now Get the API key

Now you need to add following things in Plist

enter image description here

AppDelegate.m

@import GoogleMaps;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
   [GMSServices provideAPIKey:@"YOUR API KEY"];
   return YES;
}

ViewController.h

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <GoogleMaps/GoogleMaps.h>


@interface ViewController : UIViewController<CLLocationManagerDelegate,GMSMapViewDelegate>{
    CLLocation *currentLocation;
}

@property (strong, nonatomic) IBOutlet UIView *viewMarker;
@property (nonatomic, strong) CLLocationManager *locationManager;
@property (nonatomic, strong) GMSMapView *mapView;
@end

ViewController.m

#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
@synthesize viewMarker,locationManager,
@synthesize mapView;

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    locationManager = [[CLLocationManager alloc]init];
    locationManager.delegate = self;
    locationManager.distanceFilter = 10;
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    if([CLLocationManager locationServicesEnabled] == NO){
        NSLog(@"Your location service is not enabled, So go to Settings > Location Services");
    }
    else{
        NSLog(@"Your location service is enabled");
    }
    if ([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
       [locationManager requestWhenInUseAuthorization];
    }
    [locationManager startUpdatingLocation];
}

#pragma mark - CLLocationManagerDelegate method
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
    currentLocation = [locations lastObject];
    if (currentLocation != nil){
        NSLog(@"The latitude value is - %@",[NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude]);
        NSLog(@"The logitude value is - %@",[NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude]);
    }
    //Current
    GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:currentLocation.coordinate.latitude longitude: currentLocation.coordinate.longitude zoom:13];

    self.mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
    self.mapView.myLocationEnabled = YES;
    self.mapView.delegate = self;
    self.mapView.frame = viewMarker.bounds;
    [viewMarker addSubview:self.mapView];

    GMSMarker *marker1 = [[GMSMarker alloc] init];
    //Current
    marker1.position = CLLocationCoordinate2DMake(currentLocation.coordinate.latitude, currentLocation.coordinate.longitude);
    marker1.icon = [UIImage imageNamed:@"boss-icon.png"];
    marker1.map = self.spyMapView;

    NSArray *arrLatLongValue = @[
                                 @{
                                     @"Latitude":@"12.9003",
                                     @"Longitude":@"80.2278"
                                     },
                                 @{
                                     @"Latitude":@"12.8447",
                                     @"Longitude":@"80.2254"
                                     },
                                 @{
                                     @"Latitude":@"12.7726",
                                     @"Longitude":@"80.2488"
                                     },
                                 @{
                                     @"Latitude":@"12.9171",
                                     @"Longitude":@"80.1923"
                                     }
                                 ];

    NSString *strWayPoints = [NSString stringWithFormat:@"via:%f,%f", [arrLatLongValue[0][@"Latitude"] doubleValue], [arrLatLongValue[0][@"Longitude"] doubleValue]];
    for(int j=0;j<arrLatLongValue.count;j++){
        CLLocationCoordinate2D position = { [[arrLatLongValue[j] objectForKey:@"Latitude"] doubleValue], [[arrLatLongValue[j] objectForKey:@"Longitude"] doubleValue] };
        GMSMarker *marker = [GMSMarker markerWithPosition:position];
        marker.title = [NSString stringWithFormat:@"Marker %i", j];
        marker.appearAnimation = YES;
        marker.flat = YES;
        if(j < 2)
            marker.icon = [GMSMarker markerImageWithColor:[UIColor redColor]];
        else if(j >= 2 && j < 4)
            marker.icon = [GMSMarker markerImageWithColor:[UIColor purpleColor]];
        else
            marker.icon = [GMSMarker markerImageWithColor:[UIColor greenColor]];

        if(j > 0)
            strWayPoints = [NSString stringWithFormat:@"%@|via:%f,%f", strWayPoints, [arrLatLongValue[j][@"Latitude"] doubleValue], [arrLatLongValue[j][@"Longitude"] doubleValue]];

        marker.map = self.mapView;
    }
    //Current
    NSString *originString = [NSString stringWithFormat:@"%f,%f",currentLocation.coordinate.latitude, currentLocation.coordinate.longitude];


    NSString *destinationString = [NSString stringWithFormat:@"%f,%f", @(12.9220085).doubleValue, @(80.0954032).doubleValue]; 

    NSString *str = [NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/directions/json?origin=%@&destination=%@&waypoints=%@&key=YOUR API KEY",originString,destinationString,strWayPoints];
    NSURL *url=[[NSURL alloc]initWithString:[str stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]];
    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
    NSURLSessionDataTask * dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if(data == nil) {
            return;
        }else{
            NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
            NSArray* latestRoutes = [json objectForKey:@"routes"];
            NSString *points=[[[latestRoutes objectAtIndex:0] objectForKey:@"overview_polyline"] objectForKey:@"points"];
            @try {
                // TODO: better parsing. Regular expression?
                NSArray *temp= [self decodePolyLine:[points mutableCopy]];
                GMSMutablePath *path = [GMSMutablePath path];
                for(int idx = 0; idx < [temp count]; idx++){
                    CLLocation *location=[temp objectAtIndex:idx];
                    [path addCoordinate:location.coordinate];
                }
                // create the polyline based on the array of points.
                GMSPolyline *rectangle = [GMSPolyline polylineWithPath:path];
                rectangle.strokeWidth=5.0;
                rectangle.map = self.spyMapView;
                [locationManager stopUpdatingLocation];
            }
            @catch (NSException * e) {
                // TODO: show erro
            }
        }
    }];
    [dataTask resume];
    }
    [locationManager stopUpdatingLocation];
}

pragma mark - Drawing Lines

-(NSMutableArray *)decodePolyLine: (NSMutableString *)encoded {
    [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] ;
        printf("[%f,", [latitude doubleValue]);
        printf("%f]", [longitude doubleValue]);
        CLLocation *loc = [[CLLocation alloc] initWithLatitude:[latitude floatValue] longitude:[longitude floatValue]] ;
        [array addObject:loc];
    }

    return array;
}
0
Praveen Sharma On

Its very simple, Just replace '|' with '%7C'

Your updated url will be :

https://maps.googleapis.com/maps/api/directions/json?&origin=51.606502,0.527309&waypoints=51.507679,-0.125004%7C51.524151,-0.123174&destination=51.495777,-0.108642&mode=walking

Happy Coding