在Swift4中的GoogleMaps上显示路径

时间:2018-03-28 09:04:44

标签: ios swift google-maps swift4

我的问题是我想在两点之间画出时间,而我的两个位置都来自不同的控制器

for my first Location :- 
  extension HomeViewController: PickupLocationDelegate {
func didSelectLocation(place: GooglePlaceModel?) {
    guard let place = place else {return}
    enter_Location_TF.text = place.name
    customDirectionViewTwo.isHidden = false
    direction_Button.isHidden = true
    location_Button.setImage(UIImage(named: "directionPoint")?.withRenderingMode(.alwaysOriginal), for: .normal)

    pickupMarkers.forEach { (marker) in
        marker.map = nil
    }
    let position = CLLocationCoordinate2D(latitude: place.latitude , longitude: place.longitude)
    print(position)
    let path = GMSMutablePath()
    path.add(CLLocationCoordinate2D(latitude: place.latitude, longitude: place.longitude))
    let marker = GMSMarker()
    marker.position = position
    marker.map = mapView
    mapView.camera = GMSCameraPosition.camera(withTarget: position, zoom: 14)
    pickupMarkers.append(marker)

}
}// My second location:-
 extension HomeViewController: DropLocationDelegate {
func didSelectDrop(location: GooglePlaceModel?) {
    guard let location = location else {return}
    dropLocationLbl?.text = location.name


    let position = CLLocationCoordinate2D(latitude: location.latitude , longitude: location.longitude)
    print(position)
    let marker = GMSMarker(position: position)
    marker.icon = #imageLiteral(resourceName: "icon-drop-location")
    marker.map = mapView

    mapView.camera = GMSCameraPosition.camera(withTarget: position, zoom: 14)
    pickupMarkers.append(marker)
    let path = GMSMutablePath()
    path.add(CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude))
    pickupMarkers.forEach { (marker) in
        path.add(marker.position)
    }
    let bounds = GMSCoordinateBounds(path: path)
    mapView?.animate(with: GMSCameraUpdate.fit(bounds, withPadding: 50.0))
}
}

标记正确显示但路径未显示。我用了  GMSMutable路径在位置之间绘制线但这不能正常工作。有什么帮助吗?

1 个答案:

答案 0 :(得分:2)

<强>前提条件

您需要在此链接后获取Google说明API密钥 How to get a Google Directions API key您还需要添加此行

GMSPlacesClient.provideAPIKey("Your API KEY")

AppDelegate didFinishLaunchingWithOptions方法

现在我们的问题

要查找路径,您需要使用类似这样的方法,使用googleapis.directions请求,然后在闭包中传递两个CLLocationCoordinate2D,您将获得一个CLLocationCoordinate2D数组,它们是路径的路标

public func getWaypointsAsArrayOfCoordinates(startLocation: CLLocationCoordinate2D, endLocation: CLLocationCoordinate2D, mode:String? = "walking", lang:String? = "en", finishedClosure:@escaping (([CLLocationCoordinate2D])->Void)){

        var resultedArray:[CLLocationCoordinate2D] = []

        let urlWithParams = "https://maps.googleapis.com/maps/api/directions/json" + self.customEncodedParameters(parametersDict: ["origin":"\(startLocation.latitude),\(startLocation.longitude)", "destination": "\(endLocation.latitude),\(endLocation.longitude)", "mode": mode!, "key":googleDirectionsApiKey, "language" : lang!])

        var urlRequest = URLRequest(url: URL(string: urlWithParams)!)
        urlRequest.httpMethod = "GET"

        URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in

            if let _ = error {
            } else {
                do {
                    if  let jsonData = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary {
                        let status = jsonData["status"] as! String
                        if(status == "OK") {

                            for routeDict in jsonData["routes"] as! Array<Dictionary<String, AnyObject>>
                            {
                                let legs = routeDict["legs"] as! Array<Dictionary<String, AnyObject>>
                                for leg in legs
                                {
                                    let steps = leg["steps"] as! Array<Dictionary<String, AnyObject>>
                                    for (index,step) in steps.enumerated(){
                                        let start = step["start_location"] as! Dictionary<String,Any>
                                        let end = step["end_location"] as! Dictionary<String,Any>
                                        resultedArray.append(CLLocationCoordinate2D(latitude: start["lat"] as! CLLocationDegrees, longitude: start["lng"] as! CLLocationDegrees))
                                        if(index == steps.count - 1) {
                                            resultedArray.append(CLLocationCoordinate2D(latitude: end["lat"] as! CLLocationDegrees, longitude: end["lng"] as! CLLocationDegrees))
                                        }
                                    }
                                }
                            }
                            finishedClosure(resultedArray)
                        }
                        else {
                            print("not found")
                            finishedClosure([])
                        }
                    }
                } catch {
                    print(error)
                    finishedClosure([])
                }
            }

            }.resume()

    }

编辑(添加缺失的功能)

private func customEncodedParameters(parametersDict:[String:String]) ->String
    {
        let charactersAllowed = CharacterSet.urlQueryAllowed
        var returnStr = ""
        for key in parametersDict.keys {
            if(returnStr.count == 0)
            {
                returnStr += "?"
                returnStr += key.addingPercentEncoding(withAllowedCharacters: charactersAllowed)!
                returnStr += "="
                returnStr += parametersDict[key]!.addingPercentEncoding(withAllowedCharacters: charactersAllowed)!
            }else{
                returnStr += "&"
                returnStr += key.addingPercentEncoding(withAllowedCharacters: charactersAllowed)!
                returnStr += "="
                returnStr += parametersDict[key]!.addingPercentEncoding(withAllowedCharacters: charactersAllowed)!
            }
        }
        return returnStr
    }

然后您可以在代码中使用它

extension HomeViewController: DropLocationDelegate {
func didSelectDrop(location: GooglePlaceModel?) {
    guard let location = location else {return}
    dropLocationLbl?.text = location.name


    let position = CLLocationCoordinate2D(latitude: location.latitude , longitude: location.longitude)
    print(position)
    let marker = GMSMarker(position: position)
    marker.icon = #imageLiteral(resourceName: "icon-drop-location")
    marker.map = mapView

    mapView.camera = GMSCameraPosition.camera(withTarget: position, zoom: 14)
    pickupMarkers.append(marker)
    self.getWaypointsAsArrayOfCoordinates(startLocation: pickupMarkers.first.position , endLocation: pickupMarkers.last.position) { [weak self] (arrayOfCoordinates) in

        DispatchQueue.main.async {
            let path = GMSMutablePath()

            for coordinate in arrayOfCoordinates {
                path.add(coordinate)
            }

            let polyline = GMSPolyline(path: path)
            polyline.strokeWidth = 2
            polyline.strokeColor = UIColor.red
            polyline.map = self?.mapView

            let bounds = GMSCoordinateBounds(path: path)
            self?.mapView?.animate(with: GMSCameraUpdate.fit(bounds, withPadding: 50.0))
        }
    }
}
}