使用Swift 3自定义视图中的Google Maps绘制折线

我试图在自定义UIView上使用Google地图的两个地方之间绘制路线,但无法正确实施。 我的自定义视图是mapViewX。 我已经使用pod安装了Google sdk,其中包括pod“GoogleMaps”和pod“GooglePlaces”。 我把自定义类作为“GMSMapView”。 我的代码是:

@IBOutlet weak var mapViewX: GMSMapView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let path = GMSMutablePath() path.add(CLLocationCoordinate2D(latitude: 37.778483, longitude: -122.513960)) path.add(CLLocationCoordinate2D(latitude: 37.706753, longitude: -122.418677)) let polyline = GMSPolyline(path: path) polyline.strokeColor = .black polyline.strokeWidth = 10.0 polyline.map = mapViewX } 

请帮忙!

它在这里工作正常。 确保你正在设置GMSCameraPosition正确坐标。

编辑

要在两个坐标之间绘制路线,请使用Google Maps Direction API

就像是 :

  let origin = "\(37.778483),\(-122.513960)" let destination = "\(37.706753),\(-122.418677)" let url = "https://maps.googleapis.com/maps/api/directions/json?origin=\(origin)&destination=\(destination)&mode=driving&key=[YOUR-API-KEY]" Alamofire.request(url).responseJSON { response in let json = JSON(data: response.data!) let routes = json["routes"].arrayValue for route in routes { let routeOverviewPolyline = route["overview_polyline"].dictionary let points = routeOverviewPolyline?["points"]?.stringValue let path = GMSPath.init(fromEncodedPath: points!) let polyline = GMSPolyline(path: path) polyline.strokeColor = .black polyline.strokeWidth = 10.0 polyline.map = mapViewX } } 

欲了解更多信息 – 方向API开发人员指南

要在两个坐标之间绘制路线,您需要向Google Maps Directions API发出请求并parsing其响应。 因此,您首先需要获取您的请求的API密钥。 您可以在此处创build一个项目,并在此项目中启用Google Maps Directions API。

假设您安装了Google Maps SDK,则需要向Directions API发出请求,然后parsing其响应。 一旦分析了响应JSON,就可以创build一个GMSPath对象。 我更喜欢用一个带有两个input的函数来实现这个function,开始和结束CLLocationCoordinate2D对象,并在成功时返回GMSPath,如果失败则返回错误。 下面的代码是在Swift 3中。

我的课和它的function如下所示:

 import Foundation import CoreLocation import GoogleMaps class SessionManager { let GOOGLE_DIRECTIONS_API_KEY = "INSERT_YOUR_API_KEY_HERE" func requestDirections(from start: CLLocationCoordinate2D, to end: CLLocationCoordinate2D, completionHandler: @escaping ((_ response: GMSPath?, _ error: Error?) -> Void)) { guard let url = URL(string: "https://maps.googleapis.com/maps/api/directions/json?origin=\(start.latitude),\(start.longitude)&destination=\(end.latitude),\(end.longitude)&key=\(GOOGLE_DIRECTIONS_API_KEY)") else { let error = NSError(domain: "LocalDomain", code: 0, userInfo: [NSLocalizedDescriptionKey: "Failed to create object URL"]) print("Error: \(error)") completionHandler(nil, error) return } // Set up the session let config = URLSessionConfiguration.default let session = URLSession(configuration: config) let task = session.dataTask(with: url) { (data, response, error) in // Check if there is an error. guard error == nil else { DispatchQueue.main.async { print("Google Directions Request Error: \((error!)).") completionHandler(nil, error) } return } // Make sure data was received. guard let data = data else { DispatchQueue.main.async { let error = NSError(domain: "GoogleDirectionsRequest", code: 0, userInfo: [NSLocalizedDescriptionKey: "Failed to receive data"]) print("Error: \(error).") completionHandler(nil, error) } return } do { // Convert data to dictionary. guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else { DispatchQueue.main.async { let error = NSError(domain: "GoogleDirectionsRequest", code: 2, userInfo: [NSLocalizedDescriptionKey: "Failed to convert JSON to Dictionary"]) print("Error: \(error).") completionHandler(nil, error) } return } // Check if the the Google Direction API returned a status OK response. guard let status: String = json["status"] as? String, status == "OK" else { DispatchQueue.main.async { let error = NSError(domain: "GoogleDirectionsRequest", code: 3, userInfo: [NSLocalizedDescriptionKey: "Google Direction API did not return status OK"]) print("Error: \(error).") completionHandler(nil, error) } return } print("Google Direction API response:\n\(json)") // We only need the 'points' key of the json dictionary that resides within. if let routes: [Any] = json["routes"] as? [Any], routes.count > 0, let routes0: [String: Any] = routes[0] as? [String: Any], let overviewPolyline: [String: Any] = routes0["overview_polyline"] as? [String: Any], let points: String = overviewPolyline["points"] as? String { // We need the get the first object of the routes array (route0), then route0's overview_polyline and finally overview_polyline's points object. if let path: GMSPath = GMSPath(fromEncodedPath: points) { DispatchQueue.main.async { completionHandler(path, nil) } return } else { DispatchQueue.main.async { let error = NSError(domain: "GoogleDirections", code: 5, userInfo: [NSLocalizedDescriptionKey: "Failed to create GMSPath from encoded points string."]) completionHandler(nil, error) } return } } else { DispatchQueue.main.async { let error = NSError(domain: "GoogleDirections", code: 4, userInfo: [NSLocalizedDescriptionKey: "Failed to parse overview polyline's points"]) completionHandler(nil, error) } return } } catch let error as NSError { DispatchQueue.main.async { completionHandler(nil, error) } return } } task.resume() } } 

那么你可以在你的viewDidLoad使用它:

 @IBOutlet weak var mapView: GMSMapView! override func viewDidLoad() { super.viewDidLoad() let sessionManager = SessionManager() let start = CLLocationCoordinate2D(latitude: 37.778483, longitude: -122.513960) let end = CLLocationCoordinate2D(latitude: 37.706753, longitude: -122.418677) sessionManager.requestDirections(from: start, to: end, completionHandler: { (path, error) in if let error = error { print("Something went wrong, abort drawing!\nError: \(error)") } else { // Create a GMSPolyline object from the GMSPath let polyline = GMSPolyline(path: path!) // Add the GMSPolyline object to the mapView polyline.map = self.mapView // Move the camera to the polyline let bounds = GMSCoordinateBounds(path: path!) let cameraUpdate = GMSCameraUpdate.fit(bounds, with: UIEdgeInsets(top: 40, left: 15, bottom: 10, right: 15)) self.mapView.animate(with: cameraUpdate) } }) } 

希望你觉得它有用。