在iOS中的GMSMapView上绘制两个位置之间的路线

在iOS中的GMSMapView上绘制两个位置之间的路线,ios,google-maps,ios7,google-polyline,gmsmapview,Ios,Google Maps,Ios7,Google Polyline,Gmsmapview,我正在开发一个iOS应用程序。在该应用程序中,我有两个字段From和To。我使用谷歌自动完成API输入了地址。我还能够获得这两个地方的纬度和经度,并能够在GMSMapView上显示标记 现在我想画这两个地方之间的路线。当我们使用MKMapView时,我找到了一个解决方案。但是我无法找到GMSMapView的解决方案。请帮助我在GMSMapView中绘制这两点之间的路线 如果可能的话,请给我一些重要的链接 谢谢。向Google Directions API发出URL请求,当您收到JSON文件时,完

我正在开发一个iOS应用程序。在该应用程序中,我有两个字段From和To。我使用谷歌自动完成API输入了地址。我还能够获得这两个地方的纬度和经度,并能够在
GMSMapView
上显示标记

现在我想画这两个地方之间的路线。当我们使用
MKMapView
时,我找到了一个解决方案。但是我无法找到
GMSMapView
的解决方案。请帮助我在
GMSMapView
中绘制这两点之间的路线

如果可能的话,请给我一些重要的链接


谢谢。

向Google Directions API发出URL请求,当您收到JSON文件时,完成所有步骤并解码points对象。

您好,您可以使用“LRoutController”,这是显示两点之间道路路线的最佳方式,如:

`first get all points coordinates which are coming in route then add these points latitude and longitude in path in will draw path according to that`


GMSCameraPosition *cameraPosition=[GMSCameraPosition cameraWithLatitude:18.5203 longitude:73.8567 zoom:12];
_mapView =[GMSMapView mapWithFrame:CGRectZero camera:cameraPosition];
_mapView.myLocationEnabled=YES;
GMSMarker *marker=[[GMSMarker alloc]init];
marker.position=CLLocationCoordinate2DMake(18.5203, 73.8567);
marker.icon=[UIImage imageNamed:@"aaa.png"] ;
marker.groundAnchor=CGPointMake(0.5,0.5);
marker.map=_mapView;
GMSMutablePath *path = [GMSMutablePath path];   
[path addCoordinate:CLLocationCoordinate2DMake(@(18.520).doubleValue,@(73.856).doubleValue)];
[path addCoordinate:CLLocationCoordinate2DMake(@(16.7).doubleValue,@(73.8567).doubleValue)];

GMSPolyline *rectangle = [GMSPolyline polylineWithPath:path];
rectangle.strokeWidth = 2.f;
rectangle.map = _mapView;
self.view=_mapView;
[_routeController getPolyline With Locations: (Array of first and last location)]

试试看,我希望它能解决您的问题。

我已经编写了以下代码,可以帮您解决问题:

- (void)drawRoute
{
    [self fetchPolylineWithOrigin:myOrigin destination:myDestination completionHandler:^(GMSPolyline *polyline)
     {
         if(polyline)
             polyline.map = self.myMap;
     }];
}

- (void)fetchPolylineWithOrigin:(CLLocation *)origin destination:(CLLocation *)destination completionHandler:(void (^)(GMSPolyline *))completionHandler
{
    NSString *originString = [NSString stringWithFormat:@"%f,%f", origin.coordinate.latitude, origin.coordinate.longitude];
    NSString *destinationString = [NSString stringWithFormat:@"%f,%f", destination.coordinate.latitude, destination.coordinate.longitude];
    NSString *directionsAPI = @"https://maps.googleapis.com/maps/api/directions/json?";
    NSString *directionsUrlString = [NSString stringWithFormat:@"%@&origin=%@&destination=%@&mode=driving", directionsAPI, originString, destinationString];
    NSURL *directionsUrl = [NSURL URLWithString:directionsUrlString];


    NSURLSessionDataTask *fetchDirectionsTask = [[NSURLSession sharedSession] dataTaskWithURL:directionsUrl completionHandler:
         ^(NSData *data, NSURLResponse *response, NSError *error)
         {
             NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
             if(error)
             {
                 if(completionHandler)
                     completionHandler(nil);
                 return;
             }

             NSArray *routesArray = [json objectForKey:@"routes"];

             GMSPolyline *polyline = nil;
             if ([routesArray count] > 0)
             {
                 NSDictionary *routeDict = [routesArray objectAtIndex:0];
                 NSDictionary *routeOverviewPolyline = [routeDict objectForKey:@"overview_polyline"];
                 NSString *points = [routeOverviewPolyline objectForKey:@"points"];
                 GMSPath *path = [GMSPath pathFromEncodedPath:points];
                 polyline = [GMSPolyline polylineWithPath:path];
             }

             // run completionHandler on main thread                                           
             dispatch_sync(dispatch_get_main_queue(), ^{
                 if(completionHandler)
                      completionHandler(polyline);
             });
         }];
    [fetchDirectionsTask resume];
}

以下是约翰尼·库马尔答案的快速翻译

let cameraPositionCoordinates = CLLocationCoordinate2D(latitude: 18.5203, longitude: 73.8567)
    let cameraPosition = GMSCameraPosition.cameraWithTarget(cameraPositionCoordinates, zoom: 12)

    let mapView = GMSMapView.mapWithFrame(CGRectZero, camera: cameraPosition)
    mapView.myLocationEnabled = true

    let marker = GMSMarker()
    marker.position = CLLocationCoordinate2DMake(18.5203, 73.8567)
    marker.groundAnchor = CGPointMake(0.5, 0.5)
    marker.map = mapView

    let path = GMSMutablePath()
    path.addCoordinate(CLLocationCoordinate2DMake(18.520, 73.856))
    path.addCoordinate(CLLocationCoordinate2DMake(16.7, 73.8567))

    let rectangle = GMSPolyline(path: path)
    rectangle.strokeWidth = 2.0
    rectangle.map = mapView

    self.view = mapView
来自NSLogs的DirectionResponse可用于查看您正在使用的内容

[[GMDirectionService sharedInstance] getDirectionsFrom:origin to:destination          succeeded:^(GMDirection *directionResponse) {   
if ([directionResponse statusOK]){
    NSLog(@"Duration : %@", [directionResponse durationHumanized]);
    NSLog(@"Distance : %@", [directionResponse distanceHumanized]);
    NSArray *routes = [[directionResponse directionResponse] objectForKey:@"routes"];
    // NSLog(@"Route : %@", [[directionResponse directionResponse] objectForKey:@"routes"]);

    GMSPath *path = [GMSPath pathFromEncodedPath:routes[0][@"overview_polyline"]  [@"points"]];
    GMSPolyline *polyline = [GMSPolyline polylineWithPath:path];
    polyline.strokeColor = [UIColor redColor];
    polyline.strokeWidth = 5.f;
    polyline.map = mapView;

}
} failed:^(NSError *error) {
    NSLog(@"Can't reach the server")
}];

-Swift 3.0和XCode 8.0星光线:(


如果有人在为@Tarek的答案寻找Swift 3.0,你可以使用这个。这个也可以使用和


用于swift 3绘制多段线

func getPolylineRoute(from source: CLLocationCoordinate2D, to destination: CLLocationCoordinate2D){

        let config = URLSessionConfiguration.default
        let session = URLSession(configuration: config)

        let url = URL(string: "https://maps.googleapis.com/maps/api/directions/json?origin=\(source.latitude),\(source.longitude)&destination=\(destination.latitude),\(destination.longitude)&sensor=true&mode=driving&key=YOURKEY")!

        let task = session.dataTask(with: url, completionHandler: {
            (data, response, error) in
            if error != nil {
                print(error!.localizedDescription)
                self.activityIndicator.stopAnimating()
            }
            else {
                do {
                    if let json : [String:Any] = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any]{

                        guard let routes = json["routes"] as? NSArray else {
                            DispatchQueue.main.async {
                                self.activityIndicator.stopAnimating()
                            }
                            return
                        }

                        if (routes.count > 0) {
                            let overview_polyline = routes[0] as? NSDictionary
                            let dictPolyline = overview_polyline?["overview_polyline"] as? NSDictionary

                            let points = dictPolyline?.object(forKey: "points") as? String

                            self.showPath(polyStr: points!)

                            DispatchQueue.main.async {
                                self.activityIndicator.stopAnimating()

                                let bounds = GMSCoordinateBounds(coordinate: source, coordinate: destination)
                                let update = GMSCameraUpdate.fit(bounds, with: UIEdgeInsetsMake(170, 30, 30, 30))
                                self.mapView!.moveCamera(update)
                            }
                        }
                        else {
                            DispatchQueue.main.async {
                                self.activityIndicator.stopAnimating()
                            }
                        }
                    }
                }
                catch {
                    print("error in JSONSerialization")
                    DispatchQueue.main.async {
                        self.activityIndicator.stopAnimating()
                    }
                }
            }
        })
        task.resume()
    }

    func showPath(polyStr :String){
        let path = GMSPath(fromEncodedPath: polyStr)
        let polyline = GMSPolyline(path: path)
        polyline.strokeWidth = 3.0
        polyline.strokeColor = UIColor.red
        polyline.map = mapView // Your map view
    }

注意:您需要在URL中输入googleDirection API键。

我在xCode 8.3.3和Swift 3.1中使用了AlamoFire和SwiftyJson。 将路径的图形放在只需要两个参数的函数中

字符串原点示例“48.7788,9.22222” 以及字符串目标示例“49.3212232,8.334151”


正如你所知,从谷歌获取方向和路线不是免费的,去年谷歌改变了他们的api调用价格很多!因此它可能不适合所有人。因此,如果你拥有所有关键坐标,只想将它们连接在一起,你可以使用以下方法

-Swift 4扩展 使用坐标创建路径:

extension GMSMutablePath {
    convenience init(coordinates: [CLLocationCoordinate2D]) {
        self.init()
        for coordinate in coordinates {
            add(coordinate)
        }
    }
}
将路径添加到地图:

extension GMSMapView {
    func addPath(_ path: GMSPath, strokeColor: UIColor? = nil, strokeWidth: CGFloat? = nil, geodesic: Bool? = nil, spans: [GMSStyleSpan]? = nil) {
        let line = GMSPolyline(path: path)
        line.strokeColor = strokeColor ?? line.strokeColor
        line.strokeWidth = strokeWidth ?? line.strokeWidth
        line.geodesic = geodesic ?? line.geodesic
        line.spans = spans ?? line.spans
        line.map = self
    }
}
用法:

let path = GMSMutablePath(coordinates: [<#Coordinates#>])
mapView.addPath(path)
let path=GMSMutablePath(坐标:[])
mapView.addPath(路径)
  • 注意:你可以使用谷歌工具甚至谷歌本身创建一条与谷歌完全相同的线路,将其存储在某个地方,并根据需要提供给你的客户
    • Swift 5 这对我来说很好

      视图将出现

      self.drawMap(SourceCordinate: CLLocationCoordinate2D(latitude: lat, longitude: long), destinationcordinate: CLLocationCoordinate2D(latitude: latitude, longitude: longitude))
      
      
      
      func drawMap(SourceCordinate : CLLocationCoordinate2D, destinationcordinate :CLLocationCoordinate2D)
          {
              self.mapView.clear()
              let str = String(format:"https://maps.googleapis.com/maps/api/directions/json?origin=\(SourceCordinate.latitude),\(SourceCordinate.longitude)&destination=\(destinationcordinate.latitude),\(destinationcordinate.longitude)&key=\(googleServiceKey)")
              print(str)
              Alamofire.request(str).responseJSON { (responseObject) -> Void in
                  let resJson = JSON(responseObject.result.value!)
                  print(resJson)
                  let routes : NSArray = resJson["routes"].rawValue as! NSArray
                  if(resJson["status"].rawString()! == "ZERO_RESULTS"){}
                  else if(resJson["status"].rawString()! == "NOT_FOUND"){}
                  else if routes.count == 0{}
                  else{
                      let routes : NSArray = resJson["routes"].rawValue as! NSArray
      //                let position = CLLocationCoordinate2D(latitude: SourceCordinate.latitude, longitude: SourceCordinate.longitude)
                      let markerEnd = GMSMarker()
                      markerEnd.position = CLLocationCoordinate2D(latitude: self.latitude, longitude: self.longitude)
                      markerEnd.map = self.mapView
                      let pathv : NSArray = routes.value(forKey: "overview_polyline") as! NSArray
                      let paths : NSArray = pathv.value(forKey: "points") as! NSArray
                      let newPath = GMSPath.init(fromEncodedPath: paths[0] as! String)
                      let polyLine = GMSPolyline(path: newPath)
                      polyLine.strokeWidth = 5
                      polyLine.strokeColor =  .black
                      let ThemeOrange = GMSStrokeStyle.solidColor( .blue)
                      let OrangeToBlue = GMSStrokeStyle.gradient(from:  .blue, to:  .blue)
                      polyLine.spans = [GMSStyleSpan(style: ThemeOrange),
                                        GMSStyleSpan(style: ThemeOrange),
                                        GMSStyleSpan(style: OrangeToBlue)]
                      polyLine.map = self.mapView
      
                  }
              }
          }
      

      谢谢你的回答。它解决了我的问题。小距离可以。长距离需要时间。有什么解决办法吗?它是从一个地方到另一个地方创建一条线。我想它会创建一个带有动画的锯齿形路径。怎么可能呢?你应该在for循环或使用函数中提供所有点。或者可能你没有插入rted INTERNAR points.got n错误:
      ld:library找不到-lPods谷歌地图iOS SDK clang:error:linker命令失败,退出代码为1(使用-v查看调用)
      直接下载库并添加到您的项目中,我们可以为此获得Swift版本吗?@Tarek,小心==>Google Maps iOA SDK要求所有绘图事件都在主线程上完成。因此,对于第二种方法,您必须将所有maker设置代码放入dispatch\u get\u main\u队列()中闭包。否则请准备好崩溃您的甜蜜应用程序。@Monusingh您完全正确!我刚刚修改了代码,使完成处理程序在主线程上运行。谢谢!您好!我在第
      polyline=[GMSPolyline polylineWithPath:path]行上崩溃了;
      对Google Maps SDK for iOS的所有调用都必须通过UI线程进行。我将此代码转换为swift,但如果completionHandler{completionHandler(nil)},则此处会出现错误。错误为:'(GMSPolyline?->Void'不能转换为'Bool',这画了一条直线:(安装Google Maps SDK和GoogleMapsDirection.Thank,在一些小的调整方面帮了我很大的忙!嘿,我正在使用你的代码,但我没有得到结果。是否需要任何json文件?你需要使用正确的googleAPI键,并且需要为该键启用googleDirection功能。
      extension GMSMapView {
          func addPath(_ path: GMSPath, strokeColor: UIColor? = nil, strokeWidth: CGFloat? = nil, geodesic: Bool? = nil, spans: [GMSStyleSpan]? = nil) {
              let line = GMSPolyline(path: path)
              line.strokeColor = strokeColor ?? line.strokeColor
              line.strokeWidth = strokeWidth ?? line.strokeWidth
              line.geodesic = geodesic ?? line.geodesic
              line.spans = spans ?? line.spans
              line.map = self
          }
      }
      
      let path = GMSMutablePath(coordinates: [<#Coordinates#>])
      mapView.addPath(path)
      
      self.drawMap(SourceCordinate: CLLocationCoordinate2D(latitude: lat, longitude: long), destinationcordinate: CLLocationCoordinate2D(latitude: latitude, longitude: longitude))
      
      
      
      func drawMap(SourceCordinate : CLLocationCoordinate2D, destinationcordinate :CLLocationCoordinate2D)
          {
              self.mapView.clear()
              let str = String(format:"https://maps.googleapis.com/maps/api/directions/json?origin=\(SourceCordinate.latitude),\(SourceCordinate.longitude)&destination=\(destinationcordinate.latitude),\(destinationcordinate.longitude)&key=\(googleServiceKey)")
              print(str)
              Alamofire.request(str).responseJSON { (responseObject) -> Void in
                  let resJson = JSON(responseObject.result.value!)
                  print(resJson)
                  let routes : NSArray = resJson["routes"].rawValue as! NSArray
                  if(resJson["status"].rawString()! == "ZERO_RESULTS"){}
                  else if(resJson["status"].rawString()! == "NOT_FOUND"){}
                  else if routes.count == 0{}
                  else{
                      let routes : NSArray = resJson["routes"].rawValue as! NSArray
      //                let position = CLLocationCoordinate2D(latitude: SourceCordinate.latitude, longitude: SourceCordinate.longitude)
                      let markerEnd = GMSMarker()
                      markerEnd.position = CLLocationCoordinate2D(latitude: self.latitude, longitude: self.longitude)
                      markerEnd.map = self.mapView
                      let pathv : NSArray = routes.value(forKey: "overview_polyline") as! NSArray
                      let paths : NSArray = pathv.value(forKey: "points") as! NSArray
                      let newPath = GMSPath.init(fromEncodedPath: paths[0] as! String)
                      let polyLine = GMSPolyline(path: newPath)
                      polyLine.strokeWidth = 5
                      polyLine.strokeColor =  .black
                      let ThemeOrange = GMSStrokeStyle.solidColor( .blue)
                      let OrangeToBlue = GMSStrokeStyle.gradient(from:  .blue, to:  .blue)
                      polyLine.spans = [GMSStyleSpan(style: ThemeOrange),
                                        GMSStyleSpan(style: ThemeOrange),
                                        GMSStyleSpan(style: OrangeToBlue)]
                      polyLine.map = self.mapView
      
                  }
              }
          }