Convert MKCoordinateRegion to MKMapRect
To add another implementation to the pile:
- (MKMapRect)MKMapRectForCoordinateRegion:(MKCoordinateRegion)region
{
MKMapPoint a = MKMapPointForCoordinate(CLLocationCoordinate2DMake(
region.center.latitude + region.span.latitudeDelta / 2,
region.center.longitude - region.span.longitudeDelta / 2));
MKMapPoint b = MKMapPointForCoordinate(CLLocationCoordinate2DMake(
region.center.latitude - region.span.latitudeDelta / 2,
region.center.longitude + region.span.longitudeDelta / 2));
return MKMapRectMake(MIN(a.x,b.x), MIN(a.y,b.y), ABS(a.x-b.x), ABS(a.y-b.y));
}
NB: There are many ways to convert between MKMapRect
and MKCoordinateRegion
. This one certainly is not the exact inverse of MKCoordinateRegionMakeWithDistance()
, but approximates it fairly well. So, be careful converting back and forth, because information can be lost.
Converting MKMapRect.origin to longitude and latitude
let rect = mapView.visibleMapRect
let mapPoint = MKMapPointMake(rect.origin.x, rect.origin.y)
let coordinate = MKCoordinateForMapPoint(mapPoint)
print(coordinate.latitude)
print(coordinate.longitude)
Converting a view from MKMapKit to a region
According to the Apple documentation, convert:toRegionFrom:
method:
Converts a rectangle in the specified view’s coordinate system to a
map region.Parameters
rect
The rectangle you want to convert.view The view that serves as the reference coordinate system for the
rect parameter.
So you really need to specify the view for which you provide the coordinates as the second parameter, not the map view :)
So, I believe if you pass in the frame for the radar as the first parameter, you should pass the radar view's parent as the second parameter and that should (theoretically) work.
Basically, if view
is the parent view of which map
(the MKMapView
instance) and radar
(the radar view) are children, I tried the following code:
let frame = radar.frame
let radarRegion = map.convert(frame, toRegionFrom:view)
map.setRegion(radarRegion, animated:true)
Before the above code was executed, this is what the screen looked like:
And after the above code runs:
The basic region is correct though there is a little bit of shifting up.
If this is not what you were expecting with regards to the region selected by the radar view, could you please explain what I might be missing?
What's the difference between MKMapRect and MKCoordinateRegion
A MKCoordinateRegion
is defined using degrees coordinate of type CLLocationCoordinate2D
which represents the latitude and longitude of a point on the surface of the globe.
MKMapRect
represents an actual flat rectangle defined with view coordinate (x, y) on your map view.
You can use functions to do conversions for you like MKCoordinateRegionForMapRect
See http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MapKitFunctionsReference/Reference/reference.html
And to answer your final question, you would use MKCoordinateRegion
which will define what region of the globe's surface you want to see and by definition it will set your zoom level.
Convert MKMapRect to CGRect
The map view has the convertRegion:toRectToView:
method which takes an MKCoordinateRegion
and converts it to a CGRect
relative to the specified view.
If you have an MKMapRect
, first convert it to an MKCoordinateRegion
using the MKCoordinateRegionForMapRect
function and then call convertRegion:toRectToView:
.
Example:
MKCoordinateRegion mkcr = MKCoordinateRegionForMapRect(someMKMapRect);
CGRect cgr = [mapView convertRegion:mkcr toRectToView:self.view];
Remember that although the MKMapRect
for some fixed area will not change as the map is zoomed or panned, the corresponding CGRect
will vary in its origin
and size
.
How to create an MKMapRect given two points, each specified with a latitude and longitude value?
This should do it:
// these are your two lat/long coordinates
CLLocationCoordinate2D coordinate1 = CLLocationCoordinate2DMake(lat1,long1);
CLLocationCoordinate2D coordinate2 = CLLocationCoordinate2DMake(lat2,long2);
// convert them to MKMapPoint
MKMapPoint p1 = MKMapPointForCoordinate (coordinate1);
MKMapPoint p2 = MKMapPointForCoordinate (coordinate2);
// and make a MKMapRect using mins and spans
MKMapRect mapRect = MKMapRectMake(fmin(p1.x,p2.x), fmin(p1.y,p2.y), fabs(p1.x-p2.x), fabs(p1.y-p2.y));
this uses the lesser of the two x and y coordinates for your start point, and calculates the x/y spans between the two points for the width and height.
How can I expand a MKMapRect by a fixed percentage?
In iOS7, rectForMapRect:
and mapRectForRect:
has been deprecated and now are part of the MKOverlayRenderer
class. I'd rather recommend to use the MapView
mapRectThatFits: edgePadding:
methods. 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];
latest 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)
}
Related Topics
What's the Equivalent of the Uisplitviewcontroller in Swiftui
Could Not Find an Overload for "Init" That Accepts the Supplied Arguments in Swift
Swift - Image Data from Ciimage Qr Code/How to Render Cifilter Output
How to Pass Data from One Container to Another, Both Embedded in the Same Uiviewcontroller in Swift
Auto Adjust Custom Uitableviewcell and Label in It to the Text
Set a Maximum Number of Children in Firebase
iOS 9 Orientation Auto-Rotation Animation Not Working, But Always on Main Thread
Reverse an Audio File Swift/Objective-C
How to Consecutively Present Two Alert Views Using Swiftui
How to Create Otp Verification Screen and Detect Delete Backward on Multiple Uitextfield Is Swift
Getter VS Computed Property. What Would Warrant Using One of These Approaches Over the Other
How to Make the View Update Instant in Swiftui
Dateformatter Returns Unexpected Date for Timezone
Upload Files to Dropbox from iOS App with Swift
iOS Wifi Scan, Signal Strength
"Your Binary Is Not Optimized for iPhone 5" (Itms-90096) When Submitting