Go to/zoom to current location function (MapKit) - iphone

I've got a mapView which zooms to the current location using viewDidLoad :
#define METERS_PER_MILE 1609.344
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
mapView.showsUserLocation=TRUE;
// zoom to a specific area
CLLocationCoordinate2D zoomLocation;
zoomLocation.latitude = -28.994167;
zoomLocation.longitude = 134.866944;
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, 1900*METERS_PER_MILE, 1900*METERS_PER_MILE);
MKCoordinateRegion adjustedRegion = [mapView regionThatFits:viewRegion];
// make sure the Google water mark is always visible
mapView.autoresizingMask =
(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
[mapView setRegion:adjustedRegion animated:YES];
mapView.delegate=self;
searchBar.delegate = self;
}
This works fine. I've added a search bar and a function to jump to a specific address location. This works fine, too. I now want to add a button to jump back to the current location. Can you give me a hand, please?
Cheers

You need to set the center of your map to the current location on tap of that button. Say, like this:
- (IBAction)showCurrentLocation {
[mapView setCenterCoordinate:mapView.userLocation.location.coordinate animated:YES];
}

you can also try:
mapView.userTrackingMode=YES;
mapView.userTrackingMode=NO;

You can link this IBAction to your UIButton,
it's going to move the map on the current location and zoom on it.
#IBOutlet weak var mapView: MKMapView!
#IBAction func zoomToUserCurrentLocation(sender: AnyObject) {
if self.mapView != nil {
self.mapView.setRegion(MKCoordinateRegionMake(
self.mapView.userLocation.coordinate,
MKCoordinateSpanMake(0.1, 0.1)
), animated: true)
}
}
MKCoordinateSpan defines the area spanned by a map region, smaller these values are, closer you zoom on the map.

- (void)showCurrentLocation{
MKMapPoint annotationPoint = MKMapPointForCoordinate(self.mapView.userLocation.coordinate);
MKMapRect zoomRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.0, 0.0);
[self.mapView setVisibleMapRect:zoomRect animated:YES];
}

FOR SWIFT
Add this line in button action yourMKMapView.setUserTrackingMode(.follow, animated: true)
make sure you add yourMKMapView.showsUserLocation = true in viewDidLoad()

Related

MKPointAnnotation unable to coordinate

In my mapView application i am trying to make the annotation, Without adding annotation i am getting the mapView but when i try to add annotation, Only the annotation mark is visible the map becomes invisible.
Before adding Annotation:
Code:
[super viewDidLoad];
mapView = [[MKMapView alloc]initWithFrame:CGRectMake(0, 0, 320, elf.view.frame.size.height)];
mapView.showsUserLocation = YES;
mapView.mapType = MKMapTypeStandard;
mapView.delegate = self;
[self.view addSubview:mapView];
Image:
After Adding Annotation:
Code:
[super viewDidLoad];
mapView = [[MKMapView alloc]initWithFrame:CGRectMake(0, 0, 320, self.view.frame.size.height)];
mapView.showsUserLocation = YES;
mapView.mapType = MKMapTypeStandard;
mapView.delegate = self;
[self.view addSubview:mapView];
MKUserLocation *userLocation = mapView.userLocation;
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.location.coordinate, 20, 20);
[mapView setRegion:region];
MKPointAnnotation *annotation = [[MKPointAnnotation alloc]init];
annotation.coordinate = userLocation.location.coordinate;
annotation.title = #"Here you r";
annotation.subtitle = #"Pondy";
[mapView addAnnotation:annotation];
Image:
I need the annotation appear in the map. Thanks in advance.
Try changing the value of MKCoordinateRegionMakeWithDistance.
it add anotation of your current location...You put span 20, 20. That is very close so only it takes some time to load
mapView1.showsUserLocation = YES;
MKUserLocation *userLocation = mapView1.userLocation;
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.location.coordinate, 200, 200);
[mapView1 setRegion:region];
MKPointAnnotation *annotation = [[MKPointAnnotation alloc]init];
annotation.coordinate = userLocation.location.coordinate;
annotation.title = #"Title";
annotation.subtitle = #"Sub Title";
[mapView1 addAnnotation:annotation];
I hope it will be work for you
Blue screen usually means your current location is in the sea as discussed above.
Please check the current location which you are getting is correct or not.
Usually for showing current location in MKMap we write map.showuserlocation=YES and it shows the bluew dot in the map view if you have to change the annotation pin in your map of the currentlocation you can go in view for annotation methiod and check for the userlocation class and hence change the pin of your userlocation annotation.
I think that at the time you add your annotation, the user location is still unknown:
MKUserLocation *userLocation = mapView.userLocation;
// At that time maybe the userLocation hasn't been retrieved through the GPS yet
...
MKPointAnnotation *annotation = [[MKPointAnnotation alloc]init];
annotation.coordinate = userLocation.location.coordinate;
annotation.title = #"Here you r";
annotation.subtitle = #"Pondy";
[mapView addAnnotation:annotation];
In that case, the annotation position will be 0, 0 and as your map region is also based on the user location from the mapView, you'll end in the middle of the sea at position 0,0.
In order to monitor changes of the user location of the mapView, and then readjust your pin and / or the map region only when you're sure that the userLocation given by the mapView is correct, just implement the MKMapViewDelegate protocol for this selector :
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
then, in the body of your implementation, do what you did previously, but now, you can check if the user location is correct or not, and only adjust your map region and annotation once you're sure that the user location is OK.
The reason is location of your simulator is set to NONE.
Follow these steps, you will get your answer...
`
1) Open your simulator.
2) go to Debug menu
3) Select Location.
3) Select Custom Location. (OR Select location of Apple to skip step
No 4.)
4) Enter your Latitude and Longitude.
5) Delete your app from simulator.
6) Run your project again.
`
Enjoy....

MKMapViewprevent user from zooming out past a certain range

I have a lot of pin annotations on the MKMapView in my app, the iPhone gets very slow and unresponsive when a lot of them are in view on the map. I would like the user to be able to zoom, but not out past a certain level, such as 2km squared or something.
Here's what I've got:
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:YES];
[[BicycleLDNService sharedService] requestLocationForClient:self];
CLLocationCoordinate2D zoomLocation;
CLLocation *deviceLocation = [[BicycleLDNService sharedService] deviceLocation];
zoomLocation.latitude = deviceLocation.coordinate.latitude;
zoomLocation.longitude = deviceLocation.coordinate.longitude;
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, 0.5*kMetresPerKilometre, 0.5*kMetresPerKilometre);
MKCoordinateRegion adjustedRegion = [self.mapView regionThatFits:viewRegion];
[self.mapView setRegion:adjustedRegion animated:YES];
self.mapView.zoomEnabled = YES;
}
Is there some sort of property or delegate method I can employ? Couldn't find anything useful on google or here!
Thanks in advance!
The span defines how much of the map at the given point should be visible and is also how you set the zoom level.
You can access this by using
region.span.latitute=0.5;
region.span.longitude=0.6;
Check the zoom level of the map and then set the zoomEnabled Property NO.
mapView.zoomEnabled=NO;

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
}

'Current location' BUTTON replica of the maps in iPhone

- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views {
for(MKAnnotationView *annotationView in views) {
if(annotationView.annotation == mv.userLocation) {
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta=0.002;
span.longitudeDelta=0.002;
CLLocationCoordinate2D location=mv.userLocation.coordinate;
region.span=span;
region.center=location;
[mv setRegion:region animated:TRUE];
[mv regionThatFits:region];
}
}
Hello all. I have tried searching other posts and websites. In essence I want to duplicate the 'Current location' BUTTON.
Using the above code, I was able to zoom into the users current location. This however is not flawless, sometimes the GPS updates a little late or thinks I am somewhere else, zooms to that location but then the blue dot will shift somewhere off screen to where I really am.
I was wondering is there a way I can add a 'Button', exactly like maps on the iphone. It doesn't need to gain a new zoom etc, simply move to the new updated locaiton. My main source of code would be almost replica to here.
I appreciate any help.
Create a custom annotation with the same graphic. This object must implement MKAnnotationView, and you have to return the custom view for it in the method mapView:viewForAnnotation: of the MKMapViewDelegate. If you want the exact graphic, use the project UIKit-Artwork-Extractor to get it.
Save a reference to the annotation view, subscribe to core location updates, and update the position calling something like:
- (void) animateView:(UIView *)view toPosition:(NSValue*)value
{
CGPoint newCenter = [value CGPointValue];
[UIView animateWithDuration:0.5
animations:^{
view.center = newCenter;
}
completion:^(BOOL finished){ }];
}
Then set the center of the map on the annotation:
- (void)centerMap:(CLLocation *)location {
MKCoordinateRegion region = { { 0.0f, 0.0f }, { 0.0f, 0.0f } };
region.center = location.coordinate;
region.span.longitudeDelta = 0.15f;
region.span.latitudeDelta = 0.15f;
[self.mapView setRegion:region animated:YES];
}

How can I know when MKMapview setRegion:animated: has finished?

I want to set a region on my MKMapView and then find the coordinates corresponding to the NE and SW corner of the map.
This code works just fine to do that:
//Recenter and zoom map in on search location
MKCoordinateRegion region = {{0.0f, 0.0f}, {0.0f, 0.0f}};
region.center = mySearchLocation.searchLocation.coordinate;
region.span.longitudeDelta = 0.01f;
region.span.latitudeDelta = 0.01f;
[self.mapView setRegion:region animated:NO]; //When this is set to YES it seems to break the coordinate calculation because the map is in motion
//After the new search location has been added to the map, and the map zoomed, we need to update the search bounds
//First we need to calculate the corners of the map so we get the points
CGPoint nePoint = CGPointMake(self.mapView.bounds.origin.x + mapView.bounds.size.width, mapView.bounds.origin.y);
CGPoint swPoint = CGPointMake((self.mapView.bounds.origin.x), (mapView.bounds.origin.y + mapView.bounds.size.height));
//Then transform those point into lat,lng values
CLLocationCoordinate2D neCoord;
neCoord = [mapView convertPoint:nePoint toCoordinateFromView:mapView];
CLLocation *neLocation = [[CLLocation alloc] initWithLatitude:neCoord.latitude longitude:neCoord.longitude];
CLLocationCoordinate2D swCoord;
swCoord = [mapView convertPoint:swPoint toCoordinateFromView:mapView];
CLLocation *swLocation = [[CLLocation alloc] initWithLatitude:swCoord.latitude longitude:swCoord.longitude];
The problem is I would like the map zoom to be animated. However, when I set the setRegion:animated to YES, I end up getting the coordinates from the map when it's zoomed way out (i.e., before the animation is completed). Is there any way to get a signal that the animation is done?
Never used mapkit but the MKMapViewDelegate has a method mapView:regionDidChangeAnimated: that looks to be what you're looking for.
Be aware that mapView:regionDidChangeAnimated: will get called every time there's a change, such as when the user moves the map.
I know this is super old, but just in case anyone else comes by looking for an answer, here's an alternative.
The nice thing about this version is that you can run a completion animation at the exact moment the first one is complete instead of guessing/hardcoding it in the callback method since that one is called right away.
[MKMapView animateWithDuration:1.0 animations:^{
[mapView setRegion:mapRegion animated:YES];
} completion:^(BOOL finished) {
[UIView animateWithDuration:1.0 animations:^{
self.mapDotsImageView.alpha = 1.0;
}];
}];
or just
// zoom in...
let km3:CLLocationDistance = 3000
let crTight = MKCoordinateRegionMakeWithDistance(location.coordinate, km3, km3)
MKMapView.animate(withDuration: 1.0, animations: { self.theMap.region = crTight })