Как рисовать маршруты между двумя точками в Google Maps iOS Swift

Я использую карты Google в своем проекте iOS Swift. Я хочу нарисовать путь между двумя точками на карте (не по прямой). Любая идея, как это сделать?


person Anushka Madushan    schedule 09.02.2017    source источник


Ответы (5)


Чтобы нарисовать ломаную линию между двумя точками на карте Google в 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
}
person Ashish Shah    schedule 09.02.2017
comment
Я ценю хороший ответ - person Darshan Mothreja; 10.02.2017
comment
URL-адрес должен быть https, если вы используете авторизованный ключ - person Mr.G; 24.09.2017
comment
он говорит, что инициализатор для условной привязки должен иметь необязательный тип, а не «[String: Any]» в строке jsonResult - person Dharmik; 27.11.2019
comment
@Dharmik Добавьте свой фрагмент кода, где вы получаете это предупреждение. - person Ashish Shah; 27.11.2019
comment
Я скопировал ваш код в свой проект, он выдает ошибку в guard let jsonResult = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any], let jsonResponse = jsonResult Я получаю ошибку в let jsonResponse в вашем коде, я не понимаю, в чем проблема - person Dharmik; 27.11.2019
comment
Вы разобрались с этим вопросом? ^^ - person Noah Omdal; 18.12.2019
comment
@Dharmik, чтобы избежать этой ошибки, удалите let jsonResponse = jsonResult, потому что jsonResult не является обязательным, и используйте jsonResult вместо jsonResponse - person iGhost; 14.05.2021
comment
@Dharmik, просто поставь let jsonResponse = jsonResult после защитного блока. - person Vladimir Sukanica; 23.06.2021

Отображение несколько маршрутов между двумя точками на картах Google в 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()
person Sagar Sukode    schedule 08.05.2017
comment
@sagar sukode Можем ли мы нарисовать только один маршрут. - person Akhtar; 18.09.2017

Прежде всего, ответы могут рисовать маршруты, но есть способ, которым вы можете нарисовать точный маршрут, используя 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. Не забудьте заменить их на ваш источник и пункт назначения. Надеюсь, это поможет вам создать идеальную линию маршрута.

person Noman Haroon    schedule 01.11.2019

Создайте новый файл 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

        }
    }
}
person jeff ayan    schedule 17.02.2018

Этот фрагмент кода будет работать именно для вас. Не забудьте сменить 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()
}
person Den    schedule 26.11.2017