如何在iOS中的两个位置之间获取路由?

时间:2015-09-10 05:30:24

标签: ios swift google-maps

我想使用Google API在两个CLLocationCoordinates之间绘制路线。目前我正在使用“iOS8 Day-by-Day :: Day 14 :: Rotation Deprecation?”有起源和目的地,这不是我想要做的。我想传递我的位置而不是位置名称,然后制作路线。

先谢谢。

4 个答案:

答案 0 :(得分:2)

我关注了Google地图SDK的THIS教程。在该教程中,路由用户必须将位置名称添加到alertView。但我对代码进行了一些修改,因此您可以直接从使用当前位置获取路由到输入目的地位置。

首先以observeValueForKeyPath方式从用户的当前位置获取位置名称:

var currentLocationName = String()
override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {
    if !didFindMyLocation {
        let myLocation: CLLocation = change[NSKeyValueChangeNewKey] as! CLLocation
        let geoCoder = CLGeocoder()
        let location = CLLocation(latitude: myLocation.coordinate.latitude, longitude: myLocation.coordinate.longitude)

        geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in
            let placeArray = placemarks as? [CLPlacemark]

            // Place details
            var placeMark: CLPlacemark!
            placeMark = placeArray?[0]

            // Address dictionary
            println(placeMark.addressDictionary)

            // Location name
            if let locationName = placeMark.addressDictionary["Name"] as? NSString {
                println(locationName)
            }

            // Street address
            if let street = placeMark.addressDictionary["Thoroughfare"] as? NSString {
                println(street)
            }

            // City
            if let city = placeMark.addressDictionary["City"] as? NSString {
                //get city name.
                self.currentLocationName = city as String
                println(city)
            }

            // Zip code
            if let zip = placeMark.addressDictionary["ZIP"] as? NSString {
                println(zip)
            }

            // Country
            if let country = placeMark.addressDictionary["Country"] as? NSString {
                println(country)
            }

        })
        viewMap.camera = GMSCameraPosition.cameraWithTarget(myLocation.coordinate, zoom: 10.0)
        viewMap.settings.myLocationButton = true

        didFindMyLocation = true
    }
}

现在在createRoute方法中,将这个城市名称或者您想要的内容命名为:

@IBAction func createRoute(sender: AnyObject) {

    let addressAlert = UIAlertController(title: "Create Route", message: "Connect locations with a route:", preferredStyle: UIAlertControllerStyle.Alert)

    addressAlert.addTextFieldWithConfigurationHandler { (textField) -> Void in
        //give a origin for route
        textField.text = self.currentLocationName
        textField.userInteractionEnabled = false
    }

    addressAlert.addTextFieldWithConfigurationHandler { (textField) -> Void in
        textField.placeholder = "Destination?"
    }


    let createRouteAction = UIAlertAction(title: "Create Route", style: UIAlertActionStyle.Default) { (alertAction) -> Void in
        let origin = (addressAlert.textFields![0] as! UITextField).text as String
        let destination = (addressAlert.textFields![1] as! UITextField).text as String

        self.mapTasks.getDirections(origin, destination: destination, waypoints: nil, travelMode: nil, completionHandler: { (status, success) -> Void in
            if success {
                self.configureMapAndMarkersForRoute()
                self.drawRoute()
                self.displayRouteInfo()
            }
            else {
                println(status)
            }
        })
    }

    let closeAction = UIAlertAction(title: "Close", style: UIAlertActionStyle.Cancel) { (alertAction) -> Void in

    }

    addressAlert.addAction(createRouteAction)
    addressAlert.addAction(closeAction)

    presentViewController(addressAlert, animated: true, completion: nil)
}

希望它有所帮助。

答案 1 :(得分:1)

我从这里使用了一个MapKit包装器 - https://github.com/varshylmobile/MapManager

这个包装器提供了几个类,如

directionsUsingGoogle(#from:NSString, to:NSString,directionCompletionHandler:DirectionsCompletionHandler)

directionsUsingGoogle(#from:CLLocationCoordinate2D, to:CLLocationCoordinate2D,directionCompletionHandler:DirectionsCompletionHandler)

directionsUsingGoogle(#from:CLLocationCoordinate2D, to:NSString,directionCompletionHandler:DirectionsCompletionHandler)

您可以在此处通过上述方法中的CLLocationCoordinate2D

答案 2 :(得分:1)

- (void)pathCall {
    if ([_txtAddressCity.text isEqualToString:@""] || [_txtaddressNumber.text isEqualToString:@""] || [_txtAddressState.text isEqualToString:@""] ||
        [_txtAddressStreet.text isEqualToString:@""] || [_txtAddressZip.text isEqualToString:@""])
    {
        //[PCToastMessage toastWithDuration:2.0 andText:NSLocalizedString(@"All fields are compulsory in location.",Nil) inView:self.view];
        return ;
    }
    else
    {
        _endingAddress=[[NSMutableString alloc] initWithString:_txtaddressNumber.text];
        [_endingAddress appendString:[NSString stringWithFormat:@",+%@",_txtAddressStreet.text]];
        [_endingAddress appendString:[NSString stringWithFormat:@",+%@",_txtAddressCity.text]];
        [_endingAddress appendString:[NSString stringWithFormat:@",+%@",_txtAddressState.text]];
        [_endingAddress appendString:[NSString stringWithFormat:@",+%@",_txtAddressZip.text]];
        [_endingAddress appendString:[_endingAddress stringByReplacingOccurrencesOfString:@" " withString: @"+"]];

        NSMutableString *mode= [[NSMutableString alloc]init];
        if (_selectedRowOfPicker==1 || _selectedRowOfPicker==0) {
            [mode appendString:@"driving"];
        }
        else if(_selectedRowOfPicker==2)
        {
            [mode appendString:@"bicycling"];
        }
        else if(_selectedRowOfPicker==3)
        {
            [mode appendString:@"walking"];
        }

       NSURL *url=[[NSURL alloc] initWithString:[NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/directions/json?origin=%@&destination=%@&mode=%@",[_startingAddress stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],[_endingAddress stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],mode]];

        NSURLResponse *res;
        NSError *err;
        NSData *data=[NSURLConnection sendSynchronousRequest:[[NSURLRequest alloc] initWithURL:url] returningResponse:&res error:&err];
        NSDictionary *dic=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];

        NSMutableArray *totalSeconds;
        totalSeconds = [[NSMutableArray alloc]init];

        NSArray *routes=dic[@"routes"];
        path1 = [GMSMutablePath path];

        if (routes.count != 0) {
            NSArray *legs=routes[0][@"legs"];
            NSArray *steps=legs[0][@"steps"];
            NSDictionary *duration=legs[0][@"duration"];
            NSString *totalSeconds = [duration valueForKey:@"value"];
            NSDictionary *start_address=legs[0][@"start_location"];
            NSDictionary *end_address=legs[0][@"end_location"];
            source.latitude = [[start_address valueForKey:@"lat"] doubleValue];
            source.longitude = [[start_address valueForKey:@"lng"] doubleValue];
            dest.latitude = [[end_address valueForKey:@"lat"] doubleValue];
            dest.longitude = [[end_address valueForKey:@"lng"] doubleValue];
            NSMutableArray *textsteps=[[NSMutableArray alloc] init];
            NSMutableArray *latlong=[[NSMutableArray alloc]init];
            for(int i=0; i< [steps count]; i++){

                NSString *html=steps[i][@"html_instructions"];
                [latlong addObject:steps[i][@"end_location"]];
                [textsteps addObject:html];
                NSString *polyLinePoints = [[steps[i] objectForKey:@"polyline"] objectForKey:@"points"];
                GMSPath *polyLinePath = [GMSPath pathFromEncodedPath:polyLinePoints];
                for (int p=0; p<polyLinePath.count; p++) {
                    [path1 addCoordinate:[polyLinePath coordinateAtIndex:p]];
                }
            }
            self.detailedSteps=textsteps;
            [self showDirection:latlong];

            [_lblJourneyHours setTextColor:[UIColor colorWithWhite:0.33 alpha:1.0]];
            _lblJourneyHours.text = [NSString stringWithFormat:@"%.02f", ([totalSeconds floatValue]/60)/60];
        }
        else
        {
            _lblJourneyHours.textColor = [UIColor redColor];
            _lblJourneyHours.text = @"No route found.";
        }
    }
}
-(void)showDirection:(NSMutableArray*) latlong{
    path = [GMSMutablePath path];
    bounds = [[GMSCoordinateBounds alloc] init];
    if (latlong.count !=0) {
        for(int i=0; i<[latlong count]; i++){
            double lat=[latlong[i][@"lat"] doubleValue];
            double lng=[latlong[i][@"lng"] doubleValue];
            CLLocationCoordinate2D temp;
            temp.latitude=lat;
            temp.longitude=lng;
            bounds = [bounds includingCoordinate:temp];
            [path addLatitude:lat longitude:lng];
        }
    }
}
- (IBAction)showMAP:(UIButton *)sender {
    [self hideKeyboard];

    if ([_txtAddressCity.text isEqualToString:@""] || [_txtaddressNumber.text isEqualToString:@""] || [_txtAddressState.text isEqualToString:@""] ||
        [_txtAddressStreet.text isEqualToString:@""] || [_txtAddressZip.text isEqualToString:@""])
    {
        [PCToastMessage toastWithDuration:2.0 andText:NSLocalizedString(@"All fields are compulsory in location.",Nil) inView:self.view];
        return ;
    }
    if ([_lblJourneyHours.text isEqualToString:@"No route found."])
    {
        [PCToastMessage toastWithDuration:2.0 andText:NSLocalizedString(@"No route found.",Nil) inView:self.view];
        return ;
    }
    else
    {
        _mapButton.userInteractionEnabled = NO;
        popUp = [[UIView alloc]initWithFrame:CGRectMake(self.view.frame.origin.x,0, self.view.frame.size.width, self.view.frame.size.height)];
        GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:source.latitude longitude:source.longitude zoom:7];//23.0300° N, 72.5800° E
        mapView = [GMSMapView mapWithFrame:CGRectMake(popUp.frame.origin.x+10, popUp.frame.origin.y+10, popUp.frame.size.width-20, popUp.frame.size.height-20) camera:camera];
        [mapView animateWithCameraUpdate:[GMSCameraUpdate fitBounds:bounds withPadding:30.0f]];
        popUp.backgroundColor = [UIColor whiteColor];
        popUp.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.001, 0.001);
        [self.view addSubview:popUp];

        GMSPolyline *polyline = [GMSPolyline polylineWithPath:path1];
        polyline.strokeColor = [UIColor blueColor];
        polyline.strokeWidth = 3.f;
        mapView.myLocationEnabled=YES;
        polyline.map =mapView ;

        GMSMarker *marker=[[GMSMarker alloc]init];
        marker.position=CLLocationCoordinate2DMake(source.latitude, source.longitude);
        marker.groundAnchor=CGPointMake(0.52,0.8);

        GMSMarker *marker2=[[GMSMarker alloc]init];
        marker2.position=CLLocationCoordinate2DMake(dest.latitude, dest.longitude);
        marker2.groundAnchor=CGPointMake(0.52,0.8);
        marker.map=mapView;
        marker2.map=mapView;
        [popUp addSubview:mapView];
        UIButton *closeMap = [[UIButton alloc]initWithFrame:CGRectMake(mapView.frame.size.width-17,mapView.frame.origin.y-6 , 35, 35)];
        [closeMap setBackgroundImage:[UIImage imageNamed:@"cross.png"] forState:UIControlStateNormal];
        closeMap.backgroundColor = [UIColor clearColor];
        [closeMap addTarget:self action:@selector(closeMapAction)forControlEvents:UIControlEventTouchUpInside];
        [popUp addSubview:closeMap];

        [UIView animateWithDuration:0.3/1.5 animations:^{
            popUp.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.1, 1.1);
        } completion:^(BOOL finished) {
            [UIView animateWithDuration:0.3 animations:^{
                popUp.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.9, 0.9);
            } completion:^(BOOL finished) {
                [UIView animateWithDuration:0.1 animations:^{
                    popUp.transform = CGAffineTransformIdentity;
                    _mapButton.userInteractionEnabled = YES;
                }];
            }];
        }];
    }
}

答案 3 :(得分:1)

您可以将lat long转换为给定格式,然后调用Google Directions API获取完整路线 -

let originLat: String = String(format: "%f",self.currentLocation!.coordinate.latitude)
    let originLong: String = String(format: "%f", self.currentLocation!.coordinate.longitude)
    let destLat: String = String(format: "%f", self.destinationLocation!.coordinate.latitude)
    let destLong: String = String(format: "%f", self.destinationLocation!.coordinate.longitude)

    let origin: String = "\(originLat), \(originLong)"
    let destination: String = "\(destLat), \(destLong)"


var params: [String: String] = [:]

    params.updateValue("YOUR_GOOGLE_API_KEY", forKey: "key")
    //        params.updateValue("50000", forKey: "radius")
    params.updateValue("driving", forKey: "mode")
    params.updateValue(origin, forKey: "origin")
    params.updateValue(destination, forKey: "destination")
    params.updateValue("best_guess", forKey: "traffic_model")
    params.updateValue("imperial", forKey: "units")

    let departureTime = NSDate().timeIntervalSince1970
    params.updateValue(String(format:"%.0f", departureTime), forKey: "departure_time")

    let pm = setGetParameters(params)
    let method = "GET"

    let finalUrl = "https://maps.googleapis.com/maps/api/directions/json?\(pm)"
    NSLog("Url for directions call - \(finalUrl)")

    // Create URL Request
    var request: NSMutableURLRequest!

    let urlStr : NSString = finalUrl.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
    let nsUrl: NSURL = NSURL(string: urlStr as String)!

    request = NSMutableURLRequest(URL: nsUrl)
    request.HTTPMethod = method
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.setValue("application/json", forHTTPHeaderField: "Accept")
    request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData

    let session = NSURLSession.sharedSession()

    let task = session.dataTaskWithRequest(request) {
        (data, response, error) -> Void in

        // Handle incoming data like you would in synchronous request
        NSLog("Got response from Get Directions API")
        callBack(data: data, response: response, error: error)
    }

    task.resume()