可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 12 months ago.
Improve this question
I have successfully drawn a polyline from point a to point b, but for some reason , it shows linear line not the correct waypoints
Here's the code
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
I was expecting that it would be doing some waypoints, but it just shows straight polylines
回答1:
self.googleMapsView is the google maps view.
Example : self.getDirections("26.9211992,75.8185761", destination: "26.8472496,75.7691909", waypoints: ["26.8686811,75.7568383"], travelMode: nil, completionHandler: nil)
Example: google direction link
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)
}
}
回答2:
For Swift 3.0
Please use this code...
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)
}
}
}
For 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)*/
}
}
}
回答4:
You need to get all the points for the route. To get the route you need to use Google Direction API https://developers.google.com/maps/documentation/directions/. Then use the 1st result of array that will be the shortest one, use the encoded path to draw a poly line using pathFromEncodedPath: method.
回答5:
A small improvement to Azharhussain Shaikh's answer.
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)
}
}
}
To call the function :
let fromLoc = CLLocationCoordinate2DMake(latitude1, longitude1)
let toLoc = CLLocationCoordinate2DMake(latitude2, longitude2)
drawMap(src: fromLoc, dst: toLoc)
What I have changed:
1. Parameter passing
2. Position was given statically. I changed it.