Is CLGeocoder just that coarse right now? I was expecting something relatively close to a street address. I'm testing on the 5.1 simulator and using ARC. I made a quick test project right now with the following if that helps:
- (IBAction)getLocationPressed {
if ([CLLocationManager locationServicesEnabled] &&
[CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized) {
[self.geoCoder reverseGeocodeLocation:self.locationManager.location completionHandler:
^(NSArray *placemarks, NSError *error) {
// Note: there is NO guarantee that the CLGeocodeCompletionHandler will be invoked on the main thread
dispatch_async(dispatch_get_main_queue(),^ {
NSLog(#"placemarks count: %d", [placemarks count]);
CLPlacemark *placemark = [placemarks objectAtIndex:0];
// Note: if a poor location is specified, there may be multiple placemarks for the given location
NSString *currentAddress = [[placemark.addressDictionary valueForKey:#"FormattedAddressLines"] componentsJoinedByString:#", "];
NSLog(#"I am currently at %#", currentAddress);
self.locationLabel.text = currentAddress;
});
}];
}
}
#pragma mark - CLLocationManager Delegate Methods
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
// do something...
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error {
if (error.code == kCLErrorDenied) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error!"
message:#"this can not work without location services enabled"
delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
}
#pragma mark - Lifecycle Methods
- (void)viewDidLoad {
[super viewDidLoad];
self.locationManager.delegate = self;
self.locationManager.purpose = REASON_FOR_USING_LOCATION;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;//kCLLocationAccuracyNearestTenMeters;
[self.locationManager startUpdatingLocation];
}
Thanks
YESSSS! It turns out that I just wasn't enabling location in the simulator. It actually works if I test it on my device. Here's an example of with the full .m file if it helps anyone. I've set up a couple labels and a rounded rect button that you'll see from the code:
#define REASON_FOR_USING_LOCATION (#"to find the closest widget")
#interface ViewController () <CLLocationManagerDelegate>
#property (weak, nonatomic) IBOutlet UILabel *locationLabel;
#property (strong, nonatomic) CLLocationManager *locationManager;
#property (strong, nonatomic) CLGeocoder *geoCoder;
#end
#implementation ViewController
#pragma mark - Getters/Setters
#synthesize locationLabel = _locationLabel;
#synthesize locationManager = _locationManager;
#synthesize geoCoder = _geoCoder;
// lazily instantiate as required
- (CLGeocoder *)geoCoder {
if (!_geoCoder) _geoCoder = [CLGeocoder new];
return _geoCoder;
}
- (CLLocationManager *)locationManager {
if (!_locationManager) _locationManager = [CLLocationManager new];
return _locationManager;
}
#pragma mark - Target/Action Methods
- (IBAction)clearLocationPressed {
self.locationLabel.text = #"";
}
- (IBAction)getLocationPressed {
if ([CLLocationManager locationServicesEnabled] &&
[CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized) {
[self.geoCoder reverseGeocodeLocation:self.locationManager.location completionHandler:
^(NSArray *placemarks, NSError *error) {
// Note: there is NO guarantee that the CLGeocodeCompletionHandler will be invoked on the main thread
dispatch_async(dispatch_get_main_queue(),^ {
NSLog(#"placemarks count: %d", [placemarks count]);
CLPlacemark *placemark = [placemarks objectAtIndex:0];
// Note: if a poor location is specified, there may be multiple placemarks for the given location
NSString *currentAddress = [[placemark.addressDictionary valueForKey:#"FormattedAddressLines"] componentsJoinedByString:#", "];
NSLog(#"I am currently at %#", currentAddress);
self.locationLabel.text = currentAddress;
});
}];
}
}
#pragma mark - CLLocationManager Delegate Methods
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
// do something...
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error {
if (error.code == kCLErrorDenied) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error!"
message:#"this can not work without location services enabled"
delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
}
#pragma mark - Lifecycle Methods
- (void)viewDidLoad {
[super viewDidLoad];
self.locationManager.delegate = self;
self.locationManager.purpose = REASON_FOR_USING_LOCATION;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;//kCLLocationAccuracyNearestTenMeters;
[self.locationManager startUpdatingLocation];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (void)viewDidUnload {
[self setLocationLabel:nil];
[self setLocationManager:nil];
[self setGeoCoder:nil];
[super viewDidUnload];
}
#end
Related
I am trying to get the current city and country using CLLocationManager with below code -
#pragma mark - Core Location Delegate Methods
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
CLGeocoder *reverseGeocoder = [[CLGeocoder alloc] init];
[reverseGeocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error)
{
NSLog(#"reverseGeocodeLocation:completionHandler: Completion Handler called!");
if (error){
NSLog(#"Geocode failed with error: %#", error);
return;
}
NSLog(#"Received placemarks: %#", placemarks);
CLPlacemark *myPlacemark = [placemarks objectAtIndex:0];
NSString *countryCode = myPlacemark.ISOcountryCode;
NSString *countryName = myPlacemark.country;
NSString *city1 = myPlacemark.subLocality;
NSString *city2 = myPlacemark.locality;
NSLog(#"My country code: %#, countryName: %#, city1: %#, city2: %#", countryCode, countryName, city1, city2);
}];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
CLLocationDirection th=[newHeading trueHeading];
NSLog(#"True Heading value is=%f",th);
CLLocationDirection magnetic=[newHeading magneticHeading];
NSLog(#"Magnetic Heading value is=%f",magnetic);
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSString *errorType = (error.code == kCLErrorDenied) ? NSLocalizedString(#"access_denied", #"") : NSLocalizedString(#"unknown_error", #"");
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:NSLocalizedString(#"error_getting_location", #"")
message:errorType
delegate:nil
cancelButtonTitle:NSLocalizedString(#"ok", #"")
otherButtonTitles:nil];
[alert show];
}
It always gives the result with -
My country code: IN, countryName: India, city1: (null), city2: (null)
I don't know what may be the issue for this. Has anyone faced this issue that can't able to get the city name using CLLocationManager
EDITED:
- (void) getReverseGeocode
{
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
if(currentLatLong.count > 0)
{
CLLocationCoordinate2D myCoOrdinate;
myCoOrdinate.latitude = LatValue;
myCoOrdinate.longitude = LangValue;
CLLocation *location = [[CLLocation alloc] initWithLatitude:myCoOrdinate.latitude longitude:myCoOrdinate.longitude];
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error)
{
if (error)
{
NSLog(#"failed with error: %#", error);
return;
}
if(placemarks.count > 0)
{
NSString *MyAddress = #"";
NSString *city = #"";
if([placemark.addressDictionary objectForKey:#"FormattedAddressLines"] != NULL)
MyAddress = [[placemark.addressDictionary objectForKey:#"FormattedAddressLines"] componentsJoinedByString:#", "];
else
MyAddress = #"Address Not founded";
if([placemark.addressDictionary objectForKey:#"SubAdministrativeArea"] != NULL)
city = [placemark.addressDictionary objectForKey:#"SubAdministrativeArea"];
else if([placemark.addressDictionary objectForKey:#"City"] != NULL)
city = [placemark.addressDictionary objectForKey:#"City"];
else if([placemark.addressDictionary objectForKey:#"Country"] != NULL)
city = [placemark.addressDictionary objectForKey:#"Country"];
else
city = #"City Not founded";
NSLog(#"%#",city);
NSLog(#"%#", MyAddress);
}
}];
}
}
You know about the apple maps and there database for the location, better try with google places api for getting more accurate and detailed information for reverse geocoding. I have tried same for auto filling the place names, but didn't worked,so went using google places api, there is one more free api try geonames.org
in .h file
#import <CoreLocation/CoreLocation.h>
#interface ClassDemo : NSObject<NSXMLParserDelegate,CLLocationManagerDelegate>
{
BOOL got;
BOOL needParser;
NSMutableArray *currentplaceArray;
}
#property (nonatomic, retain) CLLocation *currentLocation;
#property (nonatomic, getter = isResultsLoaded) BOOL resultsLoaded;
#property (strong, nonatomic) CLLocationManager *locationManager;
#property (strong, nonatomic) CLGeocoder *geoCoder;
in .m
#synthesize locationManager,currentLocation;
- (void)viewDidLoad
{
got=NO;
needParser=YES;
currentplaceArray=[[NSMutableArray alloc]init];
//******** Location MAnager Allocation And Intialization********//
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate=self;
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
if ([self isResultsLoaded])
{
return;
}
[self setResultsLoaded:YES];
currentLocation = newLocation;
NSLog(#"%#",currentLocation);
NSXMLParser *parser = [[NSXMLParser alloc]initWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat: #"http://maps.googleapis.com/maps/api/geocode/xml?latlng=%f,%f&sensor=false",newLocation.coordinate.latitude,newLocation.coordinate.longitude]]];
[parser setDelegate:self];
[parser parse];
}
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
NSLog(#"%#",elementName);
if([elementName isEqualToString:#"formatted_address"])
{
got = YES; //got is a BOOL
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if(got&&needParser){
got=NO;
NSLog(#"the address is = %#",string);
NSArray *tempPlaceArray=[string componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#",/"]];
NSLog(#"%#",tempPlaceArray);
for(int i=0; i <[tempPlaceArray count]; i++)
{
NSString *tempString=[[tempPlaceArray objectAtIndex:i]stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSLog(#"%#",tempString);
if (![currentplaceArray containsObject:tempString])
{
if ([tempString length]!=0)
{
[currentplaceArray addObject:tempString];
}
}
}
needParser=NO;
TempLocation *obj=[[TempLocation alloc]init];
obj.countryName=[currentplaceArray objectAtIndex:[currentplaceArray count]-1];
obj.stateName=[currentplaceArray objectAtIndex:[currentplaceArray count]-2];
obj.cityName=[currentplaceArray objectAtIndex:[currentplaceArray count]-3];
obj.fullAdd=string;
[[Database getDBObject]insertIntoCurrentLocationTable:obj.cityName :obj.stateName :obj.countryName:obj.fullAdd];
}
}
make a temp location class for temporary storage. And you can also save to the database as.
Enjoy Coding.
Even I noticed same issue. After many trail and error I found the problem with wifi I was using. If the signal strength is low you'll get city as nil. Try changing your connection.
My core location works but I receive a warning at this line of code. locationManager.delegate = self; The warning is Assigning to 'id' from incompatible type 'phoneLocationViewController *const __strong'. How do I get rid of this warning? Here is my code
.h
#interface phoneLocationViewController : UIViewController {
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation
*)newLocation fromLocation:(CLLocation *)oldLocation;
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error;
#property (nonatomic, retain) CLLocationManager *locationManager;
#property (nonatomic, retain) CLLocation *currentLocation;
.m
#synthesize locationManager, currentLocation;
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation
*)newLocation fromLocation:(CLLocation *)oldLocation {
self.currentLocation = newLocation;
if(newLocation.horizontalAccuracy <= 100.0f) { [locationManager stopUpdatingLocation]; }
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
if(error.code == kCLErrorDenied) {
[locationManager stopUpdatingLocation];
} else if(error.code == kCLErrorLocationUnknown) {
// retry
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error retrieving location"
message:[error description]
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
}
- (void)viewDidLoad
{
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self; (I GET THE WARNING HERE)
[locationManager startUpdatingLocation];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[locationManager stopUpdatingLocation];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
Declare your class as implementing the protocol of the delegate of the location manager.
#interface phoneLocationViewController : UIViewController <CLLocationManagerDelegate> {
You should add the CLLocationManagerDelegate to your interface declaration.
#interface phoneLocationViewController : UIViewController <CLLocationManagerDelegate> {
....
}
How can I make my application update location only when a button is pressed?
I have a button named "REFRESH". Everytime this button is pressed, I want to show my user their location. For example, 51 Bourke Street, Victoria.
However, I do not want to update my location regularly. I want to update its location only when the button is pressed, to save battery power.
What do you think? Am I doing it correctly?
I have these classes:
VoteViewController.h and VoteViewController.m
CoreLocationController.h and CoreLocationController.m
This is what I have:
VoteViewController.h class
#interface VoteViewController : UIViewController <CoreLocationControllerDelegate>
{
CoreLocationController *coreController;
}
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
- (void)geoReverseAddress:(MKPlacemark *)placeMark;
- (IBAction)refreshButtonPressed;
VoteViewController.m class
- (void)viewDidLoad
{
[super viewDidLoad];
coreController = [[CoreLocationController alloc] init];
coreController.delegate = self;
}
- (IBAction)refreshButtonPressed
{
NSLog(#"Refresh Button pressed");
label.text = [NSString stringWithString:#""];
[coreController.locationManager startUpdatingLocation];
}
- (void)locationUpdate:(CLLocation *)location
{
comments.text = [location description];
[coreController.locationManager stopUpdatingLocation];
}
- (void)locationError:(NSError *)error
{
comments.text = [error description];
[coreController.locationManager stopUpdatingLocation];
}
- (void)geoReverseAddress:(MKPlacemark *)placeMark
{
label.text = [NSString stringWithFormat:#"%# %#, %#", [placeMark subThoroughfare],
[placeMark thoroughfare], [placeMark locality]];
}
CoreLocationController.h class
#protocol CoreLocationControllerDelegate <NSObject>
#required
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
- (void)geoReverseAddress:(MKPlacemark *)placeMark;
#end
#interface CoreLocationController : NSObject <CLLocationManagerDelegate, MKReverseGeocoderDelegate>
{
CLLocationManager *locationManager;
id delegate;
MKReverseGeocoder *reverse;
}
#property(nonatomic, retain) CLLocationManager *locationManager;
#property(nonatomic, retain) id delegate;
#end
CoreLocationController.m class
-(id) init
{
self = [super init];
if (self != nil)
{
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.delegate = self;
self.locationManager.distanceFilter = kCLHeadingFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
}
return self;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(#"Update location");
[self.delegate locationUpdate:newLocation];
reverse = [[MKReverseGeocoder alloc] initWithCoordinate:[newLocation coordinate]];
reverse.delegate = self;
[reverse start];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
[self.delegate locationError:error];
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error
{
[self.delegate locationError:error];
[reverse cancel];
[reverse release];
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark
{
[self.delegate geoReverseAddress:placemark];
[reverse cancel];
[reverse release];
}
When you first fire up CLLocationManager, you're very likely to get one stale location from the last time it ran. Once that's out of the way, you're going to start getting very inaccurate locations while the device uses WiFi sniffing and cell triangulation, while the GPS looks for a fix.
So in your didUpdateToLocation method, you probably want to throw away the first hit, and then test the .horizontalAccuracy value of your newLocation object for a low enough value to trust.
Apart from that, I don't see anything bad about what you've sent here. I'm not sure I'd go to the trouble of wrapping the location fetching work in its own class, I'd probably just do that out in my viewController. But that's a style choice. If you're reusing this functionality elsewhere, what you've got here is obviously the way to go.
I want to calculate the maximum altitude, minimum altitude, and average altitude of the current location through CLLocationManager. I know how to calculate the altitude using the following code:
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface test : UIViewController <CLLocationManagerDelegate> {
CLLocationManager *locationManager;
CLLocation *startingPoint;
IBOutlet UILabel *altitudeLabel;
}
#property (retain, nonatomic) CLLocationManager *locationManager;
#property (retain, nonatomic) CLLocation *startingPoint;
#property (retain, nonatomic) UILabel *altitudeLabel;
#end
//this is my test.h class
#import "test.h"
#implementation test
#synthesize locationManager;
#synthesize startingPoint;
#synthesize altitudeLabel;
#pragma mark -
- (void)viewDidLoad {
self.locationManager = [[CLLocationManager alloc] init];
[locationManager startUpdatingLocation];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)dealloc {
[locationManager release];
[startingPoint release];
[altitudeLabel release];
[super dealloc];
}
#pragma mark -
#pragma mark CLLocationManagerDelegate Methods
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
if (startingPoint == nil)
self.startingPoint = newLocation;
NSString *altitudeString = [[NSString alloc] initWithFormat:#"%gm", newLocation.altitude];
altitudeLabel.text = altitudeString;
[altitudeString release];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSString *errorType = (error.code == kCLErrorDenied) ? #"Access Denied" : #"Unknown Error";
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error gettingg location from Core Location" message:errorType delegate:nil cancelButtonTitle:#"Okay" otherButtonTitles:nil];
[alert show];
[alert release];
}
#end
Through this I only get the altitude value, but I need to know how to calculate average altitude, minimum altitude, and maximum altitude. Does anyone know how to do this?
Instead of storing all the altitudes in an array as others have suggested, you could just store the current average/min/max and update it as you go.
int numUpdates = 0;
double averageAlt = 0.0;
double minAlt = DBL_MAX;
double maxAlt = DBL_MIN;
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
if (newLocation.altitude < minAlt) {
minAlt = newLocation.altitude;
}
if (newLocation.altitude > maxAlt) {
maxAlt= newLocation.altitude;
}
double sum = numUpdates * averageAlt;
sum+=newLocation.altitude;
numUpdates++;
averageAlt = sum / numUpdates;
}
I describe how to get min in the minAltitude method. I'll leave it to you to find max and average.
in .h:
NSMutableArray *altitudes;
in .m:
- (void) viewDidLoad {
[super viewDidLoad];
altitudes = [[NSMutableArray alloc] init];
}
- (void) dealloc {
[altitudes release];
[super dealloc];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
[altitudes addObject:[NSNumber numberWithDouble:newLocation.altitude]];
}
- (double) minAltitude
{
double min = DBL_MAX;
double value;
NSNumber *altitude;
for (altitude in altitudes) {
value = [altitude doubleValue];
if (value < min) {
min = value;
}
}
return min;
}
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;
}