I need help on this .... drop the pins.
current location.... pin drop.... with blue....
Event location :locations latitude:53.373812...longitude 4.890951 with red pin.
I did like this:
#interface AddressAnnotation : NSObject<MKAnnotation> {
CLLocationCoordinate2D coordinate;
NSString *mTitle;
NSString *mSubTitle;
// CLLocationManager *locationManager;
// CLLocation *currentLocation;
}
#end
#interface MapViewController : UIViewController <CLLocationManagerDelegate> {
IBOutlet MKMapView *mapView;
AddressAnnotation *addAnnotation;
NSString *address;
CLLocationManager *locationManager;
CLLocation *currentLocation;
}
+(MapViewController *)sharedInstance;
-(void)start;
-(void)stop;
-(BOOL)locationKnown;
#property(nonatomic,retain)CLLocation *currentLocation;
#property(nonatomic,retain)NSString *address;
-(CLLocationCoordinate2D) addressLocation;
-(void)showAddress;
#end
//Implementation file.
#import "MapViewController.h"
#implementation AddressAnnotation
#synthesize coordinate;
//#synthesize currentLocation;
- (NSString *)subtitle{
//return #"Sub Title";
return #"Event";
}
- (NSString *)title{
//return #"Title";
return #"Location ";
}
-(id)initWithCoordinate:(CLLocationCoordinate2D) c{
coordinate=c;
//NSLog(#"%f,%f",c.latitude,c.longitude);
return self;
}
#end
#implementation MapViewController
#synthesize address;
#synthesize currentLocation;
static MapViewController *sharedInstance;
+(MapViewController *)sharedInstance{
#synchronized (self)
{
if (!sharedInstance)
[[MapViewController alloc]init];
}
return sharedInstance;
}
+(id)alloc{
#synchronized(self){
NSAssert(sharedInstance==nil,"Attempted to allocate a second instance of a singleton LocationController.");
sharedInstance = [super alloc];
}
return sharedInstance;
}
-(id)init{
if(self==[super init]){
self.currentLocation=[[CLLocation alloc]init];
locationManager=[[CLLocationManager alloc]init];
locationManager.delegate=self;
[self start];
}
return self;
}
-(void)start{
NSLog(#"Start");
[locationManager startUpdatingLocation];
}
-(void)stop{
[locationManager stopUpdatingLocation];
}
-(BOOL)locationKnown{
if (round(currentLocation.speed)==-1)
return NO;
else return YES;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
if (abs([newLocation.timestamp timeIntervalSinceDate:[NSDate date]])<120){
self.currentLocation=newLocation;
}
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
UIAlertView *alert;
alert=[[UIAlertView alloc]initWithTitle:#"Error" message:[error description] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
self.title=#"Map-View";
[self addressLocation];
[self showAddress];
NSLog(#"address is %#",address);
}
-(void)showAddress{
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta=0.2;
span.longitudeDelta=0.2;
CLLocationCoordinate2D location = [self addressLocation];
region.span=span;
region.center=location;
if(addAnnotation != nil) {
[mapView removeAnnotation:addAnnotation];
[addAnnotation release];
addAnnotation = nil;
}
addAnnotation = [[AddressAnnotation alloc] initWithCoordinate:location];
[mapView addAnnotation:addAnnotation];
[mapView setRegion:region animated:TRUE];
[mapView regionThatFits:region];
}
-(CLLocationCoordinate2D) addressLocation {
NSString *urlString = [NSString stringWithFormat:#"http://maps.google.com/maps/geo?q=%#&output=csv",
[address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString]];
NSArray *listItems = [locationString componentsSeparatedByString:#","];
double latitude = 0.0;
double longitude = 0.0;
if([listItems count] >= 4 && [[listItems objectAtIndex:0] isEqualToString:#"200"]) {
latitude = [[listItems objectAtIndex:2] doubleValue];
longitude = [[listItems objectAtIndex:3] doubleValue];
}
else {
//Show error
}
CLLocationCoordinate2D location;
location.latitude = latitude;
location.longitude = longitude;
return location;
}
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation{
MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"currentloc"];
annView.pinColor = MKPinAnnotationColorRed;
annView.animatesDrop=YES;
annView.canShowCallout = YES;
annView.calloutOffset = CGPointMake(-5, 5);
return annView;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Overriden to allow any orientation.
return YES;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[address release];
[super dealloc];
}
#end
Please help me out...
thanks in adavance.
Showing user current location is simple.
-(void)start{
NSLog(#"Start");
mapView.showsUserLocation=YES; //This will show the current location as blue dot in your mapview
[locationManager startUpdatingLocation];
}
-(void)stop{
mapView.showsUserLocation=NO;
[locationManager stopUpdatingLocation];
}
In your viewForAnnotation Delegate
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
if (annotation == mapView.userLocation)
{
// This code will execute when the current location is called.
return nil;
}
else
{
MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"currentloc"];
annView.pinColor = MKPinAnnotationColorRed;
annView.animatesDrop=YES;
annView.canShowCallout = YES;
annView.calloutOffset = CGPointMake(-5, 5);
return annView;
}
Related
-(MKAnnotationView *) mapView: is not firing on the first run of the view.
I load pins in from a JSON call. The pins load fine with all the information but the call out(*see code) and turning them purple.(done in the -(MKAnnotationView *) mapView2:) however when I leave that tab and go back to it then it gets called and all is well.
Why this in not OK? Because end-users will not know that the map pins have a call out with phone call capabilities if they only check once.
Progress Flow: it loads the map. Loads the Pins. Changes the pins to purple with the call out. Then Zooms to pins and current location. But on the first run it does not Change the pins with call out.
I have narrowed it down to -(MKAnnotationView *) mapView: not firing the first time on several tests however on one test it did fire but only was called on the second of two pins till the view was reloaded.
I am open to any suggestions to improve any of the code weather it pertains to this or not. I always love learning better ways to do what I have done. So feel free with your criticisms.
.h file
#class Reachability;
#interface LocationsViewController : UIViewController <MKMapViewDelegate,CLLocationManagerDelegate>
{
NSString *phone;
IBOutlet MKMapView *mapView;
CLLocationManager *locationManager;
NSURLConnection *theConnection;
Reachability* internetReachable;
Reachability* hostReachable;
}
#property(nonatomic, retain) IBOutlet MKMapView *mapView;
#property(nonatomic, retain)CLLocationManager *locationManager;
#property(nonatomic, retain) NSString *phone;
- (BOOL) connectedToNetwork;
- (void) mapPinsJSON;
#end
.m file
#implementation LocationsViewController
#synthesize mapView;
#synthesize locationManager;
#synthesize phone;
MapAnnotation *ann1;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
self.title = NSLocalizedString(#"Locations", #"Locations");
self.tabBarItem.image = [UIImage imageNamed:#"locations"];
}
return self;
}
- (void)dealloc
{
[super dealloc];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
//Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
MKCoordinateRegion region;
region.center.latitude = newLocation.coordinate.latitude;
region.center.longitude= newLocation.coordinate.longitude;
region.span.longitudeDelta=0.2;
region.span.latitudeDelta =0.2;
[mapView setRegion:region animated:YES];
[mapView setDelegate:self];
NSTimer *myTimer;
myTimer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(countDown) userInfo:nil repeats:NO];
[self zoomMapViewToFitAnnotations:self.mapView animated:YES];
}
-(void)countDown{
[locationManager stopUpdatingLocation];
}
-(void)viewDidDisappear:(BOOL)animated
{
[locationManager stopUpdatingLocation];
}
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[mapView removeAnnotations:mapView.annotations];
self.locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
if([self connectedToNetwork] != YES)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"OH NO!" message:#"To get the latest information you need a data or wi-fi connection" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
else
{
[self performSelectorInBackground:#selector(mapPinsJSON) withObject:nil];
}
}
- (void) mapPinsJSON{
NSString *urlString = [NSString stringWithFormat:#"http://www.mywebsite.com/api/newlocations25/json.json"];
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error;
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
for(id key in json) {
id value = [json objectForKey:key];
NSString *titlePin = [value valueForKey:#"address"];
NSString *address = [value valueForKey:#"title"];
NSString *latitude = [value valueForKey:#"latitude"];
NSString *longitude = [value valueForKey:#"longitude"];
NSArray* foo = [address componentsSeparatedByString: #":"];
NSString* address2 = [foo objectAtIndex: 0];
phone = [foo objectAtIndex: 1];
double myLatitude = [latitude doubleValue];
double myLongitude = [longitude doubleValue];
MKCoordinateRegion location1;
location1.center.latitude =myLatitude;
location1.center.longitude= myLongitude;
location1.span.longitudeDelta=0.1;
location1.span.latitudeDelta =0.1;
ann1 =[[[MapAnnotation alloc] init] autorelease];
ann1.title=[NSString stringWithFormat:#"%#",titlePin];
ann1.subtitle=[NSString stringWithFormat:#"%#",address2];
ann1.phone=[NSString stringWithFormat:#"%#",phone];
ann1.coordinate= location1.center;
[mapView addAnnotation:ann1];
[phone retain];
}
}
-(MKAnnotationView *) mapView:(MKMapView *)mapView2 viewForAnnotation:(id<MKAnnotation>)annotation {
if (annotation == mapView2.userLocation) {
return nil;
}else{
MKPinAnnotationView *MyPin=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"current"];
MyPin.pinColor = MKPinAnnotationColorPurple;
UIButton *advertButton = [UIButton buttonWithType:UIButtonTypeInfoDark];
[advertButton setImage:[UIImage imageNamed:#"mapphone"] forState:UIControlStateNormal];
[advertButton addTarget:self action:#selector(button:) forControlEvents:UIControlEventTouchUpInside];
MyPin.rightCalloutAccessoryView = advertButton;
MyPin.draggable = NO;
MyPin.highlighted = YES;
MyPin.animatesDrop=TRUE;
MyPin.canShowCallout = YES;
return MyPin;
}
}
-(void)button:(id)sender {
UIButton *button = (UIButton *)sender;
MKPinAnnotationView *annotationView = (MKPinAnnotationView*)button.superview.superview;
MapAnnotation *mapAnnotation = annotationView.annotation;
UIDevice *device = [UIDevice currentDevice];
if ([[device model] isEqualToString:#"iPhone"] ) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:#"tel:%#",mapAnnotation.phone]]];
} else {
UIAlertView *Notpermitted=[[UIAlertView alloc] initWithTitle:mapAnnotation.phone message:#"Your device doesn't support this feature." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[Notpermitted show];
[Notpermitted release];
}
}
- (BOOL) connectedToNetwork
{
Reachability *r = [Reachability reachabilityWithHostName:#"www.google.com"];
NetworkStatus internetStatus = [r currentReachabilityStatus];
BOOL internet;
if ((internetStatus != ReachableViaWiFi) && (internetStatus != ReachableViaWWAN)) {
internet = NO;
} else {
internet = YES;
}
return internet;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
#define MINIMUM_ZOOM_ARC 0.014 //approximately 1 miles (1 degree of arc ~= 69 miles)
#define ANNOTATION_REGION_PAD_FACTOR 1.15
#define MAX_DEGREES_ARC 360
- (void)zoomMapViewToFitAnnotations:(MKMapView *)mapView3 animated:(BOOL)animated
{
NSArray *annotations = mapView.annotations;
int count = [mapView.annotations count];
if ( count == 0) { return; } //bail if no annotations
//convert NSArray of id <MKAnnotation> into an MKCoordinateRegion that can be used to set the map size
//can't use NSArray with MKMapPoint because MKMapPoint is not an id
MKMapPoint points[count]; //C array of MKMapPoint struct
for( int i=0; i<count; i++ ) //load points C array by converting coordinates to points
{
CLLocationCoordinate2D coordinate = [(id <MKAnnotation>)[annotations objectAtIndex:i] coordinate];
points[i] = MKMapPointForCoordinate(coordinate);
}
//create MKMapRect from array of MKMapPoint
MKMapRect mapRect = [[MKPolygon polygonWithPoints:points count:count] boundingMapRect];
//convert MKCoordinateRegion from MKMapRect
MKCoordinateRegion region = MKCoordinateRegionForMapRect(mapRect);
//add padding so pins aren't scrunched on the edges
region.span.latitudeDelta *= ANNOTATION_REGION_PAD_FACTOR;
region.span.longitudeDelta *= ANNOTATION_REGION_PAD_FACTOR;
//but padding can't be bigger than the world
if( region.span.latitudeDelta > MAX_DEGREES_ARC ) { region.span.latitudeDelta = MAX_DEGREES_ARC; }
if( region.span.longitudeDelta > MAX_DEGREES_ARC ){ region.span.longitudeDelta = MAX_DEGREES_ARC; }
//and don't zoom in stupid-close on small samples
if( region.span.latitudeDelta < MINIMUM_ZOOM_ARC ) { region.span.latitudeDelta = MINIMUM_ZOOM_ARC; }
if( region.span.longitudeDelta < MINIMUM_ZOOM_ARC ) { region.span.longitudeDelta = MINIMUM_ZOOM_ARC; }
//and if there is a sample of 1 we want the max zoom-in instead of max zoom-out
if( count == 1 )
{
region.span.latitudeDelta = MINIMUM_ZOOM_ARC;
region.span.longitudeDelta = MINIMUM_ZOOM_ARC;
}
[mapView3 setRegion:region animated:animated];
}
#end
Well I feel sheepish. Here is what fixed it for me.
- (void)viewDidLoad
{
[super viewDidLoad];
mapView.delegate = self;
}
Right now I am setting my region based on users current location. I would like to now set the zoom level so I can see the users current location and the nearest pin that is being pulled in via json.
Not until run time will the app know the number of pins or the locations of said pins.
Here is what I have so far.
#implementation LocationsViewController
#synthesize mapView;
#synthesize locationManager;
#synthesize phone;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
self.title = NSLocalizedString(#"Locations", #"Locations");
self.tabBarItem.image = [UIImage imageNamed:#"locations"];
}
return self;
}
- (void)dealloc
{
[super dealloc];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
//Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(#"New latitude: %f", newLocation.coordinate.latitude);
NSLog(#"New longitude: %f", newLocation.coordinate.longitude);
MKCoordinateRegion region;
region.center.latitude =newLocation.coordinate.latitude;
region.center.longitude= newLocation.coordinate.longitude;
region.span.longitudeDelta=0.2;
region.span.latitudeDelta =0.2;
[mapView setRegion:region animated:YES];
[mapView setDelegate:self];
//[locationManager stopUpdatingLocation];
}
-(void)viewDidDisappear:(BOOL)animated
{
[locationManager stopUpdatingLocation];
}
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[locationManager startUpdatingLocation];
if([self connectedToNetwork] != YES)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"OH NO!" message:#"To get the latest information you need a data or wi-fi connection" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
else
{
[mapView removeAnnotations:mapView.annotations];
NSString *urlString = [NSString stringWithFormat:#"http://www.mywebsite.com/json.json"];
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error;
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
for(id key in json) {
id value = [json objectForKey:key];
NSString *titlePin = [value valueForKey:#"address"];
NSString *address = [value valueForKey:#"title"];
NSString *latitude = [value valueForKey:#"latitude"];
NSString *longitude = [value valueForKey:#"longitude"];
NSArray* foo = [address componentsSeparatedByString: #":"];
NSString* address2 = [foo objectAtIndex: 0];
phone = [foo objectAtIndex: 1];
double myLatitude = [latitude doubleValue];
double myLongitude = [longitude doubleValue];
MKCoordinateRegion location1;
location1.center.latitude =myLatitude;
location1.center.longitude= myLongitude;
location1.span.longitudeDelta=0.1;
location1.span.latitudeDelta =0.1;
MapAnnotation *ann1 =[[[MapAnnotation alloc] init] autorelease];
ann1.title=[NSString stringWithFormat:#"%#",titlePin];
ann1.subtitle=[NSString stringWithFormat:#"%#",address2];
ann1.phone=[NSString stringWithFormat:#"%#",phone];
ann1.coordinate= location1.center;
[mapView addAnnotation:ann1];
[phone retain];
}
}
}
-(MKAnnotationView *) mapView:(MKMapView *)mapView2 viewForAnnotation:(id<MKAnnotation>)annotation {
if (annotation == mapView2.userLocation) {
return nil;
}else{
MKPinAnnotationView *MyPin=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"current"];
MyPin.pinColor = MKPinAnnotationColorPurple;
UIButton *advertButton = [UIButton buttonWithType:UIButtonTypeInfoDark];
[advertButton setImage:[UIImage imageNamed:#"mapphone"] forState:UIControlStateNormal];
[advertButton addTarget:self action:#selector(button:) forControlEvents:UIControlEventTouchUpInside];
MyPin.rightCalloutAccessoryView = advertButton;
MyPin.draggable = NO;
MyPin.highlighted = YES;
MyPin.animatesDrop=TRUE;
MyPin.canShowCallout = YES;
return MyPin;
}
}
-(void)button:(id)sender {
UIButton *button = (UIButton *)sender;
MKPinAnnotationView *annotationView = (MKPinAnnotationView*)button.superview.superview;
MapAnnotation *mapAnnotation = annotationView.annotation;
UIDevice *device = [UIDevice currentDevice];
if ([[device model] isEqualToString:#"iPhone"] ) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:#"tel:%#",mapAnnotation.phone]]];
} else {
UIAlertView *Notpermitted=[[UIAlertView alloc] initWithTitle:mapAnnotation.phone message:#"Your device doesn't support this feature." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[Notpermitted show];
[Notpermitted release];
}
}
- (BOOL) connectedToNetwork
{
Reachability *r = [Reachability reachabilityWithHostName:#"www.google.com"];
NetworkStatus internetStatus = [r currentReachabilityStatus];
BOOL internet;
if ((internetStatus != ReachableViaWiFi) && (internetStatus != ReachableViaWWAN)) {
internet = NO;
} else {
internet = YES;
}
return internet;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
#end
I did something similar, but based on two annotations, not the user's location. You should be able to replace mapView.centerCoordinate with mapView.userLocation.coordinate.
in viewForAnnotation:
CLLocation *centerLoc = [[CLLocation alloc] initWithLatitude:mapView.centerCoordinate.latitude longitude:mapView.centerCoordinate.longitude];
CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:[annotation coordinate].latitude longitude:[annotation coordinate].longitude];
CLLocationDistance distance = [loc2 distanceFromLocation:centerLoc];
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(mapView.centerCoordinate, distance*2, distance*2);
MKCoordinateRegion adjustedRegion = [mapView regionThatFits:viewRegion];
[mapView setRegion:adjustedRegion animated:YES];
Note, this code will re-calc the zoom level each time you add an annotation. You may need to save the distance and only change the map if the new distance is greater than the prior distance.
I have a little problem and i dont know why is it happening.
My map view is woking fine in the simulator but on the real device I only see the pin on the gray area and the "google" logo. It's like the images cant be loaded, it look like when you zoom in and you wait for the view to draw around the square.
Here is my code, I would appreciate any help
#import "Maps.h"
#import "RootViewController.h"
#implementation AddressAnnotation
#synthesize coordinate;
-(NSString *) subtitle{
return #"327 Anzac Parade, Wodonga, Victoria, Australia";
}
-(NSString *) title{
return #"Blazing Stump";
}
-(id)initWithCoordinate:(CLLocationCoordinate2D) c{
coordinate = c;
NSLog(#"%f,%f",c.latitude, c.longitude);
return self;
}
#end
#implementation Maps
-(CLLocationCoordinate2D) addressLocation{
NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:#"http://maps.google.com/maps/geo?q=327%20Anzac%20Parade,%20Wodonga,%20Victoria,%20Australia&output=csv&key=ABQIAAAAZs2zFXiuKBFeLpPgSfgMjBTHxw17-t8q3X3AgrE9NufATyE8MRRmwlyLMPtOSzliJQntEtaZ7T-Rww"]
encoding:NSUTF8StringEncoding error:nil];
NSArray *listItems = [locationString componentsSeparatedByString:#","];
double latitude = -36.139226;
double longitude = 146.911454;
if ([listItems count] >=4 && [[listItems objectAtIndex:0] isEqualToString:#"200"]){
latitude = [[listItems objectAtIndex:2] doubleValue];
longitude = [[listItems objectAtIndex:3] doubleValue];
}else {
//some error
}
CLLocationCoordinate2D location;
location.latitude = latitude;
location.longitude = longitude;
return location;
}
-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation{
MKPinAnnotationView *annView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"currentloc"];
annView.pinColor = MKPinAnnotationColorGreen;
annView.animatesDrop = TRUE;
annView.canShowCallout = YES;
annView.calloutOffset = CGPointMake(-5, 5);
return annView;
}
- (void)viewDidLoad {
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta=0.2;
span.longitudeDelta=0.2;
CLLocationCoordinate2D location = [self addressLocation];
region.span=span;
region.center=location;
if(addAnnotation != nil) {
[mapView removeAnnotation:addAnnotation];
[addAnnotation release];
addAnnotation = nil;
}
addAnnotation = [[AddressAnnotation alloc] initWithCoordinate:location];
[mapView addAnnotation:addAnnotation];
[mapView setRegion:region animated:TRUE];
[mapView regionThatFits:region];
//[mapView selectAnnotation:mLodgeAnnotation animated:YES];
[super viewDidLoad];
}
- (void)dealloc {
[super dealloc];
[viewController release];
}
have you made sure the map delgate has been set? Make sure you add the delagate to the header and on the view did load mapkit.delagte=self;
Dan
How do I get the current location with green pin and destination location with red pin?
When I work on some stuff I get only destination location with red pin, not at the current location.
My source code.
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <MapKit/MKAnnotation.h>
#import <CoreLocation/CoreLocation.h>
#interface AddressAnnotation : NSObject<MKAnnotation> {
CLLocationCoordinate2D coordinate;
NSString *mTitle;
NSString *mSubTitle;
// CLLocationManager *locationManager;
// CLLocation *currentLocation;
}
#end
#interface MapViewController : UIViewController <CLLocationManagerDelegate,MKMapViewDelegate> {
IBOutlet MKMapView *mapView;
AddressAnnotation *addAnnotation;
NSString *address;
CLLocationManager *locationManager;
CLLocation *currentLocation;
}
+(MapViewController *)sharedInstance;
-(void)start;
-(void)stop;
-(BOOL)locationKnown;
#property(nonatomic,retain)CLLocation *currentLocation;
#property(nonatomic,retain)NSString *address;
-(CLLocationCoordinate2D) addressLocation;
-(void)showAddress;
#end
#import "MapViewController.h"
#implementation AddressAnnotation
#synthesize coordinate;
//#synthesize currentLocation;
- (NSString *)subtitle{
//return #"Sub Title";
return #"Event";
}
- (NSString *)title{
//return #"Title";
return #"Allure-Exclusive";
}
-(id)initWithCoordinate:(CLLocationCoordinate2D) c{
coordinate=c;
//NSLog(#"%f,%f",c.latitude,c.longitude);
return self;
}
#end
#implementation MapViewController
#synthesize address;
#synthesize currentLocation;
static MapViewController *sharedInstance;
+(MapViewController *)sharedInstance{
#synchronized (self)
{
if (!sharedInstance)
[[MapViewController alloc]init];
}
return sharedInstance;
}
+(id)alloc{
#synchronized(self){
NSAssert(sharedInstance==nil,"Attempted to allocate a second instance of a singleton LocationController.");
sharedInstance = [super alloc];
}
return sharedInstance;
}
-(id)init{
if(self==[super init]){
self.currentLocation=[[CLLocation alloc]init];
locationManager=[[CLLocationManager alloc]init];
locationManager.delegate=self;
[self start];
}
return self;
}
-(void)start{
NSLog(#"Start");
mapView.showsUserLocation=YES;
[locationManager startUpdatingLocation];
}
-(void)stop{
mapView.showsUserLocation=NO;
[locationManager stopUpdatingLocation];
}
-(BOOL)locationKnown{
if (round(currentLocation.speed)==-1)
return NO;
else return YES;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
if (abs([newLocation.timestamp timeIntervalSinceDate:[NSDate date]])<120){
self.currentLocation=newLocation;
}
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
UIAlertView *alert;
alert=[[UIAlertView alloc]initWithTitle:#"Error" message:[error description] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
self.title=#"Map-View";
// [self addressLocation];
[self showAddress];
NSLog(#"address is %#",address);
}
-(void)showAddress{
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta=0.5;
span.longitudeDelta=0.5;
CLLocationCoordinate2D location = [self addressLocation];
region.span=span;
region.center=location;
if(addAnnotation != nil) {
[mapView removeAnnotation:addAnnotation];
[addAnnotation release];
addAnnotation = nil;
}
addAnnotation = [[AddressAnnotation alloc] initWithCoordinate:location];
[mapView addAnnotation:addAnnotation];
[mapView setRegion:region animated:TRUE];
[mapView regionThatFits:region];
}
-(CLLocationCoordinate2D) addressLocation {
NSString *urlString = [NSString stringWithFormat:#"http://maps.google.com/maps/geo?q=%#&output=csv",
[address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString]];
NSLog(#"locationString %#",locationString);
NSArray *listItems = [locationString componentsSeparatedByString:#","];
double latitude = 0.0;
double longitude = 0.0;
if([listItems count] >= 4 && [[listItems objectAtIndex:0] isEqualToString:#"200"]) {
latitude = [[listItems objectAtIndex:2] doubleValue];
longitude = [[listItems objectAtIndex:3] doubleValue];
NSLog(#"listItems %#",[listItems objectAtIndex:2]);
}
else {
//Show error
}
CLLocationCoordinate2D location;
location.latitude = latitude;
location.longitude = longitude;
return location;
}
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation{
if (annotation==mapView.userLocation) {
MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"currentloc"];
annView.pinColor = MKPinAnnotationColorGreen;
annView.animatesDrop=YES;
annView.canShowCallout = YES;
annView.calloutOffset = CGPointMake(-5, 5);
return annView;
//
}
else {
MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"currentloc"];
annView.pinColor = MKPinAnnotationColorRed;
annView.animatesDrop=YES;
annView.canShowCallout = YES;
annView.calloutOffset = CGPointMake(-5, 5);
return annView;
}
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Overriden to allow any orientation.
return YES;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// [self stop];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[address release];
[super dealloc];
}
#end
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation{
if (annotation==mapView.userLocation)
{
mapView.userLocation.title=#"Current Location";
[mapView setRegion:MKCoordinateRegionMakeWithDistance(mapView.userLocation.coordinate, 1000, 1000)animated:YES];
return nil;
}
else {
MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"currentloc"];
annView.pinColor = MKPinAnnotationColorRed;
annView.animatesDrop=YES;
annView.canShowCallout = YES;
annView.calloutOffset = CGPointMake(-5, 5);
return annView;
}
}
When I changed the method. it's pointing blue and blinking,but it was pointing at different location, which is at infinite Loop mariani Ave location.
It was running this in a simulator.
You'll want to set showsUserLocation.
mapView.showsUserLocation = YES;
Hey guys! I am having some trouble with giving an MKAnnotationView an image instead of a pin view. In other words, I am having trouble displaying a target image (target.png) instead of the normal pin view. Here is my code---
// .h file
#import //Here it says to import mapkit & UIKit. The code blockquote doesn't let me
#import //show you that
#interface AddressAnnotation : NSObject {
CLLocationCoordinate2D coordinate;
NSString *mTitle;
NSString *mSubTitle;
}
#end
#interface ChosenLocationMap : UIViewController {
IBOutlet MKMapView *mapView;
AddressAnnotation *addAnnotation;
}
-(CLLocationCoordinate2D) addressLocation;
// .m file
#implementation AddressAnnotation
#synthesize coordinate;
- (NSString *)subtitle{
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *stitle = [prefs objectForKey:#"addressKey"];
return #"%#",stitle;
}
- (NSString *)title{
return #"TARGET";
}
-(id)initWithCoordinate:(CLLocationCoordinate2D) c{
coordinate=c;
NSLog(#"%f,%f",c.latitude,c.longitude);
return self;
}
#end
#implementation ChosenLocationMap
#synthesize destinationLabel, startbutton, accelloop, aimview, bombblowupview, bombleftview1, bombleftview2, bombleftview3, firebutton;
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
- (void)viewDidLoad {
mapView.mapType = MKMapTypeSatellite;
MKCoordinateSpan span;
span.latitudeDelta=0.2;
span.longitudeDelta=0.2;
CLLocationCoordinate2D location = [self addressLocation];
region.span=span;
region.center=location;
if(addAnnotation != nil) {
[mapView removeAnnotation:addAnnotation];
[addAnnotation release];
addAnnotation = nil;
}
addAnnotation = [[AddressAnnotation alloc] initWithCoordinate:location];
[mapView addAnnotation:addAnnotation];
[super viewDidLoad];
}
-(CLLocationCoordinate2D) addressLocation {
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *destinationstring = [prefs objectForKey:#"addressKey"];
NSString *urlString = [NSString stringWithFormat:#"http://maps.google.com/maps/geo?q=%#&output=csv",
[destinationstring stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString]];
NSArray *listItems = [locationString componentsSeparatedByString:#","];
double latitude = 0.0;
double longitude = 0.0;
if([listItems count] >= 4 && [[listItems objectAtIndex:0] isEqualToString:#"200"]) {
latitude = [[listItems objectAtIndex:2] doubleValue];
longitude = [[listItems objectAtIndex:3] doubleValue];
}
else {
//Show error
}
CLLocationCoordinate2D location;
location.latitude = latitude;
location.longitude = longitude;
return location;
}
- (MKAnnotationView *)map:(MKMapView *)map viewForAnnotation:(id )annotation{
MKAnnotationView *annView;
annView = (MKAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:annotation.title];
if(annView == nil)
annView = [[[MKAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:annotation.title] autorelease];
else
annView.annotation = annotation;
[annView setImage:[UIImage imageNamed:#"target.png"]];
annView.canShowCallout = TRUE;
return annView;
}
Please note that I only included the code that actually involves the mapview. Thanks in advance!
EDIT: I Changed the code in my Xcode document for the changes in answer 1. I am too lazy to transfer everything to the code block above, and still, the picture still doesn't work.
SHOOP DA EDIT: Thank you for replying! My solution was that I forgot to say mapView.delegate = self. Bye!
Wow so much wrong with this code :-)
First you are missing a #property declaration in your AddressAnnotation
#property (nonatomic,assign) CLLocationCoordinate2D coordinate;
In the subtitle method you do this:
return #"%#",stitle;
But this is Objective-C and not Python, so you might want to change this to:
return stitle;
Then your initWithCoordinate is completely wrong. You do not initialize super. This is better:
-(id) initWithCoordinate: (CLLocationCoordinate2D) c
{
if ((self = [super init]) != nil) {
coordinate=c;
NSLog(#"%f,%f",c.latitude,c.longitude);
}
return self;
}
Try fixing that stuff first to see if it helps :-)
I'm new to Objective C but I think the prototype for your delegate function should be :
- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id )annotation{
MKAnnotationView *annView;
The delegate name is mapView:viewForAnnotation:, not map:viewForAnnotation:
Also you AddressAnnotation doesn't implement the MKAnnotation protocol