Google Maps iOS SDK, Getting Directions between 2 locations

我是研究僧i 提交于 2019-11-27 10:48:41

It sounds like you are looking for UI Chrome like the Google Maps app has for showing directions. Google Maps SDK for iOS will paint you a map, but you are responsible for the additional navigation chrome.

You can use the Google Directions API to request directions, and then use the encoded path returned from the service to draw a GMSPolyline using GMSPath's pathFromEncodedPath: method.

    NSString *urlString = [NSString stringWithFormat:
                       @"%@?origin=%f,%f&destination=%f,%f&sensor=true&key=%@",
                       @"https://maps.googleapis.com/maps/api/directions/json",
                       mapView.myLocation.coordinate.latitude,
                       mapView.myLocation.coordinate.longitude,
                       destLatitude,
                       destLongitude,
                       @"Your Google Api Key String"];
NSURL *directionsURL = [NSURL URLWithString:urlString];


ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:directionsURL];
[request startSynchronous];
NSError *error = [request error];
if (!error) {
    NSString *response = [request responseString];
    NSLog(@"%@",response);
    NSDictionary *json =[NSJSONSerialization JSONObjectWithData:[request responseData] options:NSJSONReadingMutableContainers error:&error];
    GMSPath *path =[GMSPath pathFromEncodedPath:json[@"routes"][0][@"overview_polyline"][@"points"]];
    GMSPolyline *singleLine = [GMSPolyline polylineWithPath:path];
    singleLine.strokeWidth = 7;
    singleLine.strokeColor = [UIColor greenColor];
    singleLine.map = self.mapView;
}
else NSLog(@"%@",[request error]);

Note: make Sure Your Google Direction API Sdk Is Enable in Your google developer Console.

These lines shows location between a given latitude / longitude and user location;

NSString *googleMapUrlString = [NSString stringWithFormat:@"http://maps.google.com/?saddr=%f,%f&daddr=%@,%@", mapView.userLocation.coordinate.latitude, mapView.userLocation.coordinate.longitude, destinationLatitude, destinationLongtitude];

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:googleMapUrlString]];

I had done it as it also shows PINS DISTANCE AND DURATION on map with DIRECTION ROUTE. But dont forget to set your GOOGLE DIRECTION API TO ENABLED in your GOOGLE DEVELOPER CONSOLE

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager.requestSerializer setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];

NSString *urlString =@"https://maps.googleapis.com/maps/api/directions/json";

 NSDictionary *dictParameters = @{@"origin" : [NSString stringWithFormat:@"%@",_sourceAdd], @"destination" : [NSString stringWithFormat:@"%@",_destinationAdd], @"mode" : @"driving", @"key":@"AIzaSyD9cWTQkAxemELVXTNUCALOmzlDv5b9Dhg"};

[manager GET:urlString parameters:dictParameters success:^(AFHTTPRequestOperation *operation, id responseObject) {


    GMSPath *path =[GMSPath pathFromEncodedPath:responseObject[@"routes"][0][@"overview_polyline"][@"points"]];
    NSDictionary *arr=responseObject[@"routes"][0][@"legs"];
    NSMutableArray *loc=[[NSMutableArray alloc]init];

    loc=[[arr valueForKey:@"start_location"]valueForKey:@"lat"];
    _sourceloc.latitude=[loc[0] doubleValue];

    loc=[[arr valueForKey:@"start_location"]valueForKey:@"lng"];
    _sourceloc.longitude=[loc[0] doubleValue];

    loc=[[arr valueForKey:@"end_location"]valueForKey:@"lat"];
    _destinationloc.latitude=[loc[0] doubleValue];

    loc=[[arr valueForKey:@"end_location"]valueForKey:@"lng"];
    _destinationloc.longitude=[loc[0] doubleValue];


    NSString *dis,*dur;
    loc=[[arr valueForKey:@"distance"]valueForKey:@"text"];
    dis=loc[0];

    loc=[[arr valueForKey:@"duration"]valueForKey:@"text"];
    dur=loc[0];


    NSString *sa,*da;
    loc=[arr valueForKey:@"start_address"];
    sa=loc[0];

    loc=[arr valueForKey:@"end_address"];
    da=loc[0];

    UIAlertView *av=[[UIAlertView alloc]initWithTitle:@"Route Info" message:[NSString stringWithFormat:@"Distance:%@ \nDuration:%@",dis,dur] delegate:nil cancelButtonTitle:@"Okay" otherButtonTitles:nil, nil];
    [av show];



    GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:_sourceloc.latitude  longitude:_sourceloc.longitude zoom:10];
    mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];

    GMSMarker *marker = [GMSMarker markerWithPosition:_sourceloc];
    marker.title=@"Source";
    marker.snippet =sa;
    marker.appearAnimation = kGMSMarkerAnimationPop;
    marker.map = mapView;


    GMSMarker *marker2 = [GMSMarker markerWithPosition:_destinationloc];
    marker2.title=@"Destination";
    marker2.snippet =da;
    marker2.appearAnimation = kGMSMarkerAnimationPop;
    marker2.map = mapView;

    GMSPolyline *singleLine = [GMSPolyline polylineWithPath:path];
    singleLine.strokeWidth = 4;
    singleLine.strokeColor = [UIColor blueColor];
    singleLine.map = mapView;

    self.view = mapView;



} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];

Swift 3.0 & XCode 8.0 Using AFNetworking & SwiftJson

        let destLatitude="26.9124"
        let destLongitude="75.7873"
        mapView.isMyLocationEnabled = true
        var urlString = "\("https://maps.googleapis.com/maps/api/directions/json")?origin=\("28.7041"),\("77.1025")&destination=\(destLatitude),\(destLongitude)&sensor=true&key=\("Your-Api-key")"

        urlString = urlString.addingPercentEncoding( withAllowedCharacters: .urlQueryAllowed)!

        let manager=AFHTTPRequestOperationManager()

        manager.responseSerializer = AFJSONResponseSerializer(readingOptions: JSONSerialization.ReadingOptions.allowFragments) as AFJSONResponseSerializer

        manager.requestSerializer = AFJSONRequestSerializer() as AFJSONRequestSerializer

        manager.responseSerializer.acceptableContentTypes = NSSet(objects:"application/json", "text/html", "text/plain", "text/json", "text/javascript", "audio/wav") as Set<NSObject>


        manager.post(urlString, parameters: nil, constructingBodyWith: { (formdata:AFMultipartFormData!) -> Void in

            }, success: {  operation, response -> Void in
                //{"responseString" : "Success","result" : {"userId" : "4"},"errorCode" : 1}
                //if(response != nil){
                let parsedData = JSON(response)
                print_debug("parsedData : \(parsedData)")
               var path = GMSPath.init(fromEncodedPath: parsedData["routes"][0]["overview_polyline"]["points"].string!)
                 //GMSPath.fromEncodedPath(parsedData["routes"][0]["overview_polyline"]["points"].string!)
                var singleLine = GMSPolyline.init(path: path)
                singleLine.strokeWidth = 7
                singleLine.strokeColor = UIColor.green
                singleLine.map = self.mapView
                //let loginResponeObj=LoginRespone.init(fromJson: parsedData)


                //  }
            }, failure: {  operation, error -> Void in

                print_debug(error)
                let errorDict = NSMutableDictionary()
                errorDict.setObject(ErrorCodes.errorCodeFailed.rawValue, forKey: ServiceKeys.keyErrorCode.rawValue as NSCopying)
                errorDict.setObject(ErrorMessages.errorTryAgain.rawValue, forKey: ServiceKeys.keyErrorMessage.rawValue as NSCopying)

        })

Swift 4.1, Xcode 9.4.1

//Here you need to set your origin and destination points and mode 
let url = NSURL(string: "https://maps.googleapis.com/maps/api/directions/json?origin=Machilipatnam&destination=Vijayawada&mode=driving")

//OR if you want to use latitude and longitude for source and destination
//let url = NSURL(string: "\("https://maps.googleapis.com/maps/api/directions/json")?origin=\("17.521100"),\("78.452854")&destination=\("15.1393932"),\("76.9214428")")

        let task = URLSession.shared.dataTask(with: url! as URL) { (data, response, error) -> Void in

            do {
                if data != nil {
                    let dic = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableLeaves) as!  [String:AnyObject]
//                        print(dic)

                    let status = dic["status"] as! String
                    var routesArray:String!
                    if status == "OK" {
                        routesArray = (((dic["routes"]!as! [Any])[0] as! [String:Any])["overview_polyline"] as! [String:Any])["points"] as! String
//                            print("routesArray: \(String(describing: routesArray))")
                    }

                    DispatchQueue.main.async {
                        let path = GMSPath.init(fromEncodedPath: routesArray!)
                        let singleLine = GMSPolyline.init(path: path)
                        singleLine.strokeWidth = 6.0
                        singleLine.strokeColor = .blue
                        singleLine.map = mapView
                    }

                }
            } catch {
                print("Error")
            }
        }

        task.resume()

Here, you need to add your key (google api key) to the above API.

Navneet Singh Rana
(void)viewDidLoad {
    [super viewDidLoad];

    GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:30.692408
                                                            longitude:76.767556
                                                                 zoom:14];
    GMSMapView *mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
    mapView.myLocationEnabled = YES;

    // Creates  markers in the center of the map.


    GMSMarker *marker = [[GMSMarker alloc] init];
    marker.position = CLLocationCoordinate2DMake(30.6936659,  76.77201819999999);
    marker.title = @"Chandigarh 47c";
    marker.snippet = @"Hello World";
    marker.map = mapView;

    GMSMarker *marker1 = [[GMSMarker alloc] init];
    marker1.position = CLLocationCoordinate2DMake(30.742138,  76.818756);
    marker1.title = @"Sukhna Lake";
    marker1.map = mapView;
    //creating a path

    GMSMutablePath *path = [GMSMutablePath path];
    [path addCoordinate:CLLocationCoordinate2DMake(@(30.6936659).doubleValue,@(76.77201819999999).doubleValue)];
    [path addCoordinate:CLLocationCoordinate2DMake(@(30.742138).doubleValue,@(76.818756).doubleValue)];

    GMSPolyline *rectangle = [GMSPolyline polylineWithPath:path];
    rectangle.strokeWidth = 2.f;
    rectangle.map = mapView;
    self.view=mapView;

 }

Create a key in google developer console make sure your project is created with App bundleID after that add the following code

NSString *KEY=@"";
NSString *Origin=@"";
NSString *Destination=@"";
NSString *str_maps=[NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/directions/json?origin=%@&destination=%@&key=%@",Origin,Destination,KEY];
NSURL *url=[NSURL URLWithString:str_maps];
 NSData *dta=[NSData dataWithContentsOfURL:url];
NSDictionary *dict=(NSDictionary *)[NSJSONSerialization JSONObjectWithData:dta options:kNilOptions error:nil];
NSLog(@"%@",dict);

Using Swift I definitely solved in this way.
My purpose was finding distance between two coordinates:

import AFNetworking 

/**
 Calculate distance between two valid coordinates

 - parameter origin:      origin coordinates
 - parameter destination: destination coordinates
 - parameter completion:  completion callback
 */
func calculateDistance(origin origin: CLLocation, destination: CLLocation, completion: (distance: Double?) -> Void) {

    let service = "https://maps.googleapis.com/maps/api/directions/json"
    let originLat = origin.coordinate.latitude
    let originLong = origin.coordinate.longitude
    let destLat = destination.coordinate.latitude
    let destLong = destination.coordinate.longitude
    let urlString = "\(service)?origin=\(originLat),\(originLong)&destination=\(destLat),\(destLong)&mode=driving&units=metric&sensor=true&key=<YOUR_KEY>"
    let directionsURL = NSURL(string: urlString)

    let request = NSMutableURLRequest(URL: directionsURL!)

    request.HTTPMethod = "GET"
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")
    let operation = AFHTTPRequestOperation(request: request)
    operation.responseSerializer = AFJSONResponseSerializer()

    operation.setCompletionBlockWithSuccess({ (operation: AFHTTPRequestOperation!, responseObject: AnyObject!) -> Void in

        if let result = responseObject as? NSDictionary {
            if let routes = result["routes"] as? [NSDictionary] {
                if let lines = routes[0]["overview_polyline"] as? NSDictionary {
                    if let points = lines["points"] as? String {
                        let path = GMSPath(fromEncodedPath: points)
                        let distance = GMSGeometryLength(path)
                        print("wow \(distance / 1000) KM")

                    }
                }
            }
        }
        }) { (operation: AFHTTPRequestOperation!, error: NSError!)  -> Void in
            print("\(error)")
    }

    operation.start()

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!