在谷歌地图上绘制两点之间的路径

时间:2017-05-04 17:43:51

标签: ios swift google-maps google-maps-api-3 swift3

我想在swift 3中的两个标记之间的谷歌地图上画一条路径,我收到一个错误。任何人都可以告诉我我做错了什么。请帮我解决这个问题。

let url = URL(string: "http://maps.googleapis.com/maps/api/directions/json?origin=\(olat),\(olng)&destination=\(dlat),\(dlng)&sensor=false&mode=driving")!


    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 routes = json["routes"] as? [Any]
                    let overview_polyline = routes?[0] as?[String:Any]
                    let polyString = overview_polyline?["points"] as?String

                    //Call this method to draw path on map

                    DispatchQueue.main.async
                    {
                            self.showPath(polyStr: polyString!)
                    }

                }

            }catch{
                print("error in JSONSerialization")
            }
        }
    })
    task.resume()

有人请指导我在两点之间的谷歌地图上画一条路线。

2 个答案:

答案 0 :(得分:1)

你想从这里解析json https://maps.googleapis.com/maps/api/directions/json?origin=50,8&destination=51,8&sensor=false&mode=driving

您需要这种嵌套结构。我的一些提示:阅读一些教程json是什么以及它如何在Swift中工作。你在网上找到了很多。 Alternativ采用像ObjectMapper或SwiftyJson这样的pod(库)。

 if let json : [String:Any] = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any]{

                    // print("json \(json)")
                    if let routes = json["routes"] as? [Any] {

                        if let route = routes[0] as? [String:Any] {

                            if let legs = route["legs"] as? [Any] {

                                if let leg = legs[0] as? [String:Any] {

                                    if let steps = leg["steps"] as? [Any] {

                                        if let step = steps[0] as? [String:Any] {


                                            if let polyline = step["polyline"] as? [String:Any] {

                                                if let points = polyline["points"] as? String {
                                                    print("points \(points)")
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

答案 1 :(得分:1)

只需两步:

第1步:调用google map plote route API。

第2步:处理路线,距离和持续时间的响应。

*****STEP 1:*****
/* request google direction GET APIs */
func requestGoogleMapsDirectionApis(originLat: String,originLong:String, destinationLat:String, destinationLong:String, onSuccess:@escaping (_ response:AnyObject)->Void, onError:@escaping (_ errorMessage:String)->Void)->Void{


// GOOGLE DIRECTION APIS DEMO
// https://maps.googleapis.com/maps/api/directions/json?origin=27.696981,85.2942719&destination=27.6792144,85.3632975&sensor=false&mode=driving&alternatives=falseGOOGLE_MAP_API_KEY


let url:String = "https://maps.googleapis.com/maps/api/directions/json?origin=\(originLat),\(originLong)&destination=\(destinationLat),\(destinationLong)&sensor=false&mode=driving&alternatives=false\(MAP_API_KEY)"
showLog(classname: classname, tagName: "**FULL URL \(url)")


Alamofire.request(url, method: .get).responseJSON { response in

    showLog(classname: classname , tagName: "\n*** RESPONSE SERIALIZATION:\n \(response.result)")   // result of response serialization

    switch response.result {
    case .success:

        if let jsonObject = response.result.value{
            showLog(classname: classname, tagName: "\n*** OnSuccessResponse: \(jsonObject as AnyObject)")
            onSuccess(jsonObject as AnyObject)
        }

    case .failure:

        /* Handle error just using simple message */
        showLog(classname: classname, tagName: "\n*** OnErrorResponse: \(response)")
        onError("failure")

    }
}


*****STEP 2:*****
/*
 * PLOT ROUTE IN GOOGLE MAP
 * CALCULATE DISTANCE
 * CALCULATE TIME
 */
func callPlotRouteCalcDistanceAndTimeApis(originLat:String, originLong:String, destinationLat:String, destinationLong:String){

    homeViewCOntroller.view.makeToastActivity(.center)
    requestGoogleMapsDirectionApis(originLat: originLat, originLong: originLong, destinationLat: destinationLat, destinationLong: destinationLong, onSuccess: { (response) in

        // filter data
        // set data to model
        // plot route in google map

        showLog(classname: self.className, tagName: response)
        self.responseJsonObjectFilter(jsonObject: response)
        self.homeViewCOntroller.view.hideToastActivity()

    }) { (failureMsz) in

        showLog(classname: self.className, tagName: failureMsz)
        self.homeViewCOntroller.view.hideToastActivity()

    }

}

/* Response object filter PLOT ROUTE APIs for SUCCESS or FAILED */
func responseJsonObjectFilter(jsonObject:AnyObject){
    showLog(classname: className ,tagName: "responseJsonObjectFilter")

    if let jsonObjectDictionary = jsonObject as? NSDictionary {

        if let statusMessage = jsonObjectDictionary["status"] as? String{

            if(statusMessage == "OK"){

                if let routesObject = jsonObjectDictionary["routes"] as? [Any] {

                    if routesObject[0] is NSDictionary {

                        let anyObject:AnyObject = routesObject[0] as AnyObject
                        if let routeObjectDictionary = anyObject as? NSDictionary{

                            /* legs KEY for duration and distance */
                            if let legsObject = routeObjectDictionary["legs"] as? [Any] {

                                let legsAnyObject:AnyObject = legsObject[0] as AnyObject
                                if let legsObjectDictionary = legsAnyObject as? NSDictionary{

                                    showLog(classname: className, tagName: legsObjectDictionary)
                                    /* DISTANCE KEY for distance */
                                    if let distanceObjectNsDictionary = legsObjectDictionary["distance"] as? NSDictionary {

                                        var estimatedDistance:Double = distanceObjectNsDictionary["value"] as! Double
                                        estimatedDistance = estimatedDistance/1000

                                        bookingModel.estimatedDistance = String(format: "%.2f", estimatedDistance)

                                    }

                                    /* DURATION KEY for duration */
                                    if let durationObjectNsDictionary = legsObjectDictionary["duration"] as? NSDictionary {

                                        var estimatedTime:Double = durationObjectNsDictionary["value"] as! Double
                                        estimatedTime = estimatedTime/60

                                        bookingModel.estimatedTime = "\(estimatedTime)"

                                    }

                                }

                            }

                            /* overview_polyline KEY for duration and distance */
                            if let poylineObjectNsDictionary = routeObjectDictionary["overview_polyline"] as? NSDictionary {

                                showLog(classname: className, tagName: poylineObjectNsDictionary["points"] as! String)
                                bookingModel.route = poylineObjectNsDictionary["points"] as? String
                                generateRoute(uiMapView:homeViewCOntroller.uiMapView, encodedString: poylineObjectNsDictionary["points"] as! String)

                            }

                        }
                    }
                }

            }else{

                showSnackbar(uiView: self.homeViewCOntroller.view, message: "Could not plot route. Please check your internet connection.")

            }
        }

    }
    self.homeViewCOntroller.view.hideToastActivity()
}


/* Generate ROUTE to UIMapView */
func generateRoute(uiMapView:GMSMapView, encodedString:String){

    uiMapView.clear()
    let path = GMSMutablePath(fromEncodedPath: encodedString)
    let polyLine = GMSPolyline(path: path)
    polyLine.strokeWidth = 3
    polyLine.strokeColor = hexStringToUIColor(hex: redColor)
    polyLine.map = uiMapView

    let polyline = Polyline(encodedPolyline: encodedString)
    let decodedCoordinates: [CLLocationCoordinate2D]? = polyline.coordinates

    let pickupLat = decodedCoordinates?[0].latitude
    let pickupLong = decodedCoordinates?[0].longitude


    let dropLat = decodedCoordinates?[((decodedCoordinates?.count)! -  1)].latitude
    let dropLong = decodedCoordinates?[((decodedCoordinates?.count)! - 1)].longitude

    // Creates a marker in the center of the map.
    let marker = GMSMarker()
    marker.position = CLLocationCoordinate2D(latitude: pickupLat!, longitude: pickupLong!)
    marker.snippet = "Pickup Location"
    marker.icon = UIImage(named: "ic_pin_pick.png")
    marker.map = uiMapView

    // Creates a marker in the center of the map.
    let marker2 = GMSMarker()
    marker2.position = CLLocationCoordinate2D(latitude: dropLat!, longitude: dropLong!)
    marker2.snippet = "Drop Location"
    marker2.icon = UIImage(named: "ic_pin_drop.png")
    marker2.map = uiMapView

}