iosxcodeswiftmapkitmkpolyline

Smooth MKPolyline to follow the road


I know this has been asked before a few years back, but all the answers involved using Google Maps API to solve this. I wonder if there is a proper way to solve this now that iOS8 is out and it brought many improvements to native MapKit.

Basically I draw a polyline on the road, which consists of many intermediate points.

    var locations = [CLLocation]()
    for item in list {
        locations.append(CLLocation(latitude: CLLocationDegrees(item["location"]["coordinate"]["x"].doubleValue), longitude: CLLocationDegrees(item["location"]["coordinate"]["y"].doubleValue)))
    }
    var coordinates = locations.map({(location: CLLocation!) -> CLLocationCoordinate2D in return location.coordinate})
    var polyline = MKPolyline(coordinates: &coordinates, count: locations.count)
    mapView.addOverlay(polyline)

At one time there are between 5 and 30 points on the map. When a polyline connects them I get more or less fair representation of the trip. The problem is: It does NOT sticks to the road.

enter image description here

So I'm getting "rough" edges from time to time. Even IF I were using Google Direction API, it is limited to 8 ways points and basically decides for you how to get from point A to point B, drawing smooth polyline along the way. Also, Directions API is limited to 2500 usages per 24 hours. All I need to do is to adjust my current polyline to the closest road

Many thanks


Solution

  • After some digging I managed to find the answer to this question, although I'm not really sure about its impact on overall performance of whether or not this going to make Apple happy, since it sends out a lot of small MKDirectionsRequest's. For me 30+ points worked just fine.

        var myRoute : MKRoute?
        var directionsRequest = MKDirectionsRequest()
        var placemarks = [MKMapItem]()
        for item in list {
            var placemark = MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: CLLocationDegrees(item["location"]["coordinate"]["x"].doubleValue), longitude: CLLocationDegrees(item["location"]["coordinate"]["y"].doubleValue)), addressDictionary: nil )
            placemarks.append(MKMapItem(placemark: placemark))
        }
        directionsRequest.transportType = MKDirectionsTransportType.Automobile
        for (k, item) in enumerate(placemarks) {
            if k < (placemarks.count - 1) {
                directionsRequest.setSource(item)
                directionsRequest.setDestination(placemarks[k+1])
                var directions = MKDirections(request: directionsRequest)
                directions.calculateDirectionsWithCompletionHandler { (response:MKDirectionsResponse!, error: NSError!) -> Void in
                    if error == nil {
                        self.myRoute = response.routes[0] as? MKRoute
                        self.mapView.addOverlay(self.myRoute?.polyline)
                    }
                }
            }
        }
    

    Special thanks goes to Anna for pointing me in the right direction.

    enter image description here