简体   繁体   中英

Encapsulate route in setRegion MapKit swift

Im having a mapView with markers (annotations) and a geolocation position for the user. when a user tap one of the markers, I draw a route between the user position and the pin pointed location.

however, the map zoom span on the user position and the only thing I'm able to do is set the map region far from the user. this is not the right approach so I'm willing to find a way to zoom in or out to maximize the route view.

is there a way to do that ?

here is my code:

//Map socket coming from storyboard @IBOutlet weak var mapView: MKMapView!

//Geolocation variables
var locationManager = CLLocationManager()
var destination: MKMapItem?

in viewDidLoad

//Setting up delegate and CoreLocaton setup
        locationManager = CLLocationManager()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()

mapView.delegate = self
        mapView.showsUserLocation = true

let initialLocation = CLLocation(latitude: 45.5215374, longitude: -73.5811606)

        let regionRadius: CLLocationDistance = 2000
        func centerMapOnLocation(location: CLLocation) {
            let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate,
                regionRadius * 2.0, regionRadius * 2.0)
            mapView.setRegion(coordinateRegion, animated: true)
        }

        //Ask the map to center itself
        centerMapOnLocation(initialLocation)

the delegates

//MAP DELEGATES
    func mapView(mapView: MKMapView!,
        didSelectAnnotationView view: MKAnnotationView!){

            //remove existing routes
            mapView.removeOverlays(mapView.overlays)

            //call for new route
            var destination = MKPlacemark(coordinate: view.annotation.coordinate, addressDictionary: nil)
            getDirection(destination)
    }


    //INTERACTION WITH ANNOTATIONS (MARKER)
    func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!,
        calloutAccessoryControlTapped control: UIControl!) {

            if control == view.rightCalloutAccessoryView {
                println("Disclosure Pressed! \(view.annotation.subtitle)")

                if let cpa = view.annotation as? MapArtwork {
                    println("cpa.imageName")
                }
            }

    }

    //UPDATE LOCATION
    func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {

        if (!locations.isEmpty)
        {

            let myLocation  = locations[0] as! CLLocation

            mapView.setRegion(MKCoordinateRegionMake(CLLocationCoordinate2DMake(myLocation.coordinate.latitude, myLocation.coordinate.longitude),
                MKCoordinateSpanMake(0.06, 0.06)), animated: true)
        }

        locationManager.stopUpdatingLocation()

    }

    //GET DIRECTION BETWEEN GEOPOSITION AND TOUCHED MARKER
    func getDirection(location:MKPlacemark){
        println("getting direction")
        destination = MKMapItem(placemark:location)

        let request = MKDirectionsRequest()
        request.setSource(MKMapItem.mapItemForCurrentLocation())
        request.setDestination(destination!)
        request.requestsAlternateRoutes = false

        let directions = MKDirections(request: request)

        directions.calculateDirectionsWithCompletionHandler({(response:
            MKDirectionsResponse!, error: NSError!) in

            if error != nil {
                // Handle error
                println(error)
            } else {
                self.showRoute(response)
            }

        })
    }

here is the part where I set the map region when displaying a route.

    //DISPLAY ROUTE OVERLAY
    func showRoute(response: MKDirectionsResponse) {
        println("showing route")
        for route in response.routes as! [MKRoute] {
            mapView.addOverlay(route.polyline,
                level: MKOverlayLevel.AboveRoads)

            for step in route.steps {
                println(step.instructions)
            }
        }
        let userLocation = mapView.userLocation
        let region = MKCoordinateRegionMakeWithDistance(
            userLocation.location.coordinate, 6000, 6000)

        mapView.setRegion(region, animated: true)
    }

    func mapView(mapView: MKMapView!, rendererForOverlay
        overlay: MKOverlay!) -> MKOverlayRenderer! {
            let renderer = MKPolylineRenderer(overlay: overlay)

            renderer.strokeColor = UIColor(red: 8.0/255.0, green: 47.0/255.0, blue: 62.0/255.0, alpha: 1.0)
            renderer.lineWidth = 5.0
            return renderer
    }

ok so I found something that do the trick, but maybe it's not the best idea.

In the following function

//DISPLAY ROUTE OVERLAY
    func showRoute(response: MKDirectionsResponse) {
        println("showing route")
        for route in response.routes as! [MKRoute] {
            mapView.addOverlay(route.polyline,
                level: MKOverlayLevel.AboveRoads)

            for step in route.steps {
                println(step.instructions)
            }
        }

        let userLocation = mapView.userLocation
        let region = MKCoordinateRegionMakeWithDistance(
            userLocation.location.coordinate, 6000, 6000)

        mapView.setRegion(region, animated: true)
    }

remove the last part:

let userLocation = mapView.userLocation
            let region = MKCoordinateRegionMakeWithDistance(
                userLocation.location.coordinate, 6000, 6000)

            mapView.setRegion(region, animated: true)

and in the following delegate:

func mapView(mapView: MKMapView!, rendererForOverlay
        overlay: MKOverlay!) -> MKOverlayRenderer! {
            let renderer = MKPolylineRenderer(overlay: overlay)

            renderer.strokeColor = UIColor(red: 8.0/255.0, green: 47.0/255.0, blue: 62.0/255.0, alpha: 1.0)
            renderer.lineWidth = 5.0
            return renderer
    }

add this:

let mapRect = MKPolygon(points: renderer.polyline.points(), count: renderer.polyline.pointCount)
            mapView.setVisibleMapRect(mapRect.boundingMapRect, edgePadding: UIEdgeInsets(top: 50.0,left: 50.0,bottom: 50.0,right: 50.0), animated: true)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM