Swift: Google Maps Draw Waypoint Polyline

SWIFT: google maps draw waypoint polyline

To draw polylines between points two ore more you should use google map request read this link https://developers.google.com/maps/documentation/directions/intro#Waypoints
in my case i did

    func drawRoute() {
ServerCommunicator.getDotsToDrawRoute(positions: positions, completion: { path in
self.route.countRouteDistance(p: path)
self.polyline.path = path
self.polyline.strokeColor = UserSession.tintColor
self.polyline.strokeWidth = 4.0
self.polyline.map = self._mapView
})
}

and the part with request

static func getDotsToDrawRoute(positions : [CLLocationCoordinate2D], completion: @escaping(_ path : GMSPath) -> Void) {
if positions.count > 1 {
let origin = positions.first
let destination = positions.last
var wayPoints = ""
for point in positions {
wayPoints = wayPoints.characters.count == 0 ? "\(point.latitude),\(point.longitude)" : "\(wayPoints)|\(point.latitude),\(point.longitude)"
}
let request = "https://maps.googleapis.com/maps/api/directions/json"
let parameters : [String : String] = ["origin" : "\(origin!.latitude),\(origin!.longitude)", "destination" : "\(destination!.latitude),\(destination!.longitude)", "wayPoints" : wayPoints, "key" : googleAPI_KEY]
Alamofire.request(request, method:.get, parameters : parameters).responseJSON(completionHandler: { response in
guard let dictionary = response.result.value as? [String : AnyObject]
else {
return
}
if let routes = dictionary["routes"] as? [[String : AnyObject]] {
if routes.count > 0 {
var first = routes.first
if let legs = first!["legs"] as? [[String : AnyObject]] {
let fullPath : GMSMutablePath = GMSMutablePath()
for leg in legs {
if let steps = leg["steps"] as? [[String : AnyObject]] {
for step in steps {
if let polyline = step["polyline"] as? [String : AnyObject] {
if let points = polyline["points"] as? String {
fullPath.appendPath(GMSMutablePath(fromEncodedPath: points))
}
}
}
completion(path: fullPath)
}
}
}
}
}
})
}
}
extension GMSMutablePath {

func appendPath(path : GMSPath?) {
if let path = path {
for i in 0..<path.count() {
self.add(path.coordinate(at: i))
}
}
}

}

Draw polyline using Google Maps in custom view with Swift 3

It works fine here. Make sure you're setting correct coordinates of GMSCameraPosition.

EDIT

To draw the route between two coordinate, use Google Maps Direction API

Something like :

    let origin = "\(37.778483),\(-122.513960)"
let destination = "\(37.706753),\(-122.418677)"
let url = "https://maps.googleapis.com/maps/api/directions/json?origin=\(origin)&destination=\(destination)&mode=driving&key=[YOUR-API-KEY]"

Alamofire.request(url).responseJSON { response in
let json = JSON(data: response.data!)
let routes = json["routes"].arrayValue

for route in routes
{
let routeOverviewPolyline = route["overview_polyline"].dictionary
let points = routeOverviewPolyline?["points"]?.stringValue
let path = GMSPath.init(fromEncodedPath: points!)

let polyline = GMSPolyline(path: path)
polyline.strokeColor = .black
polyline.strokeWidth = 10.0
polyline.map = mapViewX

}
}

For more info - Directions API Developer's Guide

route between two markers in google maps - Swift

Sample Image

func drowRoute(from source: CLLocationCoordinate2D, to destination: CLLocationCoordinate2D) {
self.mapView.clear()

let origin = "\(source.latitude),\(source.longitude)"
let destinationn = "\(destination.latitude),\(destination.longitude)"

guard let url = URL(string: "https://maps.googleapis.com/maps/api/directions/json?origin=\(origin)&destination=\(destinationn)&mode=driving&key=Your Key") else {
let error = NSError(domain: "LocalDomain", code: 0, userInfo: [NSLocalizedDescriptionKey: "Failed to create object URL"])
print("Error: \(error)")
//completionHandler(nil, error)
return
}
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
SVProgressHUD.show()
let task = session.dataTask(with: url, completionHandler: {
(data, response, error) in
if error != nil {
print(error!.localizedDescription)
SVProgressHUD.dismiss()
}
else {
do {
if let json : [String:Any] = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any]{

guard let routes = json["routes"] as? NSArray else {
DispatchQueue.main.async {
SVProgressHUD.dismiss()
}
return
}

if (routes.count > 0) {
let overview_polyline = routes[0] as? NSDictionary
let dictPolyline = overview_polyline?["overview_polyline"] as? NSDictionary
let points = dictPolyline?.object(forKey: "points") as? String

DispatchQueue.main.async {
//
let legs = overview_polyline?["legs"] as! Array<Dictionary<String, AnyObject>>

let distance = legs[0]["distance"] as? NSDictionary
let distanceValue = distance?["value"] as? Int ?? 0

let duration = legs[0]["duration"] as? NSDictionary
let totalDurationInSeconds = duration?["value"] as? Int ?? 0

let miles = Double(distanceValue) / 1609.344
print("\(miles)")

if distanceValue > Int(32186.9){
SVProgressHUD.dismiss()
self.showAlert(title: Appname, message: "Your dropping point is more than 20 miles")
self.txtToLocation.text = ""
self.txtToLocation.becomeFirstResponder()

}else{
self.showPath(polyStr: points!)

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

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

let marker1 = GMSMarker()
marker1.position = CLLocationCoordinate2D(latitude:destinationCoordinate.latitude, longitude: destinationCoordinate.longitude)
marker1.icon = UIImage(named: "icn_pin-1")
marker1.map = self.mapView

let marker2 = GMSMarker()
marker2.position = CLLocationCoordinate2D(latitude:originCoordinate.latitude, longitude: originCoordinate.longitude)
marker2.icon = UIImage(named: "icn_pin2")
marker2.map = self.mapView

}

}
}
else {
print(json)
DispatchQueue.main.async {
SVProgressHUD.dismiss()
}
}
}
}
catch {
print("error in JSONSerialization")
DispatchQueue.main.async {
SVProgressHUD.dismiss()
}
}
}
})
task.resume()
}

func showPath(polyStr :String){
SVProgressHUD.dismiss()
let path = GMSPath(fromEncodedPath: polyStr)
let polyline = GMSPolyline(path: path)
polyline.strokeWidth = 5.0
polyline.strokeColor = UIColor.UIColorFromHex(hex: "#F6881F")
polyline.map = mapView
DispatchQueue.main.async {
let bounds = GMSCoordinateBounds(path: path!)
let update = GMSCameraUpdate.fit(bounds, with: UIEdgeInsets(top: 170, left: 30, bottom: 30, right: 30))
self.mapView.moveCamera(update)

}
}

How to draw route between multiple points in Google Maps?

You need to pass one or more (list of) | (pipe) separated lat longs (lat,longs) as waypoints to google's direction API. The overview polyline returned in response will contain a path from source to destination via all the way points you specified in your request.

copying from Google's doc

https://maps.googleapis.com/maps/api/directions/json?
origin=sydney,au&destination=perth,au
&waypoints=via:-37.81223%2C144.96254%7Cvia:-34.92788%2C138.60008
&key=YOUR_API_KEY

Read: https://developers.google.com/maps/documentation/directions/overview

Scroll to waypoints section, its pretty straight forward :)

Suggestion: If you are passing a list of | (pipe) separated lat longs ensure to properly encode comma (,) to %2C between lat and long values and ensure not to leave any space between them. Properly encode | as well.

Draw a path between two points on google maps

You want to parse json from here https://maps.googleapis.com/maps/api/directions/json?origin=50,8&destination=51,8&sensor=false&mode=driving

You need this nested structure. Some tips by me: read some tutorials what json is and how does it work in Swift. You find a lot in web. Alternativ take a pod (library) like ObjectMapper or SwiftyJson.

 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)")
}
}
}
}
}
}
}
}
}


Related Topics



Leave a reply



Submit