Khoa Pham
Posted on June 11, 2019
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
- 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
Posted on June 11, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.