Location manager giving really bad coordinates - gps

I tried writing a coordinate using Core Location, and it's running nicely, only thing is, it's a vegetable when it comes to coordinates.
This is the code that gets the coordinates.
- (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
{
if (startingLocation == nil)
self.startingLocation = newLocation;
NSString *latitudeString = [[NSString alloc] initWithFormat:#"%g",newLocation.coordinate.latitude];
latitudeLabel.text = latitudeString;
NSString *longitudeString = [[NSString alloc] initWithFormat:#"%g",newLocation.coordinate.longitude];
longitudeLabel.text = longitudeString;
NSString *horizontalAccuracyString = [[NSString alloc] initWithFormat:#"%g",newLocation.horizontalAccuracy];
horizontalAccuraryLabel.text = horizontalAccuracyString;
NSString *altitudeString = [[NSString alloc] initWithFormat:#"%g",newLocation.altitude];
altitudeLabel.text = altitudeString;
NSString *verticalAccuracyString = [[NSString alloc] initWithFormat:#"%g",newLocation.verticalAccuracy];
verticalAccuracyLabel.text = verticalAccuracyString;
CLLocationDistance distance = [newLocation getDistanceFrom:startingLocation];
NSString *distanceString = [[NSString alloc] initWithFormat:#"%g",distance];
distanceTraveledLabel.text = distanceString;
}
It's giving me Lat: 37.7858 Long: -122.406 which is somewhere in USA, while I'm running the code from Europe, Romania...
Could it be because it's running from a simulator?
Also I know the locationManager:didUpdateToLocation:fromLocation is deprecated, but I tried doing it with:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
but I don't know how to access the elements of [location lastObject].

That lat & long combination is San Francisco, which is the home base for many commuting (via a posh luxury commuter bus) Apple employees.
You can set the location that your simulator is working with pretty easily:
Latitude & Longitude for Bucharest is "44.4325" & "26.103889", as far as I know.
As for accessing the elements of "[location lastObject]", the object(s) in that array will be a CLLocation object which has a "coordinate" property. If you get a "didUpdateLocations:" delegate method being called, that array will always have at least one location (which is what you access via "lastObject").

Related

Why I am not able to get Latitude and longitude on real device in Objective C

I am new in iOS and I am facing problem to get current Latitude and Longitude on the real device where as I am able to get latitude and Longitude on simulator.
My code is like this
if (nil == locationManager)
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
//Configure Accuracy depending on your needs, default is kCLLocationAccuracyBest
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
// Set a movement threshold for new events.
locationManager.distanceFilter = kCLDistanceFilterNone; // meters
[locationManager startUpdatingLocation];
Currentlatitude = locationManager.location.coordinate.latitude;
Currentlongitude = locationManager.location.coordinate.longitude;
NSLog(#"Latitude =%f",Currentlatitude);
NSLog(#"Longitude =%f",Currentlongitude);
CheckString=#"2";
// Your location from latitude and longitude
CLLocation *location = [[CLLocation alloc] initWithLatitude:Currentlatitude longitude:Currentlongitude];
// Call the method to find the address
[self getAddressFromLocation:location completionHandler:^(NSMutableDictionary *d) {
NSLog(#"address informations : %#", d);
// NSLog(#"formatted address : %#", [placemark.addressDictionary valueForKey:#"FormattedAddressLines"]);
NSLog(#"Street : %#", [d valueForKey:#"Street"]);
NSLog(#"ZIP code : %#", [d valueForKey:#"ZIP"]);
NSLog(#"City : %#", [d valueForKey:#"City"]);
CityNameCurrent=[d valueForKey:#"City"];
// etc.
} failureHandler:^(NSError *error) {
NSLog(#"Error : %#", error);
}];
- (void)getAddressFromLocation:(CLLocation *)location completionHandler:(void (^)(NSMutableDictionary *placemark))completionHandler failureHandler:(void (^)(NSError *error))failureHandler
{
NSMutableDictionary *d = [NSMutableDictionary new];
CLGeocoder *geocoder = [CLGeocoder new];
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
if (failureHandler && (error || placemarks.count == 0)) {
failureHandler(error);
} else {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
if(completionHandler) {
completionHandler(placemark.addressDictionary);
}
}
}];
}
In ViewDidLod()
mapViewMap.delegate=self;
mapViewMap.myLocationEnabled=YES;
locationtbl.hidden=YES;
if (nil == locationManager)
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
//Configure Accuracy depending on your needs, default is kCLLocationAccuracyBest
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
// Set a movement threshold for new events.
locationManager.distanceFilter = kCLDistanceFilterNone; // meters
[locationManager startUpdatingLocation];
Currentlatitude = locationManager.location.coordinate.latitude;
Currentlongitude = locationManager.location.coordinate.longitude;
NSLog(#"Latitude =%f",Currentlatitude);
NSLog(#"Longitude =%f",Currentlongitude);
mapViewMap.settings.myLocationButton = YES;
mapViewMap.settings.scrollGestures = YES;
mapViewMap.settings.zoomGestures = YES;
mapViewMap.settings.tiltGestures=YES;
mapViewMap.settings.rotateGestures=NO;
mapViewMap.settings.compassButton = YES;
I am not getting what I am doing wrong.Please help.Thanks in Advance!
The simulator doesn't have to wait for a fix before generating a location. The device does. You have to implement a delegate for the location manager and wait for the delegate to be called with an update.
You need to implement CLLocationManager delegate method didUpdateLocations, it is where you get location updates.
You can do it like this.
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
// latest location
self.currentLocation = [locations lastObject];
float longitude = self.currentLocation.coordinate.longitude;
float latitude = self.currentLocation.coordinate.latitude;
// Here you can perform operations with your location coordinates
}
You also need to add following entries in your .plist file based on your location need.
NSLocationWhenInUseUsageDescription
or
NSLocationAlwaysUsageDescription
And request the permission for location usage by calling
[locationManager requestWhenInUseAuthorization];
or
[locationManager requestAlwaysAuthorization]
Documentation link Location and Maps Programming Guide
You also need to add one (or both) of the following keys to you plist:
NSLocationWhenInUseUsageDescription
or
NSLocationAlwaysUsageDescription
and call correspondingly either
[self.locationManager requestWhenInUseAuthorization]
or
[self.locationManager requestAlwaysAuthorization]

Finding place name from google Place search

I want to find the place name from lat and long.I am using google place api.
How can I achieve this
Now I can search for nearby with that lat and long using this
https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=-33.8670522,151.1957362&radius=500&types=food&name=harbour&sensor=false&key=AddYourOwnKeyHere
You can use MKReverseGeoCoder to get the name, district, info, etc. of a given latitude and longtitude. However, notice that it is deprecated.
The ViewController should be the delegate of MKReverseGeocoderDelegate. A sample usage of MKReverseGeoCoder is;
- (void)viewDidLoad {
CLLocationCoordinate2D coordinates;
coordinates.latitude = 33.8670522;
coordinates.longitude = 151.1957362;
CLLocation *location = [[CLLocation alloc] initWithLatitude:coordinates.latitude longitude:coordinates.longitude];
MKReverseGeocoder* rev = [[MKReverseGeocoder alloc] initWithCoordinate:location.coordinate];
rev.delegate = self;
[rev start];
[super viewDidLoad];
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error {
NSLog(#"Error with reverse geo coder.");
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark {
NSLog(#"Geo coder finished successfully");
NSString *administrativeArea = placemark.administrativeArea;
NSString *thoroughfare = placemark.thoroughfare;
NSLog(#"%# %#", administrativeArea, thoroughfare);
}

List of closest annotations in MapKit

I'm developing an iPhone app with annotations on a map, and I've finished inserting all the annotations. The code I've used for all the annotations (x100) is:
CLLocationCoordinate2D theCoordinate1;
theCoordinate1.latitude = 59.92855;
theCoordinate1.longitude = 10.80467;
MyAnnotation* myAnnotation1=[[MyAnnotation alloc] init];
myAnnotation1.coordinate=theCoordinate1;
myAnnotation1.title=#"Økern Senter - DNB";
myAnnotation1.subtitle=#"Økernveien 145, 0580 OSLO";
[mapView addAnnotation:myAnnotation1];
[annotations addObject:myAnnotation1];
What I'm wondering about is how can I get all these locations in a list that shows the closest annotations to the users location?
What you need to do is calculate the distance between the user and the annotations.
First off, in your MyAnnotation, add a variable keeping the distance value:
Add the following to MyAnnotation.h:
#property (nonatomic, assign) CLLocationDistance distance;
and the synthesize to the .m file ofcourse.
Second, in your mapView class (the one keeping the annotations ect) add the following code when you recieve a new location:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
[...]
for (MyAnnotation *annotation in self.mapView.annotations) {
CLLocationCoordinate2D coord = [annotation coordinate];
CLLocation *anotLocation = [[CLLocation alloc] initWithLatitude:coord.latitude longitude:coord.longitude];
annotation.distance = [newLocation distanceFromLocation:anotLocation];
}
NSArray *sortedArray;
sortedArray = [self.mapView.annotations sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
NSNumber *first = [NSNumber numberWithDouble:[(MyAnnotation*)a distance]];
NSNumber *second = [NSNumber numberWithDouble:[(MyAnnotation*)b distance]];
return [first compare:second];
}];
[...]
}
You can now use the sortedArray as source for a tableView ect, which is sorted according distance from closest to longest distance.
Of course

Programmatically getting directions using Apple Maps

I'm a bit confused by the documentation. After some research and experimentation, this is what I have.
if ([self canUseMKMapItem]) {
[self iosTheMap];
} else {
[self googleTheMap];
}
Using this to detect whether we can use the IOS6 mapping features:
- (BOOL) canUseMKMapItem {
Class itemClass = [MKMapItem class];
return (itemClass && [itemClass respondsToSelector:#selector(openMapsWithItems:launchOptions:)]);
}
This for IOS5, using Google Maps. It automatically takes us to a screen with a list of directions from the current address (if the user allows) to the destination.
- (void)googleTheMap
{
NSNumber *userLat = [[NSNumber alloc]initWithDouble:mapView.userLocation.coordinate.latitude];
NSNumber *userLong = [[NSNumber alloc]initWithDouble:mapView.userLocation.coordinate.longitude];
NSMutableString *queryString = [NSMutableString stringWithFormat:#"http://maps.google.com/?saddr=%#,%#&daddr=",userLat,userLong];
NSString *address = [partnerObject valueForKey:ATTRIBUTE_ADDRESS];
[queryString appendString:address];
NSString *escaped = [queryString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:escaped]];
}
Here's the tricky part--this is what I'm trying to do to use Apple Maps
- (void)iosTheMap {
NSNumber * latitude = [partnerObject valueForKey:ATTRIBUTE_LATITUDE];
NSNumber * longitude = [partnerObject valueForKey:ATTRIBUTE_LONGITUDE];
CLLocationCoordinate2D coordinate;
coordinate.latitude = latitude.doubleValue;
coordinate.longitude = longitude.doubleValue;
NSMutableDictionary *addressDictionary = [[NSMutableDictionary alloc] init];
[addressDictionary setValue:[partnerObject valueForKey:ATTRIBUTE_ADDRESS] forKey:kABPersonAddressStreetKey];
MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:coordinate addressDictionary:addressDictionary];
MKMapItem *mapItem = [[MKMapItem alloc] initWithPlacemark:placemark];
[mapItem openInMapsWithLaunchOptions:nil];
}
This "works," sort of. It takes the user to a map screen with a pin showing the address. The user can tap that and get directions. However, I have a few reservations about this approach:
I have a compiler warning where I set kABPersonAddressStreetKey: "Incompatible pointer types sending 'const CFStringRef' (aka 'const struct __CFString *const') to parameter of type 'NSString *'"
The string value I am using is the full address. I use that value for the street address, although the address values are meant to be more atomic--street, city, state. It seems to work, but I'm concerned this isn't the right way to do it.
It would be nice if Apple Maps showed the name of the business/destination, not just the address.
It would be great to have Apple Maps automatically show the directions, instead of a map with the destination point, saving the user a few taps.
Any suggestions for how I can improve my approach? Although it seems to work, I suspect that it is not the right way.
You are pretty close. You need to specify the Launch Options dictionary for the openInMapsWithLaunchOptions function using the MKLaunchOptionsDirectionsModeDriving, MKLaunchOptionsDirectionsModeKey value and key.
Class itemClass = [MKMapItem class];
if (itemClass && [itemClass respondsToSelector:#selector(openMapsWithItems:launchOptions:)]) {
// Use iOS 6 maps
CLLocationCoordinate2D coordinate = [((LocationAnnotation*)[map.annotations objectAtIndex:0]) coordinate];
MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:coordinate addressDictionary:nil];
MKMapItem *mapItem = [[MKMapItem alloc] initWithPlacemark:placemark];
[mapItem openInMapsWithLaunchOptions:[NSDictionary dictionaryWithObjectsAndKeys:MKLaunchOptionsDirectionsModeDriving, MKLaunchOptionsDirectionsModeKey, nil]];
} else {
//Fall back on google
...
}

CLLocationManager return null for locality in Xcode

I am trying get current location name using coreloaction framework in Xcode through CLlocationManager object. When i am testing my app on my iPod touch CLlocationManager give value for some places but return [null] for many places. how can I rectify this problem? help me following is coding.
-(void)viewDidLoad
{
self.locationManager = [[CLLocationManager alloc] init] ;
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
[self.locationManager startUpdatingLocation];
}
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
CLGeocoder *geoCoder = [[CLGeocoder alloc]init];
[geoCoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error)
{
if(error)
{
NSLog(#"error:%#",[error localizedDescription ]);
NSLog(#"Check your inetconnection");
}
_placedetail=nil;
self.placedetail=[placemarks objectAtIndex:0];
self.Label.text=self.placedetail.locality;
}];
[manager stopUpdatingLocation];//for stop process update
}
This question is long time ago. but ill add my solution here for future reference.
I had the same problem. i think its happening due to maps are not updated yet in for some small cities. or locality conflict. to avoid this crash try error handling with giving sub locality.
Example : if locality not available go with administrative area like bigger option.