DEV Community

Khoa Pham
Khoa Pham

Posted on

1 2

How to request direction for GMSMapView using MapKit

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

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs