How to request direction for GMSMapView using MapKit
Tags: ios, swift, mapview, direction
Published: 2019-06-11 13:32:47

---
title: How to request direction for GMSMapView using MapKit
published: true
description: 
tags: ios,swift,mapview,direction
---

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

- https://developer.apple.com/documentation/mapkit/mkdirections

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


```swift
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`

```swift
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

- https://developers.google.com/maps/documentation/utilities/polylinealgorithm

> 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.

- https://github.com/mwoollard/SwiftGooglePolyline

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

- https://github.com/raphaelmor/Polyline

> 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](
            repeating: kCLLocationCoordinate2DInvalid,
            count: route.polyline.pointCount
        )
        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

- Geodesic https://nshipster.com/mkgeodesicpolyline/
- Google Directions API https://developers.google.com/maps/documentation/directions/start
- Dotted Polylines with Google Maps SDK for iOS https://engineering.door2door.io/dotted-polylines-with-google-maps-sdk-for-ios-7b21786a0645


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