【问题标题】:How to get route between two locations in iOS?如何在iOS中的两个位置之间获取路线?
【发布时间】:2015-09-10 05:30:24
【问题描述】:

我想使用 Google API 在两个 CLLocationCoordinates 之间绘制路线。目前我正在使用“https://maps.googleapis.com/maps/api/directions/json?”有出发地和目的地,这不是我想要做的。我想传递我的位置而不是位置名称,然后制定路线。

提前致谢。

【问题讨论】:

    标签: ios swift google-maps


    【解决方案1】:

    我遵循了THIS Google Maps SDK 教程。并且在该路线用户教程中,必须将两个位置名称都添加到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)
    }
    

    希望对你有帮助。

    【讨论】:

      【解决方案2】:

      我从这里使用了 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

      【讨论】:

      • 虽然这段代码一定可以正常工作,但不是我正在寻找的情况。我仍然赞成您的回答,因为您试图帮助我的朋友。干杯:)
      • 我不明白为什么它不能帮助你,你必须在其中传递CLLocationCoordinates,它会使用这个方法directionsUsingGoogle(#from:CLLocationCoordinate2D, to:CLLocationCoordinate2D,directionCompletionHandler:DirectionsCompletionHandler)从这两个CLLocationCoordinates中绘制路线,或者你有没有其他要求?
      • 我也必须清除这条路。我无法清除这一点,不得不做出很多改变。然而,我找到了另一种方法。我用你的方法做了一个自己的类,并按原样使用了你的大量代码
      【解决方案3】:
      - (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;
                      }];
                  }];
              }];
          }
      }
      

      【讨论】:

      • 你只需要做一些小的改变。
      • 首先导入@import GoogleMaps;为此,您必须集成 google map SDK .. 只需访问此链接 developers.google.com/maps/documentation/ios-sdk/start
      • 我已经完成了所有这些。我要做的就是通过向其发送坐标来创建路径。
      • 那么只要看看上面的代码,你就会得到一切。它在我的应用中完美运行
      【解决方案4】:

      您可以将 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()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-19
        • 1970-01-01
        • 1970-01-01
        • 2014-01-21
        • 1970-01-01
        • 1970-01-01
        • 2012-03-06
        • 1970-01-01
        相关资源
        最近更新 更多