Search code examples
swiftgoogle-mapsgmsmapview

How to draw routes on GMSmap view swift (not straight) using Google API and Swift


I am trying to draw route on mapview using Google Direction API. I am using the solution from the Stack Overflow itself but I am getting some errors regarding initializers.

Will the directions route will be same as Google Map itself or a straight one?

Also where should I call this methods?

I am getting error as:

Cannot invoke initializer for type 'GMSCoordinateBounds' with an argument list of type '(coordinate: String, String, coordinate: String, String)'

Below is the code:

 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=\(lat),\(long)&destination=\(directionlat),\(directionlong)&sensor=false&mode=driving&key=\(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()
    } 

Function to draw polyline:

 func drawPath(from polyStr: String){
        let mapView: GMSMapView
        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: "\(lat)","\(long)", coordinate: "\(directionlat)","\(directionlong)")) as? [String : AnyObject]
        mapView.moveCamera(cameraUpdate)
        let currentZoom = mapView.camera.zoom
        mapView.animate(toZoom: currentZoom - 1.4)
    }
    

Solution

  • GMSCoordinatesBounds takes CLLocationCoordinates2D type as parameter, not String.

    replace

    let cameraUpdate = GMSCameraUpdate.fit(GMSCoordinateBounds(coordinate: "\(lat)","\(long)", coordinate: "\(directionlat)","\(directionlong)")) as? [String : AnyObject]
    

    with

    let cameraUpdate = GMSCameraUpdate.fit(GMSCoordinateBounds(coordinate: CLLocationCoordinate2D(latitude: Double(lat), longitude: Double(long)), coordinate: CLLocationCoordinate2D(latitude: Double(directionlat), longitude: Double(directionlat))))
    

    and once you have added the mapView to your view controller and got the coordinates, call your function

    self.getRouteSteps(from source: CLLocationCoordinate2D(latitude: Double(lat), longitude: Double(long)), destination: CLLocationCoordinate2D(latitude: Double(directionlat), longitude: Double(directionlat)))