Hi,
the problem I am facing is that I have a couple of routes to show on my map. Centering the map and zooming to show one is a breeze
self.mapView.setVisibleMapRect(self.routes[0].polyline.boundingMapRect, animated: true)but when I have more than one polyline how do I zoom and center to the correct map rect?
here I attempt to calculate the size and center of a rectangle encompassing both polylines but the though the size is correct the center is always off. The center is not far off so I wonder if it might be some rounding error or something that I am missing.
// show both lines
let rectRoute1 = self.routes[0].polyline.boundingMapRect
let rectRoute2 = self.routes[1].polyline.boundingMapRect
// Calculate the furthest corners of the box that can enclose both lines
let latMax = max (rectRoute1.origin.x + rectRoute1.size.width/2 , rectRoute2.origin.x + rectRoute2.size.width/2)
let latMin = min(rectRoute1.origin.x - rectRoute1.size.width/2 , rectRoute2.origin.x - rectRoute2.size.width/2)
let lonMax = max (rectRoute1.origin.y + rectRoute1.size.height/2 , rectRoute2.origin.y + rectRoute2.size.height/2)
let lonMin = min (rectRoute1.origin.y - rectRoute1.size.height/2 , rectRoute2.origin.y - rectRoute2.size.height/2)
// Calculate the the center of the box
let origin = MKMapPoint(x: (latMin + ((latMax - latMin)/2)), y: (lonMin + ((lonMax-lonMin)/2)))
let size = MKMapSize(width: (latMax - latMin), height: (lonMax - lonMin))
let maprect = MKMapRect(origin: origin, size: size)
self.mapView.setVisibleMapRect(maprect, animated: true)This is a test project so dont try to gleen any insight into what it is doing the only purpose is to get the framing of the lines correct. Below is the whole ViewController code for the project and it just has two buttons and a map.
import UIKit
import MapKit
class ViewController: UIViewController, MKMapViewDelegate {
@IBOutlet weak var mapView: MKMapView!
var routes:[MKRoute]! = []
override func viewDidLoad() {
super.viewDidLoad()
/
/
mapView.delegate = self
/
let source = MKMapItem( placemark: MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: 59.324658, longitude: 18.062234), addressDictionary: nil))
let destination = MKMapItem( placemark: MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: 59.324296, longitude: 18.076267), addressDictionary: nil))
let destination2 = MKMapItem( placemark: MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: 59.325030, longitude: 18.083155), addressDictionary: nil))
/
let directionRequest = MKDirectionsRequest()
directionRequest.requestsAlternateRoutes = true
directionRequest.source = source
directionRequest.destination = destination
directionRequest.transportType = MKDirectionsTransportType.Walking
/
let directionRequest2 = MKDirectionsRequest()
directionRequest2.requestsAlternateRoutes = true
directionRequest2.source = destination
directionRequest2.destination = destination2
directionRequest2.transportType = MKDirectionsTransportType.Walking
let directions = MKDirections(request: directionRequest)
directions.calculateDirectionsWithCompletionHandler { (directionResponse, error) -> Void in
guard let routes = directionResponse?.routes else {
print("no routes ")
return
}
for route in routes {
self.routes.append(route)
print(" route.name: \(route.name) \n route.advisoryNotices: \(route.advisoryNotices) \n route.distance: \(route.distance) \n route.expectedTravelTime: \(route.expectedTravelTime)")
self.mapView.addOverlay(route.polyline)
self.mapView.setVisibleMapRect(route.polyline.boundingMapRect, animated: true)
}
}
let directions2 = MKDirections(request: directionRequest2)
directions2.calculateDirectionsWithCompletionHandler { (directionResponse, error) -> Void in
guard let routes = directionResponse?.routes else {
print("no routes ")
return
}
for route in routes {
self.routes.append(route)
print(" route.name: \(route.name) \n route.advisoryNotices: \(route.advisoryNotices) \n route.distance: \(route.distance) \n route.expectedTravelTime: \(route.expectedTravelTime)")
self.mapView.addOverlay(route.polyline)
self.mapView.setVisibleMapRect(route.polyline.boundingMapRect, animated: true)
}
}
}
var show1:Bool! = true
@IBAction func showHide1(){
show1 = !show1
if show1 == true {
mapView.addOverlay(routes[0].polyline)
}
else{
mapView.removeOverlay(routes[0].polyline)
}
self.zoomToShowLines()
}
var show2:Bool! = true
@IBAction func showHide2(){
show2 = !show2
if show2 == true {
mapView.addOverlay(routes[1].polyline)
}
else{
mapView.removeOverlay(routes[1].polyline)
}
self.zoomToShowLines()
}
func zoomToShowLines(){
if (show1 == true) && (show2 == true) {
/
let rectRoute1 = self.routes[0].polyline.boundingMapRect
let rectRoute2 = self.routes[1].polyline.boundingMapRect
/
let latMax = max (rectRoute1.origin.x + rectRoute1.size.width/2 , rectRoute2.origin.x + rectRoute2.size.width/2)
let latMin = min(rectRoute1.origin.x - rectRoute1.size.width/2 , rectRoute2.origin.x - rectRoute2.size.width/2)
let lonMax = max (rectRoute1.origin.y + rectRoute1.size.height/2 , rectRoute2.origin.y + rectRoute2.size.height/2)
let lonMin = min (rectRoute1.origin.y - rectRoute1.size.height/2 , rectRoute2.origin.y - rectRoute2.size.height/2)
let origin = MKMapPoint(x: (latMin + ((latMax - latMin)/Double(2))), y: (lonMin + ((lonMax-lonMin)/Double(2))))
let size = MKMapSize(width: (latMax - latMin), height: (lonMax - lonMin))
let maprect = MKMapRect(origin: origin, size: size)
self.mapView.setVisibleMapRect(maprect, animated: true)
}
else{
if (show1 == true){
/
self.mapView.setVisibleMapRect(self.routes[0].polyline.boundingMapRect, animated: true)
}
if (show2 == true){
/
self.mapView.setVisibleMapRect(self.routes[1].polyline.boundingMapRect, animated: true)
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
/
}
func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(polyline: overlay as! MKPolyline)
renderer.strokeColor = UIColor.blueColor()
renderer.lineWidth = 1
return renderer
}
}