show multiple annotation in map view - ios

i am new to map view in ios sdk. i want to show multiple annotation in map view
using lat and long.basically all lat and long are coming from server side in
json format. i am parsing all lat and long and saving it in different array.
but how to show all annotation at single time. i am able to show only one annotation
at a time.Below is code for single annotation i am using,
zoomLocation.latitude = latmpa.doubleValue;
zoomLocation.longitude = logmpa.doubleValue;
annotationPoint = [[MKPointAnnotation alloc] init];
annotationPoint.coordinate = zoomLocation;
annotationPoint.title = #"masjid....";
[mapView selectAnnotation:annotationPoint animated:YES];
[mapView addAnnotation:annotationPoint];
mapView.centerCoordinate = annotationPoint.coordinate;
MKCoordinateSpan span;
span.latitudeDelta = 1.5;
span.longitudeDelta = 1.0;
MKCoordinateRegion newRegion;
newRegion.center = zoomLocation;
newRegion.span = span;
[mapView setRegion:newRegion animated:YES];

Try This
for ( int i=0; i<[yourLatLongarray count]; i++)
{
CLLocationCoordinate2D coord;
coord.latitude=[[NSString stringWithFormat:#"%#",[yourLatitudeArray objectAtIndex:i]] floatValue];
coord.longitude=[[NSString stringWithFormat:#"%#",
[yourLongitudeArray objectAtIndex:i]] floatValue];
MKCoordinateRegion region1;
region1.center=coord;
region1.span.longitudeDelta=20 ;
region1.span.latitudeDelta=20;
[mapview setRegion:region1 animated:YES];
NSString *titleStr =[namesArr objectAtIndex:i] ;
// NSLog(#"title is:%#",titleStr);
MyAnnotation* annotObj =[[MyAnnotation alloc]initWithCoordinate:coord title:titleStr];
[mapview addAnnotation:annotObj];
}
MyAnnotation.h is
#interface MyAnnotation : NSObject <MKAnnotation>
{
CLLocationCoordinate2D coordinate;
NSString *title;
NSString *subTitle;
NSString *time;
}
#property (nonatomic)CLLocationCoordinate2D coordinate;
#property (nonatomic, retain) NSString *title;
#property (nonatomic, retain) NSString *subTitle;
#property (nonatomic,retain) NSString *time;
-(id)initWithCoordinate:(CLLocationCoordinate2D) c title:(NSString *) t subTitle:(NSString *)timed time:(NSString *)tim;
-(id)initWithCoordinate:(CLLocationCoordinate2D) c title:(NSString *)tit;
#end
MyAnnotation.m is
#implementation MyAnnotation
#synthesize coordinate;
#synthesize title;
#synthesize time;
#synthesize subTitle;
-(id)initWithCoordinate:(CLLocationCoordinate2D) c title:(NSString *) t subTitle:(NSString *)timed time:(NSString *)tim
{
self.coordinate=c;
self.time=tim;
self.subTitle=timed;
self.title=t;
return self;
}
-(id)initWithCoordinate:(CLLocationCoordinate2D) c title:(NSString *)tit
{
self.coordinate=c;
self.title=tit;
return self;
}
#end

Get all the latitudes and longitudes in array and go for the for loop as user1673099 said,
and add the following zoomtofit code for zooming the mapview to cover all the annotations in the mapview by calling the method,
[self zoomToFitMapAnnotations:self.mapView];
- (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(id<MKAnnotation> 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;
region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.1;
region = [mapView regionThatFits:region];
[mapView setRegion:region animated:YES];
}

Related

How to add Coordinates to CLLocationCoordinate2D from Dynamic NSMutableArray?

I have a MapView in which I would like to add annotations and a route from defined coordinates that I add from a Textfield and store in an NSMutableArray.
Now I'm able to show the route from multiple coordinates but only when I insert them in my code as follow :
-(void)loadMap{
int Coordinates;
//MAP
CLLocationCoordinate2D coordinateArray[Coordinates];
coordinateArray[0] = CLLocationCoordinate2DMake(LatA, LongA);
coordinateArray[1] = CLLocationCoordinate2DMake(LatB, LongB);
coordinateArray[2] = CLLocationCoordinate2DMake(LatC, LongC);
coordinateArray[3] = CLLocationCoordinate2DMake(LatD, LongD);
self.routeLine = [MKPolyline polylineWithCoordinates:coordinateArray count:Coordinates];
[MapViewHome setVisibleMapRect:[self.routeLine boundingMapRect]]; //If you want the route to be visible
[MapViewHome addOverlay:self.routeLine];
MapViewHome.mapType = MKMapTypeHybrid;
[self zoomToFitMapAnnotations:MapViewHome];
}
To Add Annotations I do this:
-(MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay
{
if(overlay == self.routeLine)
{
if(nil == self.routeLineView)
{
self.routeLineView = [[MKPolylineView alloc] initWithPolyline:self.routeLine];
self.routeLineView.fillColor = [UIColor purpleColor];
self.routeLineView.strokeColor = [UIColor purpleColor];
self.routeLineView.lineWidth = 5;
}
return self.routeLineView;
}
return nil;
}
-(void)AddAnotations{
DeparturePoint = [[MKPointAnnotation alloc] init];
DeparturePoint.coordinate = CLLocationCoordinate2DMake(LatA, LongA);
DeparturePoint.title = [NSString stringWithFormat:#"A"];
[MapViewHome addAnnotation:DeparturePoint];
ArrivalPoint = [[MKPointAnnotation alloc] init];
ArrivalPoint.coordinate = CLLocationCoordinate2DMake(LatB, LongB);
ArrivalPoint.title = [NSString stringWithFormat:#"B"];
[MapViewHome addAnnotation:ArrivalPoint];
C = [[MKPointAnnotation alloc] init];
C.coordinate = CLLocationCoordinate2DMake(LatC, LongC);
C.title = [NSString stringWithFormat:#"C"];
[MapViewHome addAnnotation:C];
D = [[MKPointAnnotation alloc] init];
D.coordinate = CLLocationCoordinate2DMake(LatD, LongD);
D.title = [NSString stringWithFormat:#"D"];
[MapViewHome addAnnotation:D];
}
NOW I would like to get Insert my Dynamic NSMutableArray in the LoadMap function in order to refresh the mapView and get a longer Route ! Any Idea ?
Here's the first solution I could think of...
First we wrap the CLLocationCoordinate2D into an object. For this I've made a wrapper class called KBLocationWrapper. Here's the interface:
#interface KBLocationWrapper : NSObject
#property (nonatomic, assign) CLLocationCoordinate2D coordinate;
#end
Next generate the NSMutableArray ...
NSMutableArray *locationCoordinatesArray = [NSMutableArray array];
Then add each coordinate to the array via the object wrapper...
KBLocationWrapper *locationWrapper = [[KBLocationWrapper alloc] init];
locationWrapper.coordinate = CLLocationCoordinate2DMake(latitude, longitude);
[locationCoordinatesArray addObject:locationWrapper];
Finally, figure out how you're going to get the locationCoordinatesArray into the -loadMap method, and then loop through each object and map the coordinate property to its respective place in coordinateArray... (I would write a separate method for this functionality, but for demonstration purposes it's going straight into -loadMap)
-(void)loadMap{
....
int Coordinates = (int)[locationCoordinatesArray count];
CLLocationCoordinate2D coordinateArray[Coordinates];
// loop through coordinates
for (int i = 0; i < Coordinates; ++i) {
// write data from the CLLocationCoordinate2D stored in the wrapper
// to the primitive data array 'coordinateArray'
coordinateArray[i] = [locationCoordinatesArray[i] coordinate];
}
// then generate the routeLine.
self.routeLine = [MKPolyline polylineWithCoordinates:coordinateArray count:Coordinates];
...
}
I add an object to NSMutableArray "NSLat" when i Unwind from another ViewController:
- (IBAction)UnwindPoiint:(UIStoryboardSegue *)segue {
float latitude;
float longitude;
NSString*PointName;
NSString*coordinates;
AddPointViewController *messageViewController = segue.sourceViewController;
PointName = messageViewController.PointBack;
latitude = [messageViewController.PointLatitude floatValue];
longitude = [messageViewController.PointLongitude floatValue];
KBLocationWrapper *locationWrapper = [[KBLocationWrapper alloc] init];
locationWrapper.coordinate = CLLocationCoordinate2DMake(latitude, longitude);
[NSLat addObject:locationWrapper];
coordinates = [NSString stringWithFormat:#"%f,%f,%#",latitude,longitude,PointName];
// [NSLat addObject:coordinates];
[self AddAnotations];
[self loadMap];
[FlightLogTable reloadData];
NSLog(#"%#",coordinates);
NSLog(#"%lu",(unsigned long)NSLat.count);
}
And I add Annotations & load Map as filed :
-(void)AddAnotations{
for(int idx = 0; idx < NSLat.count; idx++)
{
// break the string down even further to latitude and longitude fields.
NSString* currentPointString = [NSLat objectAtIndex:idx];
NSArray* latLonArr = [currentPointString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#","]];
CLLocationDegrees latitude = [[latLonArr objectAtIndex:0] doubleValue];
CLLocationDegrees longitude = [[latLonArr objectAtIndex:1] doubleValue];
NSString*Name = [NSString stringWithFormat:#"%#",[latLonArr objectAtIndex:2]];
DeparturePoint = [[MKPointAnnotation alloc] init];
DeparturePoint.coordinate = CLLocationCoordinate2DMake(latitude, longitude);
DeparturePoint.title = Name;
[MapViewHome addAnnotation:DeparturePoint];
}
[self loadMap];
}
-(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(MKPointAnnotation*annotation in MapViewHome.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) * 2; // Add a little extra space on the sides
region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 2; // Add a little extra space on the sides
region = [mapView regionThatFits:region];
[MapViewHome setRegion:region animated:YES];
}
-(void)loadMap{
int Coordinates = (int)[NSLat count];
CLLocationCoordinate2D coordinateArray[Coordinates];
// loop through coordinates
for (int i = 0; i < Coordinates; ++i) {
// write data from the CLLocationCoordinate2D stored in the wrapper
// to the primitive data array 'coordinateArray'
coordinateArray[i] = [NSLat[i] coordinate];
}
// then generate the routeLine.
self.routeLine = [MKPolyline polylineWithCoordinates:coordinateArray count:Coordinates];
[MapViewHome setVisibleMapRect:[self.routeLine boundingMapRect]]; //If you want the route to be visible
[MapViewHome addOverlay:self.routeLine];
MapViewHome.mapType = MKMapTypeHybrid;
[self zoomToFitMapAnnotations:MapViewHome];
}

Need to showing screen that show both CLLocation pins

I have mapView that suppose to contain both user location pin and object pin. What i want, is show screen that contain both pins, no matter how large distance is between them (it suppose to be not too much). For some reason i can't show user location, screen moves to some point in the ocean. There is my code and attempts to get it:
-(MKCoordinateRegion)regionForAnnotations:(NSArray*)annotations{
MKCoordinateRegion region;
if ([annotations count] ==0){
region = MKCoordinateRegionMakeWithDistance(self.mapView.userLocation.coordinate, 1000, 1000);
} else if ([annotations count] ==1 ){
id <MKAnnotation> annotation = [annotations lastObject];
region = MKCoordinateRegionMakeWithDistance(annotation.coordinate, 1000, 1000);
} else {
CLLocationCoordinate2D topLeftCord;
topLeftCord.latitude = -90;
topLeftCord.longitude = 180;
CLLocationCoordinate2D bottomRightCord;
bottomRightCord.latitude = 90;
bottomRightCord.longitude = -180;
for (id <MKAnnotation> annotation in annotations){
topLeftCord.latitude = fmax(topLeftCord.latitude, annotation.coordinate.latitude);
topLeftCord.longitude = fmin(topLeftCord.longitude, annotation.coordinate.longitude);
bottomRightCord.latitude = fmin(bottomRightCord.latitude, annotation.coordinate.latitude);
bottomRightCord.longitude = fmax(bottomRightCord.longitude, annotation.coordinate.longitude);
}
const double extraSpace = 1.1;
region.center.longitude = topLeftCord.longitude - (topLeftCord.longitude - bottomRightCord.longitude)/2.0;
region.center.latitude = topLeftCord.latitude - (topLeftCord.latitude - bottomRightCord.latitude)/2.0;
region.span.latitudeDelta = fabs(topLeftCord.latitude - bottomRightCord.latitude)*extraSpace;
region.span.longitudeDelta = fabs(topLeftCord.longitude - bottomRightCord.longitude)*extraSpace;
}
return [self.mapView regionThatFits:region];
}
-(MKAnnotationView*)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
//2
static NSString *identifier = #"Location";
MKPinAnnotationView *annotationView = (MKPinAnnotationView*)[self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil){
annotationView = [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:identifier];
}
//3
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
annotationView.animatesDrop = YES;
annotationView.pinColor = MKPinAnnotationColorPurple;
//4
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton addTarget:self action:#selector(getRoute:) forControlEvents:UIControlEventTouchUpInside];
annotationView.rightCalloutAccessoryView = rightButton;
return annotationView;
};
-(void)setEntityCoordiate{
CLLocationCoordinate2D location;
location.latitude = [self.latitudeString doubleValue];
location.longitude = [self.longitudeString doubleValue];
CLLocationCoordinate2D user;
user.latitude = self.mapView.userLocation.coordinate.latitude;
user.latitude = self.mapView.userLocation.coordinate.longitude;
CLLocation *userLocation = [[CLLocation alloc]initWithLatitude:user.latitude longitude:user.longitude ];
CLLocation *entityLocation = [[CLLocation alloc]initWithLatitude:location.latitude longitude:location.longitude];
MKCoordinateSpan span;
span.latitudeDelta = 100;
span.longitudeDelta = 100;
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(location, 400, 400);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
annotation.coordinate = location;
annotation.title = _titleForEntity;
[_locations addObject:userLocation];
[_locations addObject:entityLocation];
[_mapView addAnnotation:annotation];
}
-(void)getRoute:(UIButton*)button{
MKCoordinateRegion region = [self regionForAnnotations:_locations];
[self.mapView setRegion:region animated:YES];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self setEntityCoordiate];
}
There is might be "too much" code, but i can't figure out where i made mistake i paste it all. I think i might have problem with array containing location objects.
How to finally make screen with that two locations? Any advice would be appreciated, thanks!
Try creating an area flyTo that will "contain" your given annotations:
MKMapRect flyTo = MKMapRectNull;
for (id <MKAnnotation> annotation in annotations) {
MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0, 0);
if (MKMapRectIsNull(flyTo)) {
flyTo = pointRect;
} else {
flyTo = MKMapRectUnion(flyTo, pointRect);
}
}
mapview.visibleMapRect = flyTo;

Zooming to users location [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm making this app where people can see what tourist attractions are near them and I'm a bit stuck!
I need it to load the user's current location when the app is loaded and zoom to it, however it's not doing so.
Sorry to be a bit blunt but I really don't know how to set it up so that it will work with both the button and load their location automatically.
https://pbs.twimg.com/media/BcRSTk0CAAEV47Q.jpg
ViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface ViewController : UIViewController{
MKMapView *mapview;
}
#property (weak, nonatomic) IBOutlet MKMapView *myMapView;
-(IBAction)getlocation;
#end
ViewController.m
#import "ViewController.h"
#import "Annotation.h"
#interface ViewController ()
#end
//Thorpe Park Coordinates
#define THORPE_LATITUDE 51.40395;
#define THORPE_LONGITUDE -0.51433;
//London Eye Coordinates
#define LONDONEYE_LATITUDE 51.50340;
#define LONDONEYE_LONGITUDE -0.11952;
//The New London Dungeons
#define LONDONDUGNEONS_LATITUDE 51.50231;
#define LONDONDUGNEONS_LONGITUDE -0.11965;
//Span
#define THE_SPAN 0.50f;
#implementation ViewController
#synthesize myMapView;
-(IBAction)getlocation {
mapview.showsUserLocation = YES;
}
- (void)viewDidLoad
{
[super viewDidLoad];
//Create Region
MKCoordinateRegion myRegion;
//Center
CLLocationCoordinate2D center;
center.latitude = LONDONEYE_LATITUDE;
center.longitude = LONDONEYE_LONGITUDE;
//Span
MKCoordinateSpan span;
span.latitudeDelta = THE_SPAN;
span.longitudeDelta = THE_SPAN;
myRegion.center = center;
myRegion.span = span;
//Set our mapView
[myMapView setRegion:myRegion animated:YES];
//Annotation's
NSMutableArray * locations = [ [NSMutableArray alloc] init];
CLLocationCoordinate2D location;
Annotation *myAnn;
//London Eye
myAnn = [[Annotation alloc] init];
location.latitude = LONDONEYE_LATITUDE;
location.longitude = LONDONEYE_LONGITUDE;
myAnn.coordinate = location;
myAnn.title = #"The London Eye";
myAnn.subtitle = #"";
[locations addObject:myAnn];
//The New London Dungeons
myAnn = [[Annotation alloc] init];
location.latitude = LONDONDUGNEONS_LATITUDE;
location.longitude = LONDONDUGNEONS_LONGITUDE;
myAnn.coordinate = location;
myAnn.title = #"The London Dungeons";
myAnn.subtitle = #"";
[locations addObject:myAnn];
//Thorpe Park
myAnn = [[Annotation alloc] init];
location.latitude = THORPE_LATITUDE;
location.longitude = THORPE_LONGITUDE;
myAnn.coordinate = location;
myAnn.title = #"Thorpe Park";
myAnn.subtitle = #"";
[locations addObject:myAnn];
[self.myMapView addAnnotations:locations];
/*
//1. Create a coordinate to be used with pin
CLLocationCoordinate2D ThorpeLocation;
ThorpeLocation.latitude = THORPE_LATITUDE;
ThorpeLocation.longitude = THORPE_LONGITUDE;
Annotation * myAnnotation = [Annotation alloc];
myAnnotation.coordinate = ThorpeLocation;
myAnnotation.title = #"Thorpe Park";
myAnnotation.subtitle = #"Theme Park";
[self.myMapView addAnnotation:myAnnotation];
*/
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Use this, and don't forget to put the delegate on your .h file, hope it works ;)
_mapView.userTrackingMode = YES;
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta = 0.00001;
span.longitudeDelta = 0.00001;
CLLocationCoordinate2D location = _mapView.userLocation.coordinate;
region.span = span;
region.center = location;
[_mapView setRegion:region animated:TRUE];
[_mapView regionThatFits:region];
}

Multiple annotations from plist

I'm looking to adapt the following tutorial to create annotations from a plist. I'm brand new to Objective C and Xcode, and tried many different tutorials but can't seem to get this together.
Annotation.h
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface Annotation : NSObject <MKAnnotation>
#property (nonatomic, assign) CLLocationCoordinate2D coordinate;
#property (nonatomic, copy) NSString * title;
#property (nonatomic, copy) NSString * subtitle;
#property (nonatomic, copy) UIImageView * leftCalloutAccessoryView;
#end
Annotation.m
#import "Annotation.h"
#implementation Annotation
#synthesize coordinate, title, subtitle, leftCalloutAccessoryView;
#end
ViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet MKMapView *myMapView;
#end
ViewController.m
#import "ViewController.h"
#import "Annotation.h"
#interface ViewController ()
#end
//Wimbledon Coordinates
#define WIMB_LATITUDE 51.434783;
#define WIMB_LONGITUDE -0.213428;
//Stadium Coordinates
#define ARSENAL_LATITUDE 51.556899;
#define ARSENAL_LONGITUDE -0.106403;
#define CHELSEA_LATITUDE 51.481314;
#define CHELSEA_LONGITUDE -0.190129;
//Span
#define THE_SPAN 0.10f;
#implementation ViewController
#synthesize myMapView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Create the region
MKCoordinateRegion myRegion;
//Center
CLLocationCoordinate2D center;
center.latitude = ARSENAL_LATITUDE;
center.longitude = ARSENAL_LONGITUDE;
//Span
MKCoordinateSpan span;
span.latitudeDelta = THE_SPAN;
span.longitudeDelta = THE_SPAN;
myRegion.center = center;
myRegion.span=span;
//Set our mapView
[myMapView setRegion:myRegion animated:YES];
//Annotation
NSMutableArray * locations = [[NSMutableArray alloc] init];
CLLocationCoordinate2D location;
Annotation * myAnn;
//Arsenal Annotation
myAnn = [[Annotation alloc] init];
location.latitude = ARSENAL_LATITUDE;
location.longitude = ARSENAL_LONGITUDE;
myAnn.coordinate = location;
myAnn.title = #"Arsenal FC";
myAnn.subtitle = #"The Gunners";
//myAnn.image = [UIImage imageNamed:#"location.png"];
[locations addObject:myAnn];
//Chelsea Annotation
myAnn = [[Annotation alloc] init];
location.latitude = CHELSEA_LATITUDE;
location.longitude = CHELSEA_LONGITUDE;
myAnn.coordinate = location;
myAnn.title = #"Chelsea FC";
myAnn.subtitle = #"The Blue Lions";
[locations addObject:myAnn];
[self.myMapView addAnnotations:locations];
}
//THIS CODE WORKS FOR CUSTOM ANNOTATIONS
- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation
{
MKPinAnnotationView *newAnnotation = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"redpin"];
newAnnotation.pinColor = MKPinAnnotationColorRed;
UIImageView *IconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"marker.png"]];
newAnnotation.leftCalloutAccessoryView = IconView;
newAnnotation.animatesDrop = YES;
newAnnotation.canShowCallout = YES;
return newAnnotation;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Got it to work thanks to a suggestion above. Also added in custom markers and a left icon to call out. I commented out the old coordinate code and the annotation red pins with left icon.
Hope this helps others who might've gone crazy searching for a solution as I have.
Stadiums.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Stadiums</key>
<array>
<dict>
<key>Title</key>
<string>Arsenal</string>
<key>Subtitle</key>
<string>The Gunners</string>
<key>Latitude</key>
<string>51.556899</string>
<key>Longitude</key>
<string>-0.106403</string>
</dict>
<dict>
<key>Title</key>
<string>Chelsea</string>
<key>Subtitle</key>
<string>The Blue Lions</string>
<key>Latitude</key>
<string>51.481314</string>
<key>Longitude</key>
<string>-0.190129</string>
</dict>
</array>
</dict>
</plist>
ViewController.m
#import "ViewController.h"
#import "Annotation.h"
#interface ViewController ()
#end
//Wimbledon Coordinates
#define WIMB_LATITUDE 51.434783;
#define WIMB_LONGITUDE -0.213428;
//Stadium Coordinates
#define ARSENAL_LATITUDE 51.556899;
#define ARSENAL_LONGITUDE -0.106403;
#define CHELSEA_LATITUDE 51.481314;
#define CHELSEA_LONGITUDE -0.190129;
//Span
#define THE_SPAN 0.10f;
#implementation ViewController
#synthesize myMapView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Create the region
MKCoordinateRegion myRegion;
//Center
CLLocationCoordinate2D center;
center.latitude = ARSENAL_LATITUDE;
center.longitude = ARSENAL_LONGITUDE;
//Span
MKCoordinateSpan span;
span.latitudeDelta = THE_SPAN;
span.longitudeDelta = THE_SPAN;
myRegion.center = center;
myRegion.span=span;
//Set our mapView
[myMapView setRegion:myRegion animated:YES];
/*
//Annotation
NSMutableArray * locations = [[NSMutableArray alloc] init];
CLLocationCoordinate2D location;
Annotation * myAnn;
//Arsenal Annotation
myAnn = [[Annotation alloc] init];
location.latitude = ARSENAL_LATITUDE;
location.longitude = ARSENAL_LONGITUDE;
myAnn.coordinate = location;
myAnn.title = #"Arsenal FC";
myAnn.subtitle = #"The Gunners";
//myAnn.image = [UIImage imageNamed:#"location.png"];
[locations addObject:myAnn];
//Chelsea Annotation
myAnn = [[Annotation alloc] init];
location.latitude = CHELSEA_LATITUDE;
location.longitude = CHELSEA_LONGITUDE;
myAnn.coordinate = location;
myAnn.title = #"Chelsea FC";
myAnn.subtitle = #"The Blue Lions";
[locations addObject:myAnn];
[self.myMapView addAnnotations:locations];
*/
NSMutableArray *annotations = [[NSMutableArray alloc]init];
NSString *path = [[NSBundle mainBundle] pathForResource:#"Stadiums" ofType:#"plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSArray *anns = [dict objectForKey:#"Stadiums"];
NSLog(#"read1");
for(int i = 0; i < [anns count]; i++) {
NSLog(#"read2");
float realLatitude = [[[anns objectAtIndex:i] objectForKey:#"Latitude"] floatValue];
float realLongitude = [[[anns objectAtIndex:i] objectForKey:#"Longitude"] floatValue];
NSLog(#"read3");
Annotation *myAnnotation = [[Annotation alloc] init];
CLLocationCoordinate2D theCoordinate;
theCoordinate.latitude = realLatitude;
theCoordinate.longitude = realLongitude;
myAnnotation.coordinate = theCoordinate;
myAnnotation.title = [[anns objectAtIndex:i] objectForKey:#"Title"];
myAnnotation.subtitle = [[anns objectAtIndex:i] objectForKey:#"Subtitle"];
[myMapView addAnnotation:myAnnotation];
[annotations addObject:myAnnotation];
//[myAnnotation release];
}
}
//THIS CODE WORKS FOR CUSTOM ANNOTATIONS
- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation
{
static NSString *AnnotationViewID = #"annotationViewID";
MKAnnotationView *annotationView = (MKAnnotationView *)[myMapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
if (annotationView == nil)
{
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID];
}
//Custom Pin
annotationView.image = [UIImage imageNamed:#"toilets.png"];
//Custom Thumbnail (left side)
UIImageView *IconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"toilets.png"]];
annotationView.leftCalloutAccessoryView = IconView;
annotationView.canShowCallout = YES;
annotationView.annotation = annotation;
return annotationView;
/*
MKPinAnnotationView *newAnnotation = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"redpin"];
newAnnotation.pinColor = MKPinAnnotationColorRed;
UIImageView *ThumbView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"toilets.png"]];
newAnnotation.leftCalloutAccessoryView = ThumbView;
newAnnotation.animatesDrop = YES;
newAnnotation.canShowCallout = YES;
return newAnnotation;
*/
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Personally, I would use CoreData to store the annotations. However, if you are stuck on writing things to disk, I would make your annotation object implement the NSCoding protocol and use NSKeyedArchiver to save and load your objects.
+ (NSObject *)readArchiveFile:(NSString *)inFileName
{
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSString *documentsDirectoryPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectoryPath, inFileName];
NSObject *returnObject = nil;
if( [fileMgr fileExistsAtPath:filePath] )
{
#try
{
returnObject = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
}
#catch (NSException *exception)
{
[FileUtils deleteFile:inFileName];
returnObject = nil;
}
}
return returnObject;
}
+ (void)archiveFile:(NSString *)inFileName inObject:(NSObject *)inObject
{
NSString *documentsDirectoryPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectoryPath, inFileName];
#try
{
BOOL didSucceed = [NSKeyedArchiver archiveRootObject:inObject toFile:filePath];
if( !didSucceed )
{
NSLog(#"File %# write operation %#", inFileName, didSucceed ? #"success" : #"error" );
}
}
#catch (NSException *exception)
{
NSLog(#"File %# write operation threw an exception:%#", filePath, exception.reason);
}
}

How to center region in iOS6

I have a problem with centering the map to a particular region. I don't know where the problem is
Map.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface Map : UIViewController {
MKMapView * mapView;
}
#property(nonatomic,retain) IBOutlet MKMapView * mapView;
- (IBAction)setMap:(id)sender;
- (IBAction)getLocation:(id)sender;
#end
Map.m
#import "Map.h"
#import "Annotation.h"
#interface Map ()
#end
//define coordinates
#define Sofia_LATITUDE 42.745826;
#define Sofia_LONGITUDE 23.270186;
#define Plovdiv_LATITUDE 42.1333;
#define Plovdiv_LONGITUDE 24.75;
#define Varna_LATITUDE 43.2;
#define Varna_LONGITUDE 27.9167;
#define THE_SPAN 3.8;
#implementation Map
#synthesize mapView;
- (IBAction)getLocation:(id)sender {
mapView.showsUserLocation = YES;
[self.view addSubview:mapView];
}
- (IBAction)setMap:(id)sender {
switch (((UISegmentedControl *)sender).selectedSegmentIndex) {
case 0:
mapView.mapType = MKMapTypeStandard;
break;
case 1:
mapView.mapType = MKMapTypeSatellite;
break;
case 2:
mapView.mapType = MKMapTypeHybrid;
break;
default:
break;
}
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
MKCoordinateRegion myRegion;
//Center the map
CLLocationCoordinate2D center;
center.latitude = 42.1333;
center.longitude = 24.75;
MKCoordinateSpan span;
span.latitudeDelta = THE_SPAN;
span.longitudeDelta = THE_SPAN;
myRegion.center = center;
myRegion.span = span;
[mapView setRegion:myRegion animated:TRUE];
NSMutableArray * locations = [[NSMutableArray alloc]init];
CLLocationCoordinate2D location;
Annotation * myAnn;
//make annotations
myAnn = [[Annotation alloc]init];
location.latitude = Sofia_LATITUDE;
location.longitude = Sofia_LONGITUDE;
myAnn.coordinate = location;
myAnn.title = #"Милото";
myAnn.subtitle = #"Моята любов е ТУК!!!";
[locations addObject:myAnn];
myAnn = [[Annotation alloc]init];
location.latitude = Plovdiv_LATITUDE;
location.longitude = Plovdiv_LONGITUDE;
myAnn.coordinate = location;
myAnn.title = #"Plovdiv";
myAnn.subtitle = #"Plovdiv";
[locations addObject:myAnn];
myAnn = [[Annotation alloc]init];
location.latitude = Varna_LATITUDE;
location.longitude = Varna_LONGITUDE;
myAnn.coordinate = location;
myAnn.title = #"Varna";
myAnn.subtitle = #"Varna";
[locations addObject:myAnn];
[self.mapView addAnnotations:locations];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Annotation.h
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface Annotation : NSObject <MKAnnotation>
#property (nonatomic, assign) CLLocationCoordinate2D coordinate;
#property (nonatomic, copy) NSString * title;
#property (nonatomic, copy) NSString * subtitle;
#end
Annotation.m
#import "Annotation.h"
#implementation Annotation
#synthesize coordinate, title, subtitle;
#end
So when I launch the program and click the button to see the map, it appears but it is not centered. When I move back and again click to see the map everything is OK. Where is the problem?
You need to set the region for the mapview. The region has a coordinate (the middle) and a span (the numbers of the span stand for the degrees of the world that is shown on the map), play around with the span numbers to get the result you desire. You can set the region when you set your coordinate.
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta = 0.2;
span.longitudeDelta = 0.2;
region.span = span;
region.center = self.coordinate;
[mapView setRegion:region animated:YES];

Resources