Showing multiple annotation with user location at center - ios

all
I need to show multiple annotations within a mapview and zoom to show all this annotations.
I have the code fore that
MKMapRect zoomRect = MKMapRectNull;
int i = 0;
for (Post *post in _allPostsToList) {
if (((post.location2D.latitude == 0.0f)&&(post.location2D.longitude == 0.0f))||(!CLLocationCoordinate2DIsValid(post.location2D))) {
i++;
continue;
}
MyAnnotation *annotation = [[MyAnnotation alloc] initWithpost:post];
annotation.tag = i++;
[mapView addAnnotation:annotation];
MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0, 0);
zoomRect = (MKMapRectIsNull(zoomRect))?pointRect:MKMapRectUnion(zoomRect, pointRect);
}
[mapView setVisibleMapRect:zoomRect animated:YES];
it works fine but, I need one more thing with this, Needs user location blue bubble in the center of the map with showing all the above annotation.
How to do this.
I tried this
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
MKMapRect zoomRect = mapView.visibleMapRect;
MKMapPoint annotationPoint = MKMapPointForCoordinate(newLocation.coordinate);
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0, 0);
zoomRect = (MKMapRectIsNull(zoomRect))?pointRect:MKMapRectUnion(zoomRect, pointRect);
[mapView setVisibleMapRect:zoomRect animated:YES];
[manager stopUpdatingLocation];
}
Its working
But its not centering user location
How to dow this. Can anyone solve this problem

In didUpdateToLocation you get the current visible Rect (zoomRect), then if it is not null you're joining it with the pointRect and zooming/panning to that. How would that end up centered on the pointRect? It would only happen if the two of them had exactly the same center.
If you want to be centered on the userlocation but show all the points you could get the maximum distance of the points from the userlocation and create a maprect with a center and a span to match. But if the points were all off in one direction and the userlocation is in the middle of the screen, the other side of the screen is wasted.

Just a bet; what about accessing your mapView's region and try to set the new center:
MKCoordinateRegion region = mapView.region;
region.center = newLocation.coordinates;
[mapView setRegion:region animated:YES];

Related

How to show current location and all annotation pin on map together iOS 8

How will I show all added annotation and current location blue dot together on map visible rect?
That user can see all pins and his current location when map will load without dragging the map initially. Code for ios8 and ios7.0.
I am using MKMapKit of apple.
try this
MKMapRect zoomRect = MKMapRectNull;
for (id <MKAnnotation> annotation in mapView.annotations) {
MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0, 0);
if (MKMapRectIsNull(zoomRect)) {
zoomRect = pointRect;
} else {
zoomRect = MKMapRectUnion(zoomRect, pointRect);
}
}
[mapView setVisibleMapRect:zoomRect animated:YES];

Exclude userLocation in MapKit search

I am using MapKit with Xcode 6, and everything I have coded up to this point has worked fine. I have a text field that allows users to input any string to search Apple's map.
However, one of the issues I am having is that when the search results are returned as pins on the map, I would like the zoom to fit ONLY the results, excluding the userLocation icon.
Here is the code I have so far. (I have seen similar code with updates of adding lines to include the userLocation, however the code they say should not contain the userLocation is very similar to what I have already...)
if (response.mapItems.count == 0)
NSLog(#"No results");
else
for (MKMapItem *item in response.mapItems)
{
MKMapRect mr = [self.mapView visibleMapRect];
MKMapPoint pt = MKMapPointForCoordinate([annotation coordinate]);
mr.origin.x = pt.x - mr.size.width *0.5; // 0.5
mr.origin.y = pt.y - mr.size.width * 0.75; //0.75
[self.mapView setVisibleMapRect:mr animated:YES];
MKMapRect zoomRect = MKMapRectNull;
for (id <MKAnnotation> annotation in _mapView.annotations)
{
MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 10.4, 10.4);
zoomRect = MKMapRectUnion(zoomRect, pointRect);
}
[_mapView setVisibleMapRect:zoomRect animated:YES];
}
}];
}
Just check to make sure the annotation is not a MKUserLocation object:
MKMapRect zoomRect = MKMapRectNull;
for (id <MKAnnotation> annotation in _mapView.annotations) {
if (![annotation isKindOfClass:[MKUserLocation class]]) {
MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 10.4, 10.4);
zoomRect = MKMapRectUnion(zoomRect, pointRect);
}
}
[_mapView setVisibleMapRect:zoomRect animated:YES];
By the way, I think you want to do this after you finish iterating through the map points, not after each and every one. Though, this means that you should double check to make sure you had one or more map points before doing this.

How to set-up zoom level in iOS?

I am using the code given below to set a region in map view:
CLLocationCoordinate2D loc = (CLLocationCoordinate2D )[self geoCodeUsingAddress:searchBar.text];
CLLocationDistance visibleDistance = 100000;
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(loc, visibleDistance, visibleDistance);
MKCoordinateRegion adjustedRegion = [self.mapView regionThatFits:region];
[self.mapView setRegion:adjustedRegion animated:YES];
[self.mapView setCenterCoordinate:loc];
[self.mapView setZoomEnabled:YES];
It shows the entire map in a small area. How can increment the zoom level?
You can also take a help of span value for MapView. Animate to that small area and span map to zoom for required value.
Use below code:
CLLocationCoordinate2D loc = (CLLocationCoordinate2D )[self geoCodeUsingAddress:searchBar.text];
[UIView animateWithDuration:1.5 animations:^{
MKCoordinateRegion region;
region.center.latitude = loc.latitude;
region.center.longitude = loc.longitude;
region.span.latitudeDelta = 0.15f; // Decrement value to zoom
region.span.longitudeDelta = 0.15f; // Decrement value to zoom
[self.mapView setRegion:region animated:YES];
} completion:^(BOOL finished) { }];
Change the visibleDistance to a smaller number. Experiment until you find something you like.
Finally I have solved the issue by removing
[self.mapView setCenterCoordinate:loc];
I worked well when i removed the above.
Try this,
CLLocationCoordinate2D loc = (CLLocationCoordinate2D )[self geoCodeUsingAddress:searchBar.text];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(loc, visibleDistance, visibleDistance);
region.span.latitudeDelta = 0.15f;
region.span.longitudeDelta = 0.15f;
[self.mapView setRegion:region animated:YES];
[self.mapView setZoomEnabled:YES];

IOS: zoom in mapkit for two annotation point

I want to know if there is a way to have a dynamic zoom when I set in my mapview the blue dot (my position) and another pin...when I load mapview I want to show these two point in the same frame...is it possible? thanks
Yes, it is possible. After adding the second annotation. This sample code should work for any number of annotations:
MKMapRect zoomRect = MKMapRectNull;
NSArray *annotations = [mapView annotations];
for (MKAnnotation *annotation in annotations) {
MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0, 0);
if (MKMapRectIsNull(zoomRect)) {
zoomRect = pointRect;
} else {
zoomRect = MKMapRectUnion(zoomRect, pointRect);
}
}
[mapView setVisibleMapRect:zoomRect animated:YES];

What's the best way to zoom out and fit all annotations in MapKit

Quick background of what I have going on. UIMapView loads and shows a single annotation (Never more than one). On the menu bar, there is a Locate Me button, on tap the userLocation is found and displayed as a second annotation. I then I have MapView zoom out to fit both those annotations in range but I am unable to find a suitable way of doing so. Depending on where the first annotation is placed in relation to the user location, sometimes it doesn't zoom out enough.
For example, if the annotation is North West of the User, it zooms out fine. But if the annotation is South East of the User, it only zooms out enough that they are just getting cut off and you have to manually zoom out a bit more. Here's the code I am using, variation of some others I have found on SO.
CLLocation *whereIAm = mapView.userLocation.location;
float lat = whereIAm.coordinate.latitude;
float lon = whereIAm.coordinate.longitude;
CLLocationCoordinate2D southWest = {[currentLatitude floatValue], [currentLongitude floatValue]};
CLLocationCoordinate2D northEast = southWest;
southWest.latitude = MIN(southWest.latitude, lat);
southWest.longitude = MIN(southWest.longitude, lon);
northEast.latitude = MAX(northEast.latitude, lat);
northEast.longitude = MAX(northEast.longitude, lon);
CLLocation *locSouthWest = [[CLLocation alloc] initWithLatitude:southWest.latitude longitude:southWest.longitude];
CLLocation *locNorthEast = [[CLLocation alloc] initWithLatitude:northEast.latitude longitude:northEast.longitude];
CLLocationDistance meters = [locSouthWest distanceFromLocation:locNorthEast];
MKCoordinateRegion region;
region.center.latitude = (southWest.latitude + northEast.latitude) / 2.0;
region.center.longitude = (southWest.longitude + northEast.longitude) / 2.0;
region.span.latitudeDelta = meters / 111319.5
region.span.longitudeDelta = 7.0;
MKCoordinateRegion savedRegion = [mapView regionThatFits:region];
[mapView setRegion:savedRegion animated:YES];
[locSouthWest release];
[locNorthEast release];
Is there a better way built into MapKit to just zoom out so that both annotations have, lets say half an inch between them at the outer frame? I don't really care if the user has to zoom in after, I just want it to zoom out properly.
-(void)zoomToFitMapAnnotations:(MKMapView*)mapView
{
if([mapView.annotations count] == 0)
return;
CLLocationCoordinate2D topLeftCoord;
topLeftCoord.latitude = -90;
topLeftCoord.longitude = 180;
CLLocationCoordinate2D bottomRightCoord;
bottomRightCoord.latitude = 90;
bottomRightCoord.longitude = -180;
for(MapAnnotation* annotation in mapView.annotations)
{
topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude);
topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude);
bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude);
bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude);
}
MKCoordinateRegion region;
region.center.latitude = topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) * 0.5;
region.center.longitude = topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) * 0.5;
region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 1.1; // Add a little extra space on the sides
region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.1; // Add a little extra space on the sides
region = [mapView regionThatFits:region];
[mapView setRegion:region animated:YES];
}
Taken from: http://codisllc.com/blog/zoom-mkmapview-to-fit-annotations/
(Use it all the time.)
In iOS7 there's a method that does just that. Just call:
[yourMapView showAnnotations:yourAnnotationsArray animated:YES];
Those who do the monotouch c# coding
BasicMapAnnotation is inherit class from MKAnnotation
private void GetRegion(MKMapView mapView)
{
var userWasVisible = mapView.ShowsUserLocation;
mapView.ShowsUserLocation = false; // ignoring the blue blip
// start with the widest possible viewport
var tl = new CLLocationCoordinate2D(-90, 180); // top left
var br = new CLLocationCoordinate2D(90, -180); // bottom right
foreach (var an in mapView.Annotations)
{
// narrow the viewport bit-by-bit
CLLocationCoordinate2D coordinate = ((BasicMapAnnotation) an).Coordinate;
tl.Longitude = Math.Min(tl.Longitude, coordinate.Longitude);
tl.Latitude = Math.Max(tl.Latitude, coordinate.Latitude);
br.Longitude = Math.Max(br.Longitude, coordinate.Longitude);
br.Latitude = Math.Min(br.Latitude, coordinate.Latitude);
}
var center = new CLLocationCoordinate2D
{
// divide the range by two to get the center
Latitude = tl.Latitude - (tl.Latitude - br.Latitude)*0.5,Longitude = tl.Longitude + (br.Longitude - tl.Longitude)*0.5
};
var span = new MKCoordinateSpan
{
// calculate the span, with 20% margin so pins aren’t on the edge
LatitudeDelta = Math.Abs(tl.Latitude - br.Latitude)*1.2,LongitudeDelta = Math.Abs(br.Longitude - tl.Longitude)*1.2
};
var region = new MKCoordinateRegion {Center = center, Span = span};
region = mapView.RegionThatFits(region); // adjusts zoom level too
mapView.SetRegion(region, true); // animated transition
mapView.ShowsUserLocation =
userWasVisible;
}
You can use this code to show all annotations
MKMapRect zoomRect = MKMapRectNull;
for (id <MKAnnotation> annotation in mapView.annotations)
{
MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);
zoomRect = MKMapRectUnion(zoomRect, pointRect);
}
[mapView setVisibleMapRect:zoomRect animated:YES];
if you want to include user location just replace two lines below with the first line of above code
MKMapPoint annotationPoint = MKMapPointForCoordinate(mapView.userLocation.coordinate);
MKMapRect zoomRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);

Resources