MKCoordinateregion's center changes when span changed - iphone - iphone

I have a MKCoordinateregion called region. I want to change span of this region without changing it's center. I am using following method to change zoom.
-(void) changeZoom
{
NSLog(#"before zoom span, center are %f, %f,%f,%f", region.span.latitudeDelta, region.span.longitudeDelta, mymap.centerCoordinate.latitude, mymap.centerCoordinate.longitude);
region.span.latitudeDelta = current_factor ;
region.span.longitudeDelta = current_factor ;
region.center.latitude = mymap.centerCoordinate.latitude ;
region.center.longitude = mymap.centerCoordinate.longitude ;
[mymap setRegion:region animated:TRUE];
NSLog(#"after zoom span, center are %f, %f,%f,%f", region.span.latitudeDelta, region.span.longitudeDelta, mymap.centerCoordinate.latitude, mymap.centerCoordinate.longitude);
}
Log shows :
before zoom span, center are 0.021950, 0.021950,19.068080,72.838111
after zoom span, center are 0.043901, 0.043901,19.068040,72.838154
This method set's span accurately as desired.But I dont want any change in the center's coordinate, Because when I zoom out and then zoom back I end up at a location different from starting location.
Is there any method so that zoom in and out are possible without any change in center?
Thanks for any help in advance.

Your before and after center coordinates are almost exactly the same, so it shouldn't be a problem. If you really want the exact same center coordinates, call setCenterCoordinate:animated: right after you use setRegion:animated: and pass some saved center coordinates.
CLLocationCoordinate2D originalCenter = mymap.centerCoordinate;
// ... adjust region
[mymap setCenterCoordinate:originalCenter animated:NO];
Also, you should use YES instead of TRUE for booleans:
[mymap setRegion:region animated:YES];

You need to adjust the region of the map to make sure the aspect ratio fits the frame size of the map view.
Once the region with the desired center is calculated, adjust the region as,
MKCoordinateRegion adjustedRegion = [mymap regionThatFits:region];
[mymap setRegion:adjustedRegion animated:TRUE];
See docs.

Related

MapKit iPhone display Zoom Controls

Is it possible using MapKit to show a map in iPhone, like i´m doing, to display zoom controls on the map?
If not, what are the flags or methods i should use to increase and diminish the zoom, so i can created methods which will do this at the push of a button.
There aren't any built-in controls for it.
A couple of suggestions:
You can predefine some spans and store them in an array somewhere and then store your position in that array as well. Zooming in/out changes the position and gets the span.
Zooming in takes the current span and divides by 2, zooming out multiplies by 2.
You change the span in the region of the mapView. So you have to:
Get the region of the mapView.
Get the span of the region.
Change the span to what you want.
Set the regions span to the new span.
Set the mapView's region to the new region.
Here's some code for suggestion 2:
MKCoordinateRegion region = mapView.region;
MKCoordinateSpan span;
span.latitudeDelta = region.span.latitudeDelta*2;
span.longitudeDelta = region.span.longitudeDelta*2;
region.span = span;
[mapView setRegion:region animated:TRUE];
For swift 4, this is what I use:
func zoom(_ zoomin : Bool) {
var region = mapView.region;
var span = MKCoordinateSpan();
span.latitudeDelta = zoomin ? region.span.latitudeDelta / 2 : region.span.latitudeDelta * 2;
span.longitudeDelta = zoomin ? region.span.longitudeDelta / 2 : region.span.longitudeDelta * 2;
region.span = span;
mapView.setRegion(region, animated: true);
}
Off the top of my head I don't remember (at work on a windows box) if there is a switch to display the zoom controls. I assume you are talking about displaying the level of zoom, because by default you can pinch/spread the view for zoom.
If there isn't a switch to display the controls, then you will need to create a custom view layer and put it on top of the mapkit view. Then you will need to call the different functions to change the zoom level.
Those functions are all documented in the mapkit docs. Just do a search for MapKit in the documentation center.
Edit:
http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MKMapView_Class/MKMapView/MKMapView.html#//apple_ref/doc/uid/TP40008205
According to the docs there isn't a switch to display the controls, but the zoom enabled property lets you turn the ability on and off.
So you can subscribe to the delegate function regionWillChange and use the mapView object to get the zoom level and then set your graphics accordingly.
I don't think you should do that, the expected way to zoom in and out is using the pinch gestures. However if you still want to go ahead and do it, you should place yourself the buttons over the MKMapView, and then with those modify the region property of the MKMapView

Move MKMapView point to pixel coordinates

I have a quick question. I am using a custom view as a callout accessory for my map view. I am having some issues with getting the annotation to move to the right bottom corner of the said view. I am currently trying to get the CGPoint coords of the selected annotation, but beyond that I've drawn a blank Any help would be greatly appreciated.
The current code I'm using (I know it is incorrect is:)
CGPoint bottomLeftPoint = CGPointMake(xOffset,[self.internalAnnotationCallout view].frame.size.height);
CLLocationCoordinate2D bottomLeftCoord = [self.branchLocation convertPoint:bottomLeftPoint toCoordinateFromView:self.branchLocation];
MKCoordinateSpan span = {latitudeDelta: kMapMultiLatDelta, longitudeDelta: kMapMultiLatDelta};
MKCoordinateRegion region = {bottomLeftCoord, span};
[self.branchLocation setRegion:region animated:YES];
//[self.branchLocation setCenterCoordinate:newCenterCoordinate animated:YES];
EDIT:
Ok so I messed around with this a little and was able to to put something together that seems to work, hoping that I now actually understand what you're trying to achieve!
- (void)shiftToCorner{
//ignore "Annotation", this is just my own custom MKAnnotation subclass
Annotation *currentAnnotation = [[mapView selectedAnnotations] objectAtIndex:0];
[mapView setCenterCoordinate:currentAnnotation.coordinate];
CGPoint fakecenter = CGPointMake(20, 20);
CLLocationCoordinate2D coordinate = [mapView convertPoint:fakecenter toCoordinateFromView:mapView];
[mapView setCenterCoordinate:coordinate animated:YES];
}
Let me quickly explain what this does; Let's say you want your annotation to move to a position 20 points in from the right edge and 20 points up from the bottom edge of the map view. If you think about it, if the current annotation is at the center of the map view, then the distance to this point is the same as the distance to (20, 20). This means that we can send our annotation to this point by first centering our map view on the annotation, then animating to (20, 20).

GPS location on map in application

I have one application that shows maps. I need to show current position of user and manage to do that with
[mapView setShowsLocation:YES];
But when I zoom In or zoom Out map it needs a lot of time to show me that blue pin again.
Is it normal or I need to put something else to keep that blue pin on screen all time???
Thanks.
[self setCurrentLocation:self._mapView.userLocation.location.coordinate withZoom:1.0];
self._mapView.showsUserLocation = YES;
- (void)setCurrentLocation:(CLLocationCoordinate2D)coord withZoom:(float)zoomLevel {
MKCoordinateRegion region = self._mapView.region;
region.span.latitudeDelta = self.defaultSpanLevel.latitudeDelta*zoomLevel;
region.span.longitudeDelta = self.defaultSpanLevel.longitudeDelta*zoomLevel;
region.center = coord;
[self._mapView setRegion:region animated:YES];
}
You can use this in view will appear Method
Then You can use mapview delegate methods....
region did change animated:YES { and set map's region here.... take
current user location as region centre.. }
This will solve your problem
}

Continuous zooming with MKMapView?

I am working with a MKMapView thats visible area (zoom level) is set with a slider.
I set the visible area with a MKCoordinateRegion and setRegion:animated:.
The problem is that I don't seem to be able to get extremely precise control over the visible area. It's as if the latitude\longitude deltas snap to the default ~21 zoom levels provided by Google.
What I really want is similar to the behavior of the Map.app when pinching to zoom. It scales the view until the threshold for a new zoom level is reached, and then it renders the new map level.
Is there a simple way to access\emulate this behavior? How does it work?
Code I'm using:
MKCoordinateRegion region;
MKCoordinateSpan span;
CLLocationCoordinate2D center = {45.475969,-73.64095};
region.center = center;
span.latitudeDelta = 0.01;
span.longitudeDelta = 0.01;
region.span = span;
[mapView setRegion:region animated:TRUE];
If I use a delta of 0.01 or 0.013, I get the exact same map.
The simple answer is that MapKit does not allow you to programatically set a zoom level other than the default 21 levels supplied by google. The region span you set will always "snap" to the closest one.
Are you using setRegion:animated: ?
http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MKMapView_Class/MKMapView/MKMapView.html#//apple_ref/occ/instm/MKMapView/setRegion:animated:
You can set mapview's visibleMapRect to achieve continuous zooming.
Following code shows how to zoom in 1 level (it's a subclass of a MKMapView so self is an instance of MKMapView).
MKMapRect visibleRect = self.visibleMapRect;
MKMapSize size = visibleRect.size;
CGFloat aspectRatio = size.width / size.height;
CGPoint center = CGPointMake(visibleRect.origin.x + size.width/2, visibleRect.origin.y + size.height/2);
CGFloat zoomedHeight = size.height / 2; // By divide by 2, will zoom in exact 1 level
CGFloat zoomedWidth = zoomedHeight * aspectRatio;
visibleRect = MKMapRectMake(center.x - zoomedWidth/2, center.y - zoomedHeight/2, zoomedWidth, zoomedHeight);
self.visibleMapRect = visibleRect;

How to get left-top and right-buttom latitude and longitude of map in MapKit For iPad?

i'm looking for answer about getting latitude and longitude from uimapkit. there is same problem that has been answered, but it didn't give right coordinate. http://yit.me/3ddp73
it's code from thread i'm linking above.
CLLocationCoordinate2D topLeft, bottomRight;
topLeft = [mapView convertPoint:CGPointMake(0,0) toCoordinateFromView:mapView];
CGPoint pointBottomRight = CGPointMake(mapView.frame.size.width, mapView.frame.size.height);
bottomRight = [mapView convertPoint:pointBottomRight toCoordinateFromView:mapView];
NSLog(#"topleft = %f", topLeft);
NSLog(#"bottom right = %f", bottomRight);
any idea to fix this issue ?
thanks
The map view has a region property.
MKCoordinateRegion region = mapView.region;
the region contains the center and the 2D span, so
CLLocationCoordinate2D topLeft = CLLocationCoordinate2DMake(
region.center.latitude - region.span.latitudeDelta/2,
region.center.longitude - region.span.longitudeDelta/2,
);
etc.
The original solution is close. The view's coordinate system has the origin at the bottom left. Therefore CGPoint(0,0) is actually bottom left, not top. And the other coordinate will be your top right.