loading...

How to request direction for GMSMapView using MapKit

onmyway133 profile image Khoa Pham ・2 min read

Due to policy, we can't use Google Directions API on MKMapView, but we can use MKDirections on GMSMapView. Code is in Swift 5

MKDirections

A utility object that computes directions and travel-time information based on the route information you provide.

let source = MKMapItem(placemark: MKPlacemark(coordinate: userLocation.coordinate))
let destination = MKMapItem(placemark: MKPlacemark(coordinate: store.toCoordinate())
let request = MKDirections.Request()
request.source = source
request.destination = destination
request.requestsAlternateRoutes = fals
let directions = MKDirections(request: request
directions.calculate(completionHandler: { (response, error) in

})

MKRoute to CLLocationCoordinate2D

MKPolyline inherits from MKMultiPoint

let route = response.routes[0]

var coordinates = [CLLocationCoordinate2D](
    repeating: kCLLocationCoordinate2DInvalid,
    count: route.polyline.pointCount
)

route.polyline.getCoordinates(
    &coordinates,
    range: NSRange(location: 0, length: route.polyline.pointCount)
)

Google encoded polyline algorithm

Polyline encoding is a lossy compression algorithm that allows you to store a series of coordinates as a single string. Point coordinates are encoded using signed values.

Google's direction API provides points along route segments as an encoded string. For example the encoded string:

_p~iF~ps|U_ulLnnqC_mqNvxq`@

decodes to the coordinate points:

(38.5, -120.2), (40.7, -120.95), (43.252, -126.453)

Encode a CLLocationCoordinate2D array to a polyline

`swift
import Polyline

private func googlePolylines(from response: MKDirections.Response) -> [GMSPolyline] {
let polylines: [GMSPolyline] = response.routes.map({ route in
var coordinates = CLLocationCoordinate2D
route.polyline.getCoordinates(
&coordinates,
range: NSRange(location: 0, length: route.polyline.pointCount)
)
let polyline = Polyline(coordinates: coordinates)
let encodedPolyline: String = polyline.encodedPolyline
let path = GMSPath(fromEncodedPath: encodedPolyline)
return GMSPolyline(path: path)
})
return polylines
}
`

Render GMSPolyline

Use GMSStyleSpans to style

`swift
func show(polylines: [GMSPolyline]) {
polylines.forEach { polyline in
let strokeStyles = [
GMSStrokeStyle.solidColor(R.color.primary),
GMSStrokeStyle.solidColor(.clear)
]
let strokeLengths = [
NSNumber(value: 10),
NSNumber(value: 6)
]
if let path = polyline.path {
polyline.spans = GMSStyleSpans(path, strokeStyles, strokeLengths, .rhumb)
}
polyline.strokeWidth = 3
polyline.map = mapView
}

self.polylines = polylines

}
`

Read more

Original post https://github.com/onmyway133/blog/issues/290

Posted on by:

onmyway133 profile

Khoa Pham

@onmyway133

My apps https://onmyway133.com/apps/

Discussion

pic
Editor guide