google maps route between 2 points with multi waypoints swift ios

Viewed 2725

I have this code but for some reason it's just drawing a rout between 2 points (first, and last points) ignoring all other points which is [index == 1 to index == n-1 ]

output : route between only 2 markers

expected output : route between all markers (5 markers)

Is any body knows what is the wrong with my code ?

 func getDotsToDrawRoute(positions : [CLLocationCoordinate2D], completion: @escaping(_ path : GMSPath) -> Void) {
    if positions.count > 1 {
        let origin = positions.first
        let destination = positions.last
        var wayPoints = ""
        for point in positions {
            wayPoints = wayPoints.characters.count == 0 ? "\(point.latitude),\(point.longitude)" : "\(wayPoints)|\(point.latitude),\(point.longitude)"
        }
        print("this is fullPath :: \(wayPoints)")
        let request = "https://maps.googleapis.com/maps/api/directions/json"
        let parameters : [String : String] = ["origin" : "\(origin!.latitude),\(origin!.longitude)", "destination" : "\(destination!.latitude),\(destination!.longitude)", "wayPoints" : wayPoints, "stopover": "true", "key" : kyes.google_map]
        Alamofire.request(request, method:.get, parameters : parameters).responseJSON(completionHandler: { response in
            guard let dictionary = response.result.value as? [String : AnyObject]
                else {
                    return
            }
            print ("route iss ::: \(dictionary["routes"])")
            if let routes = dictionary["routes"] as? [[String : AnyObject]] {
                if routes.count > 0 {
                    var first = routes.first
                    if let legs = first!["legs"] as? [[String : AnyObject]] {
                        let fullPath : GMSMutablePath = GMSMutablePath()
                        for leg in legs {
                            if let steps = leg["steps"] as? [[String : AnyObject]] {
                                for step in steps {
                                    if let polyline = step["polyline"] as? [String : AnyObject] {
                                        if let points = polyline["points"] as? String {
                                            fullPath.appendPath(path: GMSMutablePath(fromEncodedPath: points))
                                        }
                                    }
                                }

                                let polyline = GMSPolyline.init(path: fullPath)

                                polyline.path = fullPath
                                polyline.strokeWidth = 4.0
                                polyline.map = self._map                                }
                        }
                    }
                }
            }
        })
    }
}
3 Answers

Check out this solution working fine with me

    func drawpath(positions: [CLLocationCoordinate2D]) {

    let origin = positions.first!
    let destination = positions.last!
    var wayPoints = ""
    for point in positions {
        wayPoints = wayPoints.characters.count == 0 ? "\(point.latitude),\(point.longitude)" : "\(wayPoints)%7C\(point.latitude),\(point.longitude)"
    }

    let url = "https://maps.googleapis.com/maps/api/directions/json?origin=\(origin!.latitude),\(origin!.longitude)&destination=\(destination.latitude),\(destination.longitude)&mode=driving&waypoints=\(wayPoints)&key=KEY"
    Alamofire.request(url).responseJSON { response in

        print(response.request as Any)  // original URL request
        print(response.response as Any) // HTTP URL response
        print(response.data as Any)     // server data
        print(response.result as Any)   // result of response serialization

        let json = try!  JSON(data: response.data!)
        let routes = json["routes"][0]["overview_polyline"]["points"].stringValue

        let path = GMSPath.init(fromEncodedPath: routes)
        let polyline = GMSPolyline.init(path: path)
        polyline.strokeWidth = 4
        polyline.strokeColor = UIColor.red
        polyline.map = self._map
    }


}

try with:

    func getPolylineRoute(from source: CLLocationCoordinate2D, to destination: CLLocationCoordinate2D){
        self.mapView.clear()
        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=YOUR_API_KEY")! 
        let task = session.dataTask(with: url, completionHandler: {
            (data, response, error) in
            if error != nil {
                print("Error" + error!.localizedDescription)
            }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 {
                            return
                        }
                        print(routes)
                        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!)

                            let distancia = overview_polyline?["legs"] as? NSArray
                            let prueba = distancia![0] as? NSDictionary
                            let distancia2 = prueba?["distance"] as? NSDictionary
                            let control = distancia2?.object(forKey: "text") as! String

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

                }
            }
        })
        task.resume()
    }

You call the method with

self.getPolylineRoute(from: origin, to: destination)

Remember in the google url to put your api key where it says YOUR_API_KEY

You can use this function for drawing the polyline which covers your waypoints.

Make sure that positions doesn't have same waypoint coordinates. If so, it will just draw the polylines from source to destination

func drawPolyLine(for positions: [CLLocationCoordinate2D]) {
            let origin = positions.first!
            let destination = positions.last!
            var wayPoints = ""
            for point in positions {
                wayPoints = wayPoints.count == 0 ? "\(point.latitude),\(point.longitude)" : "\(wayPoints)%7C\(point.latitude),\(point.longitude)"
            }
            let url = "https://maps.googleapis.com/maps/api/directions/json?origin=\(origin.latitude),\(origin.longitude)&destination=\(destination.latitude),\(destination.longitude)&mode=driving&waypoints=\(wayPoints)&key=\(YOUR_GOOLE_MAP_API_KEY)"
            Alamofire.request(url).responseJSON { response in
                do {
                    let json = try JSONSerialization.jsonObject(with: response.data!, options: .allowFragments) as? [String: Any]
                    guard let routes = json?["routes"] as? NSArray else {
                        return
                    }
                    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 = 4
                        polyline.strokeColor = UIColor(red: 95/255.0, green: 233/255.0, blue: 188/255.0, alpha: 1.0)
                        polyline.map = self.mapView
                    }
                } catch {
                    print("Unexpected Error")
                }
            }
        }
Related