How can I extend MKMapRect by a fixed percentage?

I want to get the result of MKMapRect, which is 10-20% larger in all directions than the current visibleMapRect . If it were a CGRect, I would use a CGRectInset with negative x and y values, giving me a backward insert (i.e., a large straight line). Unfortunately, MKMapInset does not support negative insertion values, so this is not so simple.

It might be easier if the values ​​for the display rectangle were recognizable units, but the values ​​of the beginning x and y are of the order of 4.29445e + 07, and the width / height is 2500-3000.

I need about 10 seconds from writing a category to do it manually, but I wanted to make sure that I didn't miss anything. Is there an easier way to extend MKMapRect?

+11
objective-c mapkit
source share
4 answers

In iOS7, rectForMapRect: and mapRectForRect: are deprecated and are now part of the MKOverlayRenderer class. I would prefer to use the MapView methods mapRectThatFits: edgePadding: Here is a sample code:

 MKMapRect visibleRect = self.mapView.visibleMapRect; UIEdgeInsets insets = UIEdgeInsetsMake(50, 50, 50, 50); MKMapRect biggerRect = [self.mapView mapRectThatFits:visibleRect edgePadding:insets]; 

The latest version of Swift for 2017.

 func updateMap() { mkMap.removeAnnotations(mkMap.annotations) mkMap.addAnnotations(yourAnnotationsArray) var union = MKMapRectNull for p in yourAnnotationsArray { // make a small, say, 50meter square for each let pReg = MKCoordinateRegionMakeWithDistance( pa.coordinate, 50, 50 ) // convert it to a MKMapRect let r = mkMapRect(forMKCoordinateRegion: pReg) // union all of those union = MKMapRectUnion(union, r) // probably want to turn on the "sign" for each mkMap.selectAnnotation(pa, animated: false) } // expand the union, using the new #edgePadding call. T,L,B,R let f = mkMap.mapRectThatFits(union, edgePadding: UIEdgeInsetsMake(70, 0, 10, 35)) // NOTE you want the TOP padding much bigger than the BOTTOM padding // because the pins/signs are actually very tall mkMap.setVisibleMapRect(f, animated: false) } 
+26
source share

How to convert visibleMapRect to CGRect using rectForMapRect: getting a new CGRect with CGRectInset and then converting it back to MKMapRect with mapRectForRect: :?

+5
source share

Fixed and fixed user2285781 answer for Swift 4:

  // reference: https://stackoverflow.com/a/15683034/347339 func MKMapRectForCoordinateRegion(region:MKCoordinateRegion) -> MKMapRect { let topLeft = CLLocationCoordinate2D(latitude: region.center.latitude + (region.span.latitudeDelta/2), longitude: region.center.longitude - (region.span.longitudeDelta/2)) let bottomRight = CLLocationCoordinate2D(latitude: region.center.latitude - (region.span.latitudeDelta/2), longitude: region.center.longitude + (region.span.longitudeDelta/2)) let a = MKMapPointForCoordinate(topLeft) let b = MKMapPointForCoordinate(bottomRight) return MKMapRect(origin: MKMapPoint(x:min(ax,bx), y:min(ay,by)), size: MKMapSize(width: abs(ax-bx), height: abs(ay-by))) } // reference: /questions/681745/how-can-i-expand-a-mkmaprect-by-a-fixed-percentage/2642465#2642465 // assuming coordinates that create a polyline as well as a destination annotation func updateMap(coordinates: [CLLocationCoordinate2D], annotation: MKAnnotation) { var union = MKMapRectNull var coordinateArray = coordinates coordinateArray.append(annotation.coordinate) for coordinate in coordinateArray { // make a small, say, 50meter square for each let pReg = MKCoordinateRegionMakeWithDistance( coordinate, 50, 50 ) // convert it to a MKMapRect let r = MKMapRectForCoordinateRegion(region: pReg) // union all of those union = MKMapRectUnion(union, r) } // expand the union, using the new #edgePadding call. T,L,B,R let f = mapView.mapRectThatFits(union, edgePadding: UIEdgeInsetsMake(70, 35, 10, 35)) // NOTE you want the TOP padding much bigger than the BOTTOM padding // because the pins/signs are actually very tall mapView.setVisibleMapRect(f, animated: false) } 
0
source share

Simple and clean solution for Xcode 10+, Swift 4.2

Just set the edge inserts for the map fields as follows:

 self.mapView.layoutMargins = UIEdgeInsets(top: 8, right: 8, bottom: 8, left: 8) self.mapView.showAnnotations(map.annotations, animated: true) 

Please let us know if this works for you.

0
source share

All Articles