Core Location returning 00 - iphone

Here's the full method, I didn't put the second half originally because I know it works:
-(void)showDirections
{
locationManager = [[CLLocationManager alloc] init];
[locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];
[locationManager setDelegate:self];
CLLocation *location = [locationManager location];
CLLocationCoordinate2D coordinate = [location coordinate];
NSNumber *myLatitude = [NSNumber numberWithDouble:coordinate.latitude];
NSNumber *myLongitude = [NSNumber numberWithDouble:coordinate.longitude];
double myLatitude2 = [myLatitude doubleValue];
double myLongitude2 = [myLongitude doubleValue];
NSArray *array = [dataHold objectForKey:#"Subtree"];
NSString *latitude = [NSString stringWithFormat:#"%#",[array objectAtIndex:4]];
NSString *longitude = [NSString stringWithFormat:#"%#",[array objectAtIndex:5]];
double clubLatitude = [latitude doubleValue];
double clubLongitude = [longitude doubleValue];
CLLocationCoordinate2D start = { myLatitude2, myLongitude2};
CLLocationCoordinate2D destination = { clubLatitude, clubLongitude};
NSString *googleMapsURLString = [NSString stringWithFormat:#"http://maps.google.com/?saddr=%1.6f,%1.6f&daddr=%1.6f,%1.6f",start.latitude, start.longitude, destination.latitude, destination.longitude];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:googleMapsURLString]];
}

Two issues:
1) You are doing a NSNumber box/unbox cycle that has no use whatsoever
2) Core Location is asynchronous, therefore you cannot return the user's location straight away, you must use the delegate method(s) to retrieve the location if/when it is available.
Here's an example of how it should work:
-(void)showDirections
{
locationManager = [[CLLocationManager alloc] init];
[locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];
[locationManager setDelegate:self];
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
CLLocationCoordinate2D coord = [newLocation coordinate];
NSArray *array = [dataHold objectForKey:#"Subtree"];
NSString *latitude = [NSString stringWithFormat:#"%#",[array objectAtIndex:4]];
NSString *longitude = [NSString stringWithFormat:#"%#",[array objectAtIndex:5]];
double clubLatitude = [latitude doubleValue];
double clubLongitude = [longitude doubleValue];
NSString *googleMapsURLString = [NSString stringWithFormat:#"http://maps.google.com/?saddr=%1.6f,%1.6f&daddr=%1.6f,%1.6f", coord.latitude, coord.longitude, clubLatitude, clubLongitude];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:googleMapsURLString]];
}

The fourth line of your code is where the problem begins. You cannot get the location instantly, you will need to wait until the location services notify the delegate that a location is available. I will add some comments to your code to explain:
-(void)showDirections
{
locationManager = [[CLLocationManager alloc] init];
[locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];
[locationManager setDelegate:self];
// this is not where you should be looking
CLLocation *location = [locationManager location];
// the rest of this function is not included in this example ...
}
Since you set the delegate as "self", the current class but implement the "CLLocationManagerDelegate" protocol, which defines the following two functions:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { /* */ }
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { /* */ }
That is where you will get a location provided to you.
Dont forget to update your class definition like so:
#interface MyClass : NSObject <CLLocationManagerDelegate> {
And as a side note, it seems like you do not fully understand delegates and the purpose that they serve, which is fine if you are new to Objective-C, but getting more familiar with them will certainly make your life a bit easier.
Some other helpful stuff:
A CoreLocation Tutorial (covers what you are trying to do)

Related

CLGeocoder not working

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after app launch
[window addSubview:viewController.view];
[window makeKeyAndVisible];
[window addViewForTouchPriority:viewController.view];
if(self.locationManager==nil){
locationManager=[[CLLocationManager alloc] init];
locationManager.delegate=self;
locationManager.purpose = #"We will try to tell you where you are if you get lost";
locationManager.desiredAccuracy=kCLLocationAccuracyBest;
locationManager.distanceFilter=500;
self.locationManager=locationManager;
}
geoCoder = [[CLGeocoder alloc] init];
if([CLLocationManager locationServicesEnabled]){
[self.locationManager startUpdatingLocation];
}
return YES;
}
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
lati = [[NSString alloc] initWithFormat:#"%+.6f", newLocation.coordinate.latitude];
NSLog(#"address:%#",lati);
longi = [[NSString alloc] initWithFormat:#"%+.6f", newLocation.coordinate.longitude];
NSLog(#"address:%#",longi);
CLLocationCoordinate2D coord;
coord.latitude = [lati doubleValue];
coord.longitude = [longi doubleValue];
[geoCoder reverseGeocodeLocation: newLocation completionHandler: ^(NSArray *placemarks, NSError *error)
{
//Get nearby address
CLPlacemark *placemark = [placemarks objectAtIndex:0];
//String to hold address
NSString *locatedAt = [[placemark.addressDictionary valueForKey:#"FormattedAddressLines"] componentsJoinedByString:#", "];
//Print the location to console
NSLog(#"I am currently at %#",locatedAt);
address = [[NSString alloc]initWithString:locatedAt];
NSLog(#"address:%#",address);
}];
}
I am using above code to get address by giving latitude and longitude, but control is not entering in to geocoder method, it skips it. Can anybody help me in it.
Thanks in advance.
It doesn't matter, control does not enter in the method, but it works, note the output it will work.
that is normal, because the code inside the reverseGeocodeLocation is execute inside a block.
The execution of the code inside a block occurs in another thread, so is not execute in the main thread, that's why the control don't enter inside the geocoder method.

How to get the current Location name as a string , when we know the latitude and longitude [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to retrieve user's current city name?
using the following methods i am getting latitude and longitude of the current position
- (void)viewDidLoad {
[super viewDidLoad];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
int degrees = newLocation.coordinate.latitude;
double decimal = fabs(newLocation.coordinate.latitude - degrees);
int minutes = decimal * 60;
double seconds = decimal * 3600 - minutes * 60;
NSString *lat = [NSString stringWithFormat:#"%d° %d' %1.4f\"",
degrees, minutes, seconds];
latLabel.text = lat;
degrees = newLocation.coordinate.longitude;
decimal = fabs(newLocation.coordinate.longitude - degrees);
minutes = decimal * 60;
seconds = decimal * 3600 - minutes * 60;
NSString *longt = [NSString stringWithFormat:#"%d° %d' %1.4f\"",
degrees, minutes, seconds];
longLabel.text = longt;
}
now i need to get the current location name as a string... but not required on a map, how can i do this, give me some suggestion pls,,,thanx in advance
Use this common function and just pass latitude and longitude as argument in this function.
-(NSString *)getAddressFromLatLon:(double)pdblLatitude withLongitude:(double)pdblLongitude
{
NSString *urlString = [NSString stringWithFormat:kGeoCodingString,pdblLatitude, pdblLongitude];
NSError* error;
NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString] encoding:NSASCIIStringEncoding error:&error];
locationString = [locationString stringByReplacingOccurrencesOfString:#"\"" withString:#""];
return [locationString substringFromIndex:6];
}
and declare this
#define kGeoCodingString #"http://maps.google.com/maps/geo?q=%f,%f&output=csv"
This function will return address of the latitude and longitude you are passing.
Hope It helps.
You are asking about Reverse Geocoding.. Use MKReverseGeocoding for this purpose.. This SO question explains it a bit..
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
[self.locationManager stopUpdatingLocation];
CLGeocoder * geoCoder = [[CLGeocoder alloc] init];
[geoCoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error) {
for (CLPlacemark * placemark in placemarks)
{
NSString *addressTxt = [NSString stringWithFormat:#"%# %#,%# %#",
[placemark subThoroughfare],[placemark thoroughfare],
[placemark locality], [placemark administrativeArea]];
NSLog(#"%#",addressTxt);
}
}];
}
You can use the google API to get the address. Probably you have to send lat and long value as parameter.
Use google reverse geoCoding
sample http call here http://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&sensor=true_or_false
Maybe this is what you will have to use MKReverseGeocoder

Get current location using CLLocationCoordinate2D

I am trying to get current location of user using CLLocationCoordinate2D. I want the values in the format like
CLLocationCoordinate2D start = {-28.078694,153.382844 };
So that I can use them like following:
NSString *urlAddress = [NSString
stringWithFormat:#"http://maps.google.com/?saddr=%1.6f,%1.6f&daddr=%1.6f,%1.6f",
start.latitude, start.longitude,
destination.latitude, destination.longitude];
I used
CLLocation *location = [[CLLocation alloc]init ];
CLLocationDegrees currentLatitude = location.coordinate.latitude;
CLLocationDegrees currentLongitude = location.coordinate.longitude;
to get current lat & long.
But I am getting 0.000 for both when I try to test. I am testing on iPhone 4s.
If there is any sample code, it will be great.
Add CoreLocation framework first and then use the following code...and your viewController must implement CLLocationManagerDelegate
-(void)findCurrentLocation
{
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
if ([locationManager locationServicesEnabled])
{
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager startUpdatingLocation];
}
CLLocation *location = [locationManager location];
CLLocationCoordinate2D coordinate = [location coordinate];
NSString *str=[[NSString alloc] initWithFormat:#" latitude:%f longitude:%f",coordinate.latitude,coordinate.longitude];
NSLog(#"%#",str);
}
in AppDelegate.h declare following variable. and implement
CLLocationManagerDelegate delegate.
CLLocationManager *locationManager;
CLLocation *currentLocation;
in AppDelegate.h.m file write following code.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
self.currentLocation = newLocation;
self.currentLat = newLocation.coordinate.latitude;
self.currentLong = newLocation.coordinate.longitude;
}
You need to use CLLocationManager to get a user's location. CLLocation is only a class of objects used to represent locations, it can't get user location by it self.
For more details and example, please follow to Apple docs on Location Awareness Programming.
CLLocationCoordinate2D location = [[[mapview userLocation] location] coordinate];
NSLog(#"Location found from Map: %f %f",location.latitude,location.longitude);
and also refer the link(without mapview0
https://developer.apple.com/library/ios/#samplecode/LocateMe/Introduction/Intro.html
use location manager to get lat and long, follow this tutorial for sample code http://www.edumobile.org/iphone/miscellaneous/how-to-get-current-latitude-and-longitude-in-iphone/
-(void)findCurrentLocation
{
if ([CLLocationManager locationServicesEnabled])
{
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager startUpdatingLocation];
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
[self setLocation:[[manager location] coordinate]];
}

How to get user's location in a later screen for the MapKit?

I am building a navigation-based app for the iPhone, where I calculate the user's geolocation in the RootViewController (this is the code for my RootViewController.h) class:
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import "SecondViewController.h"
#import <sqlite3.h>
#interface RootViewController : UITableViewController <CLLocationManagerDelegate>{
SecondViewController *secondViewController;
NSUInteger numUpdates;
CLLocationManager *lm;
CLLocation *firstLocation;
CLLocation *secondLocation;
}
#property (nonatomic, retain) SecondViewController *secondViewController;
#property (nonatomic, retain) NSMutableArray *restaurants;
#property (nonatomic, retain) NSArray *sortedRestaurants;
here is the code for my RootViewController.m class:
- (void) locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
CLLocationCoordinate2D location;
NSString *lat = [[NSString alloc] initWithFormat:#"%g", newLocation.coordinate.latitude];
double lat1 = newLocation.coordinate.latitude;
location.latitude = newLocation.coordinate.latitude; //setting the latitude property of the location variable
NSString *lng = [[NSString alloc] initWithFormat:#"%g", newLocation.coordinate.longitude];
double lon1 = newLocation.coordinate.longitude;
location.longitude = newLocation.coordinate.longitude; //setting the longitude property of the location variable
MapViewController *mController = [[MapViewController alloc] initWithNibName:#"MapViewController" bundle:[NSBundle mainBundle]];
self.mapViewController = mController;
[mController release];
self.mapViewController.userCoord = [[[CLLocation alloc] initWithLatitude:location.latitude longitude:location.longitude] autorelease];
//in the above line I get the error, "incompatible type for argument 1 of 'setUserCoord' "
[lm stopUpdatingLocation];
Because I am calculating the user's geolocation in the RootViewController class, I would like to re-use these value when I use the MapKit later on in the application in the MapViewController.m class:
- (void)viewDidLoad {
[super viewDidLoad];
MKCoordinateRegion region;
MKCoordinateSpan span;
region.center = userCoord;
/* userCoord is declared as an object of type CLLocationCoordinate2D
in MapViewController.h, and is declared as a property, and then
synthesized in the .m class. Even though I am trying to center
the map on the user's coordinates, the map is neither centering,
nor zooming to my settings. */
span.latitudeDelta = 0.2;
span.longitudeDelta = 0.2;
region.span = span;
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
mapView.showsUserLocation = YES;
[mapView setRegion:region animated:YES];
RestaurantAnnotation *rAnnotation = [[RestaurantAnnotation alloc] init];
rAnnotation.title = restaurantObj.name;
rAnnotation.subTitle = restaurantObj.address;
CLLocationCoordinate2D newCoord = {restaurantObj.latitude, restaurantObj.longitude};
rAnnotation.coordinate = newCoord;
[mapView addAnnotation:rAnnotation];
}
I would like the map to be centered on the user's location, and choose appropriate span values as well.
There are a lot of ways to do this, the way I've done it is to store the location in NSUserDefaults and access that value later when I'm presenting my map. The benefit of doing it this way is that the user's location persists between runs, so if the next time they open the app they're having trouble getting a GPS signal, you still have a location to display.
This code may not be 100%, i'm writing it from memory:
#define latKey #"latKey"
#define lonKey #"lonKey"
#define locationKey #"locationKey"
- (void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSNumber *lat = [NSNumber numberWithDouble:newLocation.coordinate.latitude];
NSNumber *lon = [NSNumber numberWithDouble:newLocation.coordinate.longitude];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:lat, latKey, lon, lonKey, nil];
[[NSUserDefaults standardUserDefaults] addObjectForKey:locationKey];
}
- (void)viewDidLoad {
NSDictionary *dict = [[NSUserDefaults standardUserDefaults] dictForKey:locationKey];
CLLocation *location = [[CLLocation alloc] initWithLatitude:[[dict objectForKey:lat] doubleValue] longitude:[[dict objectForKey:lon] doubleValue]];
}

CLLocationDistance: Cant get "getDistanceFrom" to work

view based app,
.m
- (void)viewDidLoad {
[super viewDidLoad];
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.delegate = self;
[[self locationManager] startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
CurrentLocation = newLocation;
[locationManager stopUpdatingLocation];
myActivity.hidden=YES;
[self reStart];
}
-(void)reStart{
[self checkAndCreateDatabase]; //Sucess
[self readFromDatabase]; //Success if I comment the get distance part
[self sort]; //Success
}
-(void) readFromDatabase {
...
CLLocationCoordinate2D cord;
cord.latitude = [[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)] doubleValue];
cord.longitude =[[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)] doubleValue];
NSDate *today = [NSDate date];
CLLocation *objectLocation = [[CLLocation alloc] initWithCoordinate:cord altitude:1 horizontalAccuracy:1 verticalAccuracy:-1 timestamp:today];
CLLocationDistance distance = [objectLocation getDistanceFrom:CurrentLocation]/1000;
NSLog([NSString stringWithFormat:#"%.0f", distance]);
}
What is wrong?
debugger says:
obj_msgSend
0x912e8688 <+0024> mov 0x20(%edx),%edi
object from database:
long: 59.291114
lat: 17.816191
Use distanceFromLocation: instead
Is CurrentLocation an instance-variable/property? You are setting it directly without an accessor and you are not retaining it. If it is released before you use it in getDistance: it will cause a crash.
If it is a property use the self.CurrentLocation to ensure it is retained.
Also, the construction...
NSLog([NSString stringWithFormat:#"%.0f", distance]);
... is risky and redundant. Use...
NSLog(#"%.0f", distance);
... instead.