Zoom mapview to a region where pins are dropped - iphone

If I have 3 pins in a mapview, how will I zoom to these pins, when the map loads. That is, when the map loads I need to have a zoomed view, but the view should accomodate all pins dropped in the map. Its working, when the map has just one pin. But I cant handle zoom with multiple pins. Help needed

The below method will do that,
- (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];
}

I wrote the below code in an App and it is similar to #ElanthiraiyanS Answer
-(void)zoomToFitMapAnnotations:(MKMapView*)mapView insideArray:(NSArray*)anAnnotationArray
{
// NSLog(#"%s", __FUNCTION__);
if([mapView.annotations count] == 0) return;
CLLocationCoordinate2D topLeftCoord;
topLeftCoord.latitude = -90;
topLeftCoord.longitude = 180;
CLLocationCoordinate2D bottomRightCoord;
bottomRightCoord.latitude = 90;
bottomRightCoord.longitude = -180;
for(MKPointAnnotation* annotation in anAnnotationArray)
{
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];
}

you may calc the center of all pins
- (CLLocationCoordinate2D)centerPointFromAnnotationArray:(NSArray *)array
{
CLLocationCoordinate2D coorMax = CLLocationCoordinate2DMake(0, 0);
CLLocationCoordinate2D coorMin = CLLocationCoordinate2DMake(999, 999);
for ( int i = 0 ; i < [array count] ; ++i )
{
LMPoint *a = [array objectAtIndex:i];
if ( ( a.coordinate.latitude != 0.0f ) || ( a.coordinate.longitude != 0.0f ) )
{
if ( a.coordinate.latitude > coorMax.latitude )
{
coorMax.latitude = a.coordinate.latitude;
}
if ( a.coordinate.longitude > coorMax.longitude )
{
coorMax.longitude = a.coordinate.longitude;
}
if ( a.coordinate.latitude < coorMin.latitude )
{
coorMin.latitude = a.coordinate.latitude;
}
if ( a.coordinate.longitude < coorMin.longitude )
{
coorMin.longitude = a.coordinate.longitude;
}
}
}
CLLocationCoordinate2D coorCenter = CLLocationCoordinate2DMake((coorMax.latitude+coorMin.latitude)/2, (coorMax.longitude+coorMin.longitude)/2);
return coorCenter;
}
then zoom at the point with a proper zoomlevel

Related

let annotations fit my MKMapView?

First, thank you, and next, it's my problem, the core code:
for(int idx = 0; idx < route0.polyLine.count; idx++)
{
CLLocationCoordinate2D coordinate = [[route0.polyLine objectAtIndex:idx] coordinate];
minLat = MIN(minLat, coordinate.latitude);
minLon = MIN(minLon, coordinate.longitude);
maxLat = MAX(maxLat, coordinate.latitude);
maxLon = MAX(maxLon, coordinate.longitude);
}
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta = 1.06f*(maxLat - minLat);
span.longitudeDelta = 1.06f*(maxLon - minLon);
CLLocationCoordinate2D location;
location.latitude = (minLat + maxLat)/2;
location.longitude = (minLon + maxLon)/2;
region.span=span;
region.center=location;
[_mapView regionThatFits:region];
[_mapView setRegion:region animated:false];
My attentio is let the annotations on the mapview just fit screen, but if the annotations is too close, will appear:

how to show source and destination at a time in Mapview? [duplicate]

This question already has answers here:
Finding Path/Route Between two points on MapKit in iPhone
(5 answers)
Closed 9 years ago.
I am using MKMapView to show route. I want to zoom out this map so that it will show both source at destination at a time.
how can I zoom out map as per distance so that it will show whole route in one screen.
I am using this code:
double maxLatitude = annotation.coordinate.latitude;
double maxLongitude = annotation.coordinate.longitude;
double minLatitude = annotation.coordinate.latitude;
double minLongitude = annotation.coordinate.longitude;
MKCoordinateRegion region;
region.center.latitude = (minLatitude + maxLatitude) / 2;
region.center.longitude = (minLongitude + maxLongitude) / 2;
region.span.latitudeDelta = (maxLatitude - minLatitude) * MAP_PADDING;
region.span.latitudeDelta = (region.span.latitudeDelta < MINIMUM_VISIBLE_LATITUDE)
? MINIMUM_VISIBLE_LATITUDE
: region.span.latitudeDelta;
region.span.longitudeDelta = (maxLongitude - minLongitude) * MAP_PADDING;
[self.mapView addAnnotation:annotation];
[self.mapView regionThatFits:region];
You can try it by the following method
for (int i = 1; i<[arrayOfPointsToFindDistance count]; i++) {
connection_listdata *detail_connection=[arrayOfPointsToFindDistance objectAtIndex:i];
[self findDistancewithConnecionList:detail_connection];
}
findDistancewithConnecionList method is given below.
-(void)findDistancewithConnecionList:(connection_listdata *)connectionlist{
NSLog(#"sssssss");
CLLocation *oldLoc = [[CLLocation alloc] initWithLatitude:connectionlist.coordinate_connection.latitude longitude: connectionlist.coordinate_connection.longitude];
for(int i =0; i<[mapArray count];i++){
NSLog(#"ghsghshhs");
NSMutableArray *firstArrayTemp = [mapArray objectAtIndex:i];
connection_listdata *detail_connection=[firstArrayTemp objectAtIndex:0];
CLLocation *newLoc = [[CLLocation alloc] initWithLatitude:detail_connection.coordinate_connection.latitude longitude: detail_connection.coordinate_connection.longitude];
CLLocationDistance d = [newLoc distanceFromLocation:oldLoc];
NSLog(#"distanceeeee:%f",d);
if(d <= 500){
NSLog(#"foundddd");
NSLog(#"maparray values= %#",mapArray);
[firstArrayTemp addObject:connectionlist];
[mapArray addObject:firstArrayTemp];
return;
}
[newLoc release];
}
NSMutableArray *array = [[NSMutableArray alloc]init];
[array addObject:connectionlist];
[mapArray addObject:array];
[array release];
[oldLoc release];
return;
}

When i drop multiple pins in map depends on different latitude and longitude values. im getting all pins at one place only

When i drop multiple pins in map depends on different latitude and longitude values. im getting all pins are at one place in map.
I wrote this code for dropping multiple pins .
dealerMapView.mapType = MKMapTypeStandard;
dealerMapView.zoomEnabled =YES;
[dealerMapView setDelegate:nil];
dealerMapView.scrollEnabled = YES;
dealerMapView.showsUserLocation = NO;
CLLocationCoordinate2D location;
for (int i =0; i<[delarsInfoArray count]; i++) {
NSString *lattitudeValue = [[delarsInfoArray objectAtIndex:i]objectForKey:#"LATITUDE" ];
NSString *longitudeValue = [[delarsInfoArray objectAtIndex:i]objectForKey:#"LONGITUDE" ];
CLLocationCoordinate2D pCoordinate ;
pCoordinate.latitude = [lattitudeValue floatValue];
pCoordinate.longitude = [longitudeValue floatValue];
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta = 0.005;
span.longitudeDelta = 0.005;
region.span = span;
region.center = location;
[dealerMapView setRegion:region animated:YES];
myAnnotation1 = [[MyAnnotation alloc] init];
myAnnotation1.coordinate = location;
myAnnotation1.title = [[delarsInfoArray objectAtIndex:i]objectForKey:#"STORE"];
[dealerMapView addAnnotation:myAnnotation1];
}
Try this code:
MKCoordinateSpan span;
span.latitudeDelta = 0.2;
span.longitudeDelta= 0.2;
if( [delarsInfoArray count] > 0 ){
CLLocationCoordinate2D start;
NSString *lattitudeValue = [[delarsInfoArray objectAtIndex:0]objectForKey:#"LATITUDE" ];
NSString *longitudeValue = [[delarsInfoArray objectAtIndex:j]objectForKey:#"LONGITUDE" ];
// create region, consisting of span and location
MKCoordinateRegion mapRegion;
mapRegion.span = span;
mapRegion.center = start;
//Move the map to our location //
[dealerMapView setRegion:mapRegion animated:YES];
}
// do not show pins and annotations more then 200 in the map at a time.
for (int j = 0; j< ([delarsInfoArray count] < 200?[delarsInfoArray count]:200); j++) {
NSString *lattitudeValue = [[delarsInfoArray objectAtIndex:i]objectForKey:#"LATITUDE"];
NSString *longitudeValue = [[delarsInfoArray objectAtIndex:i]objectForKey:#"LONGITUDE" ];
CLLocationCoordinate2D pinLocation;
if(([lattitudeValue floatValue] != 0) && ([longitudeValue floatValue] != 0) ) {
pinLocation.latitude = [lattitudeValue floatValue];
pinLocation.longitude = [longitudeValue floatValue];
if(pinLocation.latitude !=0 && pinLocation.longitude !=0) {
myAnnotation1 = [[MyAnnotation alloc] init];
myAnnotation1.coordinate = location;
myAnnotation1.title = [[delarsInfoArray objectAtIndex:i] objectForKey: #"STORE"];
[dealerMapView addAnnotation:myAnnotation1];
}
}
}
I hope it helps you!! Best Luck. Cheers!!

MKPolyLine not visible on MAP

i have the following code...
DistanceInformation *distanceInformation=[[DistanceInformation alloc]init];
NSArray *latLongArray=[distanceInformation calculateDistance];
[distanceInformation release];
NSLog(#"lat l %#",latLongArray);
NSUInteger length,count;
length = [[latLongArray objectAtIndex:0] count];
//Calcualte center of the map based on current location and airport location
CLLocationCoordinate2D centerOfMap;
centerOfMap.latitude = (27.1766700 + 28.6361600)/2;
centerOfMap.longitude = (78.0080700 + 78.0526500)/2;
//Set map span according to the distance between airport and user location
CGFloat zoomingLevel;
//set the zoom level of the map according to the distance to airport
if([[latLongArray objectAtIndex:2] intValue] <= 50)
zoomingLevel = 0.2;
else if(([[latLongArray objectAtIndex:2] intValue] > 50)&&([[latLongArray objectAtIndex:2] intValue] <= 100))
zoomingLevel = 0.6;
else if(([[latLongArray objectAtIndex:2] intValue]> 100)&&([[latLongArray objectAtIndex:2] intValue] <= 500))
zoomingLevel = 1.7;
else if(([[latLongArray objectAtIndex:2] intValue] > 500)&&([[latLongArray objectAtIndex:2] intValue] <= 1000))
zoomingLevel = 2.0;
else
zoomingLevel = 2.5;
NSLog(#"Center of map: %f, %f",centerOfMap.latitude, centerOfMap.longitude);
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta=zoomingLevel;
span.longitudeDelta=zoomingLevel;
region.span = span;
region.center = centerOfMap;
[mapView setRegion:region animated:TRUE];
[mapView regionThatFits:region];
CLLocationCoordinate2D coords[length];
for (count = 0; count<length; count++) {
NSLog(#"coo ");
coords[count] = CLLocationCoordinate2DMake([[[latLongArray objectAtIndex:0] objectAtIndex:count] doubleValue], [[[latLongArray objectAtIndex:1] objectAtIndex:count] doubleValue]);
}
//Display polyline containing route points as an overlay over the mapview
MKPolyline *polyLine=[MKPolyline polylineWithCoordinates:coords count:length];
NSLog(#"polyLine.pointCount %d",polyLine.pointCount) ;
[mapView addOverlay:polyLine];
[polyLine release];
but the polyline is not visible on map. The polyline is getting initialized with values that I have checked..
Noob mistake on my side... Forgot to implement the MKMapViewDelegate method..
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id < MKOverlay >)overlay{
}

Point to location using compass

I am trying to develop a compass for an appliation which has a set of annotations on a map. I would like to be able to choose an annotation and then have the compass point the user to the chosen location.
I have calculated the degress from the user's location to the location of the annotation and I have the magnetic heading and the true heading of the iPhone. Also I know how to rotate an image.
But I can't figure out what the next step is.
The degrees between the user's location and the annotation location is calculated like this:
// get user location
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager startUpdatingLocation];
[locationManager startUpdatingHeading];
CLLocation *location = [locationManager location];
CLLocationCoordinate2D coordinate = [location coordinate];
float x1 = coordinate.latitude;
float y1 = coordinate.longitude;
float x2 = [annLatitude floatValue];
float y2 = [annLongitude floatValue];
float dx = (x2 - x1);
float dy = (y2 - y1);
if (dx == 0) {
if (dy > 0) {
result = 90;
}
else {
result = 270;
}
}
else {
result = (atan(dy/dx)) * 180 / M_PI;
}
if (dx < 0) {
result = result + 180;
}
if (result < 0) {
result = result + 360;
}
The true and the magnetic heading is retrieved like this:
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {
arrow.transform = CGAffineTransformMakeRotation(newHeading.magneticHeading);
// NSLog(#"magnetic heading: %f", newHeading.magneticHeading);
// NSLog(#"true heading: %f", newHeading.trueHeading);
}
Can anyone tell me what I should do now to make the arrow point to the location - even if the iPhone is rotated?
I had time to play with this again.
This will do it:
- (void)viewDidLoad {
[super viewDidLoad];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager startUpdatingLocation];
[locationManager startUpdatingHeading];
CLLocation *location = [locationManager location];
CLLocationCoordinate2D user = [location coordinate];
[self calculateUserAngle:user];
}
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
CLLocationCoordinate2D here = newLocation.coordinate;
[self calculateUserAngle:here];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {
compass.transform = CGAffineTransformMakeRotation(newHeading.magneticHeading * M_PI / 180);
needle.transform = CGAffineTransformMakeRotation((degrees - newHeading.magneticHeading) * M_PI / 180);
}
-(void) calculateUserAngle:(CLLocationCoordinate2D)user {
locLat = [[targetLocationDictionary objectForKey:#"latitude"] floatValue];
locLon = [[targetLocationDictionary objectForKey:#"longitude"] floatValue];
NSLog(#"%f ; %f", locLat, locLon);
float pLat;
float pLon;
if(locLat > user.latitude && locLon > user.longitude) {
// north east
pLat = user.latitude;
pLon = locLon;
degrees = 0;
}
else if(locLat > user.latitude && locLon < user.longitude) {
// south east
pLat = locLat;
pLon = user.longitude;
degrees = 45;
}
else if(locLat < user.latitude && locLon < user.longitude) {
// south west
pLat = locLat;
pLon = user.latitude;
degrees = 180;
}
else if(locLat < user.latitude && locLon > user.longitude) {
// north west
pLat = locLat;
pLon = user.longitude;
degrees = 225;
}
// Vector QP (from user to point)
float vQPlat = pLat - user.latitude;
float vQPlon = pLon - user.longitude;
// Vector QL (from user to location)
float vQLlat = locLat - user.latitude;
float vQLlon = locLon - user.longitude;
// degrees between QP and QL
float cosDegrees = (vQPlat * vQLlat + vQPlon * vQLlon) / sqrt((vQPlat*vQPlat + vQPlon*vQPlon) * (vQLlat*vQLlat + vQLlon*vQLlon));
degrees = degrees + acos(cosDegrees);
}