【问题标题】:How to draw a proper polylines on google maps [closed]如何在谷歌地图上绘制正确的折线[关闭]
【发布时间】:2016-06-11 11:13:54
【问题描述】:

我已成功绘制了一条从 a 点到 b 点的折线,但由于某种原因,它显示的直线不是正确的航点

这是代码

let path = GMSMutablePath()
        path.addLatitude(3.1970044, longitude:101.7389365)
        path.addLatitude(3.2058354, longitude:101.729536)
        let polyline = GMSPolyline(path: path)
        polyline.strokeWidth = 5.0
        polyline.geodesic = true
        polyline.map = mapView

我原以为它会做一些航路点,但它只显示直线折线

【问题讨论】:

  • 您想将两点之间的路线添加为折线吗?
  • 是的,就像在航点中一样。
  • 如果你想让折线跟随道路,你需要从 DirectionService 中获取。

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


【解决方案1】:

self.googleMapsView 是谷歌地图视图。

示例:self.getDirections("26.9211992,75.8185761", destination: "26.8472496,75.7691909", waypoints: ["26.8686811,75.7568383"], travelMode: nil, completionHandler: nil)

示例:谷歌方向链接 https://maps.googleapis.com/maps/api/directions/json?origin=26.9211992,75.8185761&destination=26.8472496,75.7691909&waypoints=optimize:true|26.8686811,75.7568383

   let baseURLGeocode = "https://maps.googleapis.com/maps/api/geocode/json?"
let baseURLDirections = "https://maps.googleapis.com/maps/api/directions/json?"

var selectedRoute: Dictionary<NSObject, AnyObject>!

var overviewPolyline: Dictionary<NSObject, AnyObject>!

var originCoordinate: CLLocationCoordinate2D!

var destinationCoordinate: CLLocationCoordinate2D!


func getDirections(origin: String!, destination: String!, waypoints: Array<String>!, travelMode: AnyObject!, completionHandler: ((status: String, success: Bool) -> Void)?) {
    if let originLocation = origin {
        if let destinationLocation = destination {
            var directionsURLString = baseURLDirections + "origin=" + originLocation + "&destination=" + destinationLocation
            if let routeWaypoints = waypoints {
                directionsURLString += "&waypoints=optimize:true"

                for waypoint in routeWaypoints {
                    directionsURLString += "|" + waypoint
                }
            }
            print(directionsURLString)
            directionsURLString = directionsURLString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
            let directionsURL = NSURL(string: directionsURLString)
            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                let directionsData = NSData(contentsOfURL: directionsURL!)
                do{
                    let dictionary: Dictionary<NSObject, AnyObject> = try NSJSONSerialization.JSONObjectWithData(directionsData!, options: NSJSONReadingOptions.MutableContainers) as! Dictionary<NSObject, AnyObject>

                    let status = dictionary["status"] as! String

                    if status == "OK" {
                        self.selectedRoute = (dictionary["routes"] as! Array<Dictionary<NSObject, AnyObject>>)[0]
                        self.overviewPolyline = self.selectedRoute["overview_polyline"] as! Dictionary<NSObject, AnyObject>

                        let legs = self.selectedRoute["legs"] as! Array<Dictionary<NSObject, AnyObject>>

                        let startLocationDictionary = legs[0]["start_location"] as! Dictionary<NSObject, AnyObject>
                        self.originCoordinate = CLLocationCoordinate2DMake(startLocationDictionary["lat"] as! Double, startLocationDictionary["lng"] as! Double)

                        let endLocationDictionary = legs[legs.count - 1]["end_location"] as! Dictionary<NSObject, AnyObject>
                        self.destinationCoordinate = CLLocationCoordinate2DMake(endLocationDictionary["lat"] as! Double, endLocationDictionary["lng"] as! Double)

                        let originAddress = legs[0]["start_address"] as! String
                        let destinationAddress = legs[legs.count - 1]["end_address"] as! String

                        let originMarker = GMSMarker(position: self.originCoordinate)
                        originMarker.map = self.googleMapsView
                        originMarker.icon = GMSMarker.markerImageWithColor(UIColor.greenColor())
                        originMarker.title = originAddress

                        let destinationMarker = GMSMarker(position: self.destinationCoordinate)
                        destinationMarker.map = self.googleMapsView
                        destinationMarker.icon = GMSMarker.markerImageWithColor(UIColor.redColor())
                        destinationMarker.title = destinationAddress

                        if waypoints != nil && waypoints.count > 0 {
                            for waypoint in waypoints {
                                let lat: Double = (waypoint.componentsSeparatedByString(",")[0] as NSString).doubleValue
                                let lng: Double = (waypoint.componentsSeparatedByString(",")[1] as NSString).doubleValue

                                let marker = GMSMarker(position: CLLocationCoordinate2DMake(lat, lng))
                                marker.map = self.googleMapsView
                                marker.icon = GMSMarker.markerImageWithColor(UIColor.purpleColor())

                            }
                        }

                        let route = self.overviewPolyline["points"] as! String

                        let path: GMSPath = GMSPath(fromEncodedPath: route)!
                        let routePolyline = GMSPolyline(path: path)
                        routePolyline.map = self.googleMapsView
                    }
                    else {
                        print("status")
                        //completionHandler(status: status, success: false)
                    }
                }
                catch {
                    print("catch")

                   // completionHandler(status: "", success: false)
                }
            })
        }
        else {
            print("Destination is nil.")
            //completionHandler(status: "Destination is nil.", success: false)
        }
    }
    else {
        print("Origin is nil")
        //completionHandler(status: "Origin is nil", success: false)
    }
}

【讨论】:

  • 这对我有帮助。谢谢你
  • 谢谢 非常有帮助 (Y)
  • @sfg2k 请更新 swift 4.2 的代码
【解决方案2】:

对于 Swift 3.0 请使用此代码...

func getDirections(origin: String!, destination: String!, waypoints:    Array<String>!, travelMode: AnyObject!, completionHandler: ((_ status:   String, _ success: Bool) -> Void)?) {

        if let originLocation = origin {
            if let destinationLocation = destination {
                var directionsURLString = baseURLDirections + "origin=" + originLocation + "&destination=" + destinationLocation
                if let routeWaypoints = waypoints {
                    directionsURLString += "&waypoints=optimize:true"

                    for waypoint in routeWaypoints {
                        directionsURLString += "|" + waypoint
                    }
                }
                print(directionsURLString)
                directionsURLString = directionsURLString.addingPercentEscapes(using: String.Encoding.utf8)!
                let directionsURL = NSURL(string: directionsURLString)
                DispatchQueue.main.async( execute: { () -> Void in
                    let directionsData = NSData(contentsOf: directionsURL! as URL)
                    do{
                        let dictionary: Dictionary<String, AnyObject> = try JSONSerialization.jsonObject(with: directionsData! as Data, options: JSONSerialization.ReadingOptions.mutableContainers) as! Dictionary<String, AnyObject>

                        let status = dictionary["status"] as! String

                        if status == "OK" {
                            self.selectedRoute = (dictionary["routes"] as! Array<Dictionary<String, AnyObject>>)[0]
                            self.overviewPolyline = self.selectedRoute["overview_polyline"] as! Dictionary<String, AnyObject>

                            let legs = self.selectedRoute["legs"] as! Array<Dictionary<String, AnyObject>>

                            let startLocationDictionary = legs[0]["start_location"] as! Dictionary<String, AnyObject>
                            self.originCoordinate = CLLocationCoordinate2DMake(startLocationDictionary["lat"] as! Double, startLocationDictionary["lng"] as! Double)

                            let endLocationDictionary = legs[legs.count - 1]["end_location"] as! Dictionary<String, AnyObject>
                            self.destinationCoordinate = CLLocationCoordinate2DMake(endLocationDictionary["lat"] as! Double, endLocationDictionary["lng"] as! Double)

                            let originAddress = legs[0]["start_address"] as! String
                            let destinationAddress = legs[legs.count - 1]["end_address"] as! String

                            let originMarker = GMSMarker(position: self.originCoordinate)
                            originMarker.map = self.mapView
                            originMarker.icon = UIImage(named: "mapIcon")
                            originMarker.title = originAddress

                            let destinationMarker = GMSMarker(position: self.destinationCoordinate)
                            destinationMarker.map = self.mapView
                            destinationMarker.icon = UIImage(named: "mapIcon")
                            destinationMarker.title = destinationAddress

                            if waypoints != nil && waypoints.count > 0 {
                                for waypoint in waypoints {
                                    let lat: Double = (waypoint.components(separatedBy: ",")[0] as NSString).doubleValue
                                    let lng: Double = (waypoint.components(separatedBy: ",")[1] as NSString).doubleValue

                                    let marker = GMSMarker(position: CLLocationCoordinate2DMake(lat, lng))
                                    marker.map = self.mapView
                                    marker.icon = UIImage(named: "mapIcon")

                                }
                            }

                            let route = self.overviewPolyline["points"] as! String

                            let path: GMSPath = GMSPath(fromEncodedPath: route)!
                            let routePolyline = GMSPolyline(path: path)
                            routePolyline.map = self.mapView
                            routePolyline.strokeColor = UIColor(red: 44, green: 134, blue: 200)
                            routePolyline.strokeWidth = 3.0
                        }
                        else {
                            print("status")
                            //completionHandler(status: status, success: false)
                        }
                    }
                    catch {
                        print("catch")

                        // completionHandler(status: "", success: false)
                    }
                })
            }
            else {
                print("Destination is nil.")
                //completionHandler(status: "Destination is nil.", success: false)
            }
        }
        else {
            print("Origin is nil")
            //completionHandler(status: "Origin is nil", success: false)
        }
    }

【讨论】:

    【解决方案3】:
    func drawMap ()
    {
    
        let str = String(format:"https://maps.googleapis.com/maps/api/directions/json?origin=\(originLatitude),\(originlongitude)&destination=\(destinationlatitude),\(destinationlongitude)&key=AIzaSyC8HZTqt2wsl14eI_cKxxxxxxxxxxxx")
    
    
        Alamofire.request(str).responseJSON { (responseObject) -> Void in
    
            let resJson = JSON(responseObject.result.value!)
            print(resJson)
    
            if(resJson["status"].rawString()! == "ZERO_RESULTS")
            {
    
            }
            else if(resJson["status"].rawString()! == "NOT_FOUND")
            {
    
            }
            else{
    
                let routes : NSArray = resJson["routes"].rawValue as! NSArray
                print(routes)
    
                let position = CLLocationCoordinate2D(latitude: self.sellerlatitude, longitude: self.sellerlongitude)
    
                let marker = GMSMarker(position: position)
                marker.icon = UIImage(named: "mapCurrent")
                marker.title = "Customer have selected same location as yours"
                marker.map = self.Gmap
    
                let position2 = CLLocationCoordinate2D(latitude: self.Buyyerlatitude, longitude: self.Buyyerlongitude)
    
                let marker1 = GMSMarker(position: position2)
                marker1.icon = UIImage(named: "makeupmarker")
                marker1.title = self.locationAddress
                marker1.map = self.Gmap
    
                let pathv : NSArray = routes.value(forKey: "overview_polyline") as! NSArray
                print(pathv)
                let paths : NSArray = pathv.value(forKey: "points") as! NSArray
                print(paths)
                let newPath = GMSPath.init(fromEncodedPath: paths[0] as! String)
    
    
                let polyLine = GMSPolyline(path: newPath)
                polyLine.strokeWidth = 3
                polyLine.strokeColor = UIColor.blue
                polyLine.map = self.Gmap
    
                let bounds = GMSCoordinateBounds(coordinate: position, coordinate: position2)
                let update = GMSCameraUpdate.fit(bounds, with: UIEdgeInsetsMake(170, 30, 30, 30))
                self.Gmap!.moveCamera(update)
    
            }
        }
    }
    

    对于 Swift 5

        func drawMap(SourceCordinate : CLLocationCoordinate2D, destinationcordinate :CLLocationCoordinate2D)
       {
           self.mapView.clear()
           let str = String(format:"https://maps.googleapis.com/maps/api/directions/json?origin=\(SourceCordinate.latitude),\(SourceCordinate.longitude)&destination=\(destinationcordinate.latitude),\(destinationcordinate.longitude)&key=\(googleServiceKey)")
           print(str)
           Alamofire.request(str).responseJSON { (responseObject) -> Void in
               let resJson = JSON(responseObject.result.value!)
               print(resJson)
               let routes : NSArray = resJson["routes"].rawValue as! NSArray
               if(resJson["status"].rawString()! == "ZERO_RESULTS"){}
               else if(resJson["status"].rawString()! == "NOT_FOUND"){}
               else if routes.count == 0{}
               else{
                   let routes : NSArray = resJson["routes"].rawValue as! NSArray
                   let position = CLLocationCoordinate2D(latitude: SourceCordinate.latitude, longitude: SourceCordinate.longitude)
                   /*let marker = GMSMarker(position: position)
                   marker.icon = #imageLiteral(resourceName: "ic_usermaplocation")//UIImage(named: "ic_MapPinGreyIcon")
                   marker.title = "" // Addres
                   marker.map = self.mapView
                   let position2 = CLLocationCoordinate2D(latitude: destinationcordinate.latitude, longitude: destinationcordinate.longitude)
                   let marker1 = GMSMarker(position: position2)
                   marker1.icon = #imageLiteral(resourceName: "ic_usermaplocation")//UIImage(named: "ic_LocationPinRedIcon")
                   marker1.title = "" // Destination Address
                   marker1.map = self.mapView*/
                   let pathv : NSArray = routes.value(forKey: "overview_polyline") as! NSArray
                   let paths : NSArray = pathv.value(forKey: "points") as! NSArray
                   let newPath = GMSPath.init(fromEncodedPath: paths[0] as! String)
                   let polyLine = GMSPolyline(path: newPath)
                   polyLine.strokeWidth = 5
                   polyLine.strokeColor =  .black
                   let ThemeOrange = GMSStrokeStyle.solidColor( .black)
                   let OrangeToBlue = GMSStrokeStyle.gradient(from:  .black, to:  .black)
                   polyLine.spans = [GMSStyleSpan(style: ThemeOrange),
                                     GMSStyleSpan(style: ThemeOrange),
                                     GMSStyleSpan(style: OrangeToBlue)]
                   polyLine.map = self.mapView
                   let camera = GMSCameraPosition.camera(withLatitude: self.sourceLat, longitude: self.sourceLong, zoom: 15.0)
                   self.mapView.animate(to: camera)
                   /*let bounds = GMSCoordinateBounds(coordinate: position, coordinate: position2)
                    let update = GMSCameraUpdate.fit(bounds, with: UIEdgeInsets(top: 100, left: 100, bottom: 400, right: 100))
                    self.objMapVIew!.moveCamera(update)*/
               }
           }
       }
    

    【讨论】:

    • 终于找到了真正有用的东西..!非常感谢。
    • @NavalHasan 欢迎兄弟
    • @AzharhussainShaikh 请更新 swift 5 的代码
    • @DavenderVermaSoni 请检查 swift 5 的更新代码
    • @AzharhussainShaikh,我需要包含航点的代码。它仅用于绘制从源到目的地的路径
    【解决方案4】:

    Azharhussain Shaikh's 答案的小改进。

    func drawMap (src: CLLocationCoordinate2D, dst: CLLocationCoordinate2D) {
    
            let str = String(format:"https://maps.googleapis.com/maps/api/directions/json?origin=\(src.latitude),\(src.longitude)&destination=\(dst.latitude),\(dst.longitude)&key=AIzaSyBKV************")
    
            Alamofire.request(str).responseJSON { (responseObject) -> Void in
    
                let resJson = JSON(responseObject.result.value!)
                print(resJson)
    
                if(resJson["status"].rawString()! == "ZERO_RESULTS")
                {
    
                }
                else if(resJson["status"].rawString()! == "NOT_FOUND")
                {
    
                }
                else{
    
                    let routes : NSArray = resJson["routes"].rawValue as! NSArray
                    print(routes)
    
                    let position = CLLocationCoordinate2D(latitude: src.latitude, longitude: src.longitude)
    
                    let marker = GMSMarker(position: position)
                    marker.icon = UIImage(named: "mapCurrent")
                    marker.title = "Customer have selected same location as yours"
                    marker.map = self.mapView
    
                    let position2 = CLLocationCoordinate2D(latitude: dst.latitude, longitude: dst.longitude)
    
                    let marker1 = GMSMarker(position: position2)
                    marker1.icon = UIImage(named: "makeupmarker")
                    marker1.title = "aa"
                    marker1.map = self.mapView
    
                    let pathv : NSArray = routes.value(forKey: "overview_polyline") as! NSArray
                    print(pathv)
                    let paths : NSArray = pathv.value(forKey: "points") as! NSArray
                    print(paths)
                    let newPath = GMSPath.init(fromEncodedPath: paths[0] as! String)
    
    
                    let polyLine = GMSPolyline(path: newPath)
                    polyLine.strokeWidth = 3
                    polyLine.strokeColor = UIColor.blue
                    polyLine.map = self.mapView
    
                    let bounds = GMSCoordinateBounds(coordinate: position, coordinate: position2)
                    let update = GMSCameraUpdate.fit(bounds, with: UIEdgeInsetsMake(170, 30, 30, 30))
                    self.mapView!.moveCamera(update)
    
                }
            }
        }
    

    调用函数:

    let fromLoc = CLLocationCoordinate2DMake(latitude1, longitude1)
    let toLoc = CLLocationCoordinate2DMake(latitude2, longitude2)
    
    drawMap(src: fromLoc, dst: toLoc)
    

    我改变了什么: 1.参数传递 2. 位置是静态给定的。我改了。

    【讨论】:

      【解决方案5】:

      您需要获得路线的所有积分。要获取路线,您需要使用 Google Direction API https://developers.google.com/maps/documentation/directions/。然后使用数组的第一个结果,这将是最短的一个,使用编码路径使用 pathFromEncodedPath: 方法绘制一条折线。

      【讨论】:

      • 你能给我一些代码吗?
      猜你喜欢
      • 1970-01-01
      • 2013-05-30
      • 1970-01-01
      • 2019-10-03
      • 1970-01-01
      • 2015-10-17
      • 1970-01-01
      • 2016-05-14
      • 2017-03-09
      相关资源
      最近更新 更多