【问题标题】:How to draw routes between two locations in google maps iOS swift如何在谷歌地图iOS swift中的两个位置之间绘制路线
【发布时间】:2017-06-27 10:24:03
【问题描述】:

我在我的 iOS swift 项目中使用谷歌地图。我想在地图上的两个位置之间绘制一条路径(不是直线)。知道该怎么做吗?

【问题讨论】:

    标签: ios swift google-maps-sdk-ios google-polyline


    【解决方案1】:

    在 Swift 中在谷歌地图上的两个位置之间绘制折线。

    //在这个方法中传递你的源和目标坐标。

    func fetchRoute(from source: CLLocationCoordinate2D, to destination: CLLocationCoordinate2D) {
        
        let session = URLSession.shared
        
        let url = URL(string: "http://maps.googleapis.com/maps/api/directions/json?origin=\(source.latitude),\(source.longitude)&destination=\(destination.latitude),\(destination.longitude)&sensor=false&mode=driving")!
        
        let task = session.dataTask(with: url, completionHandler: {
            (data, response, error) in
            
            guard error == nil else {
                print(error!.localizedDescription)
                return
            }
            
            guard let jsonResult = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any], let jsonResponse = jsonResult else {
                print("error in JSONSerialization")
                return
            }
            
            guard let routes = jsonResponse["routes"] as? [Any] else {
                return
            }
            
            guard let route = routes[0] as? [String: Any] else {
                return
            }
    
            guard let overview_polyline = route["overview_polyline"] as? [String: Any] else {
                return
            }
            
            guard let polyLineString = overview_polyline["points"] as? String else {
                return
            }
            
            //Call this method to draw path on map
            self.drawPath(from: polyLineString)
        })
        task.resume()
    }
    

    在地图上绘制折线。

    func drawPath(from polyStr: String){
        let path = GMSPath(fromEncodedPath: polyStr)
        let polyline = GMSPolyline(path: path)
        polyline.strokeWidth = 3.0
        polyline.map = mapView // Google MapView
    }
    

    【讨论】:

    • 感谢您的好回答
    • 如果您使用授权密钥,url 应该是 https
    • 它在 jsonResult 行显示“条件绑定的初始化程序必须具有可选类型,而不是 '[String : Any]'”
    • @Dharmik 在收到此警告的位置添加您的代码 sn-p。
    • 我已将您的代码复制粘贴到我的项目中,它在guard let jsonResult = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any], let jsonResponse = jsonResult 出现错误我在您的代码中在let jsonResponse 收到错误,我不明白是什么问题
    【解决方案2】:

    swift 3.0 中使用相机缩放在谷歌地图中的两个位置之间显示多条路线

        let origin = "\(startLocation.coordinate.latitude),\(startLocation.coordinate.longitude)"
        let destination = "\(destinationLocation.coordinate.latitude),\(destinationLocation.coordinate.longitude)"
    
        let urlString = "https://maps.googleapis.com/maps/api/directions/json?origin=\(origin)&destination=\(destination)&mode=driving&key=API_KEY"
    
        let url = URL(string: urlString)
        URLSession.shared.dataTask(with: url!, completionHandler: {
            (data, response, error) in
            if(error != nil){
                print("error")
            }else{
                do{
                    let json = try JSONSerialization.jsonObject(with: data!, options:.allowFragments) as! [String : AnyObject]
                    let routes = json["routes"] as! NSArray
                    self.mapView.clear()
    
                    OperationQueue.main.addOperation({
                        for route in routes
                        {
                            let routeOverviewPolyline:NSDictionary = (route as! NSDictionary).value(forKey: "overview_polyline") as! NSDictionary
                            let points = routeOverviewPolyline.object(forKey: "points")
                            let path = GMSPath.init(fromEncodedPath: points! as! String)
                            let polyline = GMSPolyline.init(path: path)
                            polyline.strokeWidth = 3
    
                            let bounds = GMSCoordinateBounds(path: path!)
                            self.mapView!.animate(with: GMSCameraUpdate.fit(bounds, withPadding: 30.0))
    
                            polyline.map = self.mapView
    
                        }
                    })
                }catch let error as NSError{
                    print("error:\(error)")
                }
            }
        }).resume()
    

    【讨论】:

    • @sagar sukode 我们可以只画一条路线吗?
    【解决方案3】:

    以上所有答案都可以绘制路线,但有一种方法可以使用路线 API 绘制准确的路线。以下是代码,希望对您有所帮助。

    func getRouteSteps(from source: CLLocationCoordinate2D, to destination: CLLocationCoordinate2D) {
    
        let session = URLSession.shared
    
        let url = URL(string: "https://maps.googleapis.com/maps/api/directions/json?origin=\(source.latitude),\(source.longitude)&destination=\(destination.latitude),\(destination.longitude)&sensor=false&mode=driving&key=\(Your_API_Key)")!
    
        let task = session.dataTask(with: url, completionHandler: {
            (data, response, error) in
    
            guard error == nil else {
                print(error!.localizedDescription)
                return
            }
    
            guard let jsonResult = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any] else {
    
                print("error in JSONSerialization")
                return
    
            }
    
    
    
            guard let routes = jsonResult["routes"] as? [Any] else {
                return
            }
    
            guard let route = routes[0] as? [String: Any] else {
                return
            }
    
            guard let legs = route["legs"] as? [Any] else {
                return
            }
    
            guard let leg = legs[0] as? [String: Any] else {
                return
            }
    
            guard let steps = leg["steps"] as? [Any] else {
                return
            }
              for item in steps {
    
                guard let step = item as? [String: Any] else {
                    return
                }
    
                guard let polyline = step["polyline"] as? [String: Any] else {
                    return
                }
    
                guard let polyLineString = polyline["points"] as? String else {
                    return
                }
    
                //Call this method to draw path on map
                DispatchQueue.main.async {
                    self.drawPath(from: polyLineString)
                }
    
            }
        })
        task.resume()
    }
    

    然后

        //MARK:- Draw Path line
    func drawPath(from polyStr: String){
        let path = GMSPath(fromEncodedPath: polyStr)
        let polyline = GMSPolyline(path: path)
        polyline.strokeWidth = 3.0
        polyline.map = mapView // Google MapView
    
    
        let cameraUpdate = GMSCameraUpdate.fit(GMSCoordinateBounds(coordinate: sourceLocationCordinates, coordinate: destinationLocationCordinates))
        mapView.moveCamera(cameraUpdate)
        let currentZoom = mapView.camera.zoom
        mapView.animate(toZoom: currentZoom - 1.4)
    }
    

    注意:我已经添加了sourcesLocationCordinates 和destinationLocationCordinates 变量。不要忘记将它们替换为您的源和目的地。希望这将帮助您制作完美的路线。

    【讨论】:

      【解决方案4】:

      创建一个新的 Swift 文件复制此代码,然后从地图视图中调用 drawPolygon() 方法以获取多边形线。

      import GoogleMaps
      
      private struct MapPath : Decodable{
          var routes : [Route]?
      }
      
      private struct Route : Decodable{ 
          var overview_polyline : OverView?
      }
      
      private struct OverView : Decodable {
          var points : String?
      }
      
      extension GMSMapView {
      
          //MARK:- Call API for polygon points
      
          func drawPolygon(from source: CLLocationCoordinate2D, to destination: CLLocationCoordinate2D){
      
              let config = URLSessionConfiguration.default
              let session = URLSession(configuration: config)
      
              guard let url = URL(string: "https://maps.googleapis.com/maps/api/directions/json?origin=\(source.latitude),\(source.longitude)&destination=\(destination.latitude),\(destination.longitude)&sensor=false&mode=driving") else {
                  return
              }
      
              DispatchQueue.main.async {
      
                  session.dataTask(with: url) { (data, response, error) in
      
                      guard data != nil else {
                          return
                      }
                      do {
      
                          let route = try JSONDecoder().decode(MapPath.self, from: data!)
      
                          if let points = route.routes?.first?.overview_polyline?.points {
                              self.drawPath(with: points)
                          }
                          print(route.routes?.first?.overview_polyline?.points)
      
                      } catch let error {
      
                          print("Failed to draw ",error.localizedDescription)
                      }
                      }.resume()
                  }
          }
      
          //MARK:- Draw polygon
      
          private func drawPath(with points : String){
      
              DispatchQueue.main.async {
      
                  let path = GMSPath(fromEncodedPath: points)
                  let polyline = GMSPolyline(path: path)
                  polyline.strokeWidth = 3.0
                  polyline.strokeColor = .red
                  polyline.map = self
      
              }
          }
      }
      

      【讨论】:

        【解决方案5】:

        这段代码适合您。不要忘记更改您的 API 密钥和模式(步行、驾驶)。

        func draw(src: CLLocationCoordinate2D, dst: CLLocationCoordinate2D){
        
            let config = URLSessionConfiguration.default
            let session = URLSession(configuration: config)
        
            let url = URL(string: "https://maps.googleapis.com/maps/api/directions/json?origin=\(src.latitude),\(src.longitude)&destination=\(dst.latitude),\(dst.longitude)&sensor=false&mode=walking&key=**YOUR_KEY**")!
        
            let task = session.dataTask(with: url, completionHandler: {
                (data, response, error) in
                if error != nil {
                    print(error!.localizedDescription)
                } else {
                    do {
                        if let json : [String:Any] = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any] {
        
                            let preRoutes = json["routes"] as! NSArray
                            let routes = preRoutes[0] as! NSDictionary
                            let routeOverviewPolyline:NSDictionary = routes.value(forKey: "overview_polyline") as! NSDictionary
                            let polyString = routeOverviewPolyline.object(forKey: "points") as! String
        
                            DispatchQueue.main.async(execute: {
                                let path = GMSPath(fromEncodedPath: polyString)
                                let polyline = GMSPolyline(path: path)
                                polyline.strokeWidth = 5.0
                                polyline.strokeColor = UIColor.green
                                polyline.map = mapView    
                            })
                        }
        
                    } catch {
                        print("parsing error")
                    }
                }
            })
            task.resume()
        }
        

        【讨论】:

          猜你喜欢
          • 2016-10-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-05-15
          • 1970-01-01
          • 2016-02-27
          相关资源
          最近更新 更多