I m working to get the Longitude and Latitude for current place and i m using the code
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;
lat = [NSString stringWithFormat:#"%d° %d' %1.4f\"",
degrees, minutes, seconds];
NSLog(#" Current Latitude : %#",lat);
degrees = newLocation.coordinate.longitude;
decimal = fabs(newLocation.coordinate.longitude - degrees);
minutes = decimal * 60;
seconds = decimal * 3600 - minutes * 60;
// longt = [NSString stringWithFormat:#"%d° %d' %1.4f\"",
// degrees, minutes, seconds];
longt = [NSString stringWithFormat:#"%d° %d' %1.4f\"",
degrees, minutes, seconds];
NSLog(#" Current Longitude : %#",longt);
}
and getting the:
Current Latitude : 37° 47' 9.0024"
Current Longitude : -122° 24' 23.1012"
But i want the Latitude and Longitude like that 13.233233 (mean in points). So how i can convert this in Longitude and Latitude in point ?Please help.
From the following answer Converting from longitude\latitude to Cartesian coordinates
x = R * cos(lat) * cos(lon)
y = R * cos(lat) * sin(lon)
z = R *sin(lat)
Where R is the approximate radius of earth (e.g. 6371KM).
In newLocation.coordinate.latitude and newLocation.coordinate.longitude, you have the values you want, just don't convert them.
why are you using this depreciated method use this method for getting location in iOS 7. Use this method
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
// location_updated = [locations lastObject];
// NSLog(#"updated coordinate are %#",location_updated);
float currentLocationLati = [[locations objectAtIndex:0] coordinate].latitude;
float currentLocationLong = [[locations objectAtIndex:0] coordinate].longitude;
}
By this methods you will find update latitude and longitude just use them don't convert them into degree
Related
I have to calculate the distance between two locations in iOS and objective c. My one location is fixed at a point and when I walk I have to calculate a distance between my current position and the fixed point. I have used distanceFromLocation method but I am not getting the closer distance value. I have gone through a few articles and a few StackOverflow solutions but none gave me proper result.
Below is the code I used and in the code currentLocation and destinationLocation are properties to hold latitude and longitude of the locations. The destinationLocation is always a fixed location and currentLocation keep on changing when I walk. There are few UILabels to print current and fixed latitude and longitude values. I have to calculate the distance every time between these two points. When I move half or less meter it shows me a large distance which is inconsistent as well. Could you please help me what mistake am I doing here? Is there any other way to achieve this? Thanks!
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
CLLocation *newLocation = locations.lastObject;
self.currentLocation = [[CLLocation alloc] initWithLatitude:newLocation.coordinate.latitude longitude:newLocation.coordinate.longitude];
if(self.destinationLocation == nil){
self.destinationLocation = [[CLLocation alloc] initWithLatitude:newLocation.coordinate.latitude longitude:newLocation.coordinate.longitude];
self.destinationLatitude.text = [NSString stringWithFormat:#"%.8f", self.destinationLocation.coordinate.latitude];
self.destinationLongitude.text = [NSString stringWithFormat:#"%.8f", self.destinationLocation.coordinate.longitude];
}
self.currentLatitude.text = [NSString stringWithFormat:#"%.8f", self.currentLocation.coordinate.latitude];
self.currentLongitude.text = [NSString stringWithFormat:#"%.8f", self.currentLocation.coordinate.longitude];
CLLocationDistance distance = [self.currentLocation distanceFromLocation:self.destinationLocation];
self.gpsDistanceMeasurement.text = [NSString stringWithFormat:#"%.2f m", distance];
}
you can use haversine formula to calculate the distance between two points
swift 3.x
let Source = CLLocationCoordinate2D.init(latitude: lat, longitude: long)
let Destination = CLLocationCoordinate2D.init(latitude: lat, longitude: long)
func DistanceCalculator(Source:CLLocationCoordinate2D,Destination:CLLocationCoordinate2D) -> Double
{
// HaverSine Formula to calculate Diastance On Sphere Refrences//https://www.movable-type.co.uk/scripts/latlong.html
// Angle = sin2(∆Ø/2) + cosØ1 * cosØ2 * sin2(∆ø/2)
// constant = 2 * atan2(√angle,√1-angle)
// distance = R * c
let Earth_Radius:Double = 6371 * 1000
let LatDelta = self.DegreeToRad(Degree: (Destination.latitude - Source.latitude))
let LongDelta = self.DegreeToRad(Degree: (Destination.longitude - Source.longitude))
let latRad = self.DegreeToRad(Degree: Source.latitude)
let longRad = self.DegreeToRad(Degree: Destination.latitude)
let Angle = (sin(LatDelta/2) * sin(LatDelta/2)) + (cos(latRad) * cos(longRad) * sin(LongDelta/2) * sin(LongDelta/2))
let constant = 2 * atan2(sqrt(Angle),sqrt(1-Angle))
let Distance = Earth_Radius * constant
return Distance
}
func DegreeToRad(Degree:Double) -> Double
{
return Degree * (Double.pi / 180)
}
I have an array full of longitudes and latitudes. I have two double variables with my users location. I'd like to test the distance between my user's locations against my array to see which location is the closest. How do I do this?
This will get the distance between 2 location but stuggeling to understand
how I'd test it against an array of locations.
CLLocation *startLocation = [[CLLocation alloc] initWithLatitude:userlatitude longitude:userlongitude];
CLLocation *endLocation = [[CLLocation alloc] initWithLatitude:annotation.coordinate.latitude longitude:annotation.coordinate.longitude];
CLLocationDistance distance = [startLocation distanceFromLocation:endLocation];
You just need to iterate through the array checking the distances.
NSArray *locations = //your array of CLLocation objects
CLLocation *currentLocation = //current device Location
CLLocation *closestLocation;
CLLocationDistance smallestDistance = DOUBLE_MAX;
for (CLLocation *location in locations) {
CLLocationDistance distance = [currentLocation distanceFromLocation:location];
if (distance < smallestDistance) {
smallestDistance = distance;
closestLocation = location;
}
}
At the end of the loop you will have the smallest distance and the closest location.
#Fogmeister
I think this is a mistake which must be set right about DBL_MAX and an assignment.
First : Use DBL_MAX instead of DOUBLE_MAX.
DBL_MAX is a #define variable in math.h.
It's the value of maximum representable finite floating-point (double) number.
Second : In your condition, your assignment is wrong :
if (distance < smallestDistance) {
distance = smallestDistance;
closestLocation = location;
}
You must do :
if (distance < smallestDistance) {
smallestDistance = distance;
closestLocation = location;
}
The difference is that will be assign distance value into smallestDistance, and not the opposite.
The final result :
NSArray *locations = //your array of CLLocation objects
CLLocation *currentLocation = //current device Location
CLLocation *closestLocation;
CLLocationDistance smallestDistance = DBL_MAX; // set the max value
for (CLLocation *location in locations) {
CLLocationDistance distance = [currentLocation distanceFromLocation:location];
if (distance < smallestDistance) {
smallestDistance = distance;
closestLocation = location;
}
}
NSLog(#"smallestDistance = %f", smallestDistance);
Can you confirm that is correct ?
I have just completed compass app which will show distance between 2 coordinates.
Here is working code :
....
// created a timer to call locationUpdate method : 5sec
[NSTimer scheduledTimerWithTimeInterval:5 target: self selector: #selector(locationUpdate) userInfo: nil repeats: YES];
....
-(void)locationUpdate {
[locationManager startUpdatingLocation];
}
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLoc
fromLocation:(CLLocation *)oldLoc
{
//To get the current location Latitude & Longitude.
float latitude = locationManager.location.coordinate.latitude;
float longitude = locationManager.location.coordinate.longitude;
startPoint = [[CLLocation alloc] initWithLatitude: latitude longitude: longitude ]; //Current Latitude and Longitude
endPoint = [[CLLocation alloc] initWithLatitude: 12.923670 longitude: 77.573496]; //Target Latitude and Longitude -----------------------------------> Need to come from database.
//To get the distance from the 2 coordinates in feet
CLLocationDistance distInMeter = [startPoint distanceFromLocation:endPoint];
//Lable veiw to update remaining distance.
if(distInMeter > 999.000f) {
self.labelLongLat.text = [NSString stringWithFormat: #"Remainig distance %.2f KM with Lat : %lf LAN %lf", distInMeter / 1000, latitude, longitude ];
}else
self.labelLongLat.text = [NSString stringWithFormat: #"Remainig distance %.2f M Lat : %lf LAN %lf" , distInMeter, latitude,longitude ];
}
My problem is while updating location for each 5sec, the coordinates varies a lot. That will result in Remaining distance calculation. Which is highly unstable!! How can I fix this?
Thanks in Advance,
The delegate method you are using is deprecated. You should use locationManager:didUpdateLocations:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *currentLocation = [locations lastObject];
endPoint = [[CLLocation alloc] initWithLatitude: 12.923670 longitude: 77.573496]; //Target Latitude and Longitude -----------------------------------> Need to come from database.
//To get the distance from the 2 coordinates in meters
CLLocationDistance distInMeter = [currentLocation distanceFromLocation:endPoint];
//Label view to update remaining distance.
if(distInMeter > 999 ) {
self.labelLongLat.text = [NSString stringWithFormat: #"Remaining distance %.2f Km with Lat : %lf LAN %lf", distInMeter / 1000, currentLocation.coordinate.latitude, currentLocation.coordinate.longitude ];
} else {
self.labelLongLat.text = [NSString stringWithFormat: #"Remaining distance %.2f m Lat : %lf LAN %lf" , distInMeter, currentLocation.coordinate.latitude, currentLocation.coordinate.longitude ];
}
}
The accuracy of your location can be affected by signal quality (tall buildings, indoor location etc). You can examine the horizontalAccuracy property of your location to see how accurate the position is. If the accuracy is low then you can defer updating your label. Beware that you may never get an accurate fix.
One strategy is to wait for an accuracy <20m or after 5 updates -
#property (nonatomic) NSInteger locationUpdates;
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
self.locationUpdates++;
CLLocation *currentLocation = [locations lastObject];
if (currentLocation.horizontalAccuracy < 20.0 || self.locationUpdates>5) {
endPoint = [[CLLocation alloc] initWithLatitude: 12.923670 longitude: 77.573496]; //Target Latitude and Longitude -----------------------------------> Need to come from database.
//To get the distance from the 2 coordinates in meters
CLLocationDistance distInMeter = [currentLocation distanceFromLocation:endPoint];
//Label view to update remaining distance.
if(distInMeter > 999 ) {
self.labelLongLat.text = [NSString stringWithFormat: #"Remaining distance %.2f Km with Lat : %lf LAN %lf", distInMeter / 1000, currentLocation.coordinate.latitude, currentLocation.coordinate.longitude ];
} else {
self.labelLongLat.text = [NSString stringWithFormat: #"Remaining distance %.2f m Lat : %lf LAN %lf" , distInMeter, currentLocation.coordinate.latitude, currentLocation.coordinate.longitude ];
}
}
}
In my iOS app I've to track the distance from a a start point to my current location. I implemented this code:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLLocation *currentLocation = [locations lastObject];
CLLocation *startLocation = [locations firstObject];
[coordArray addObject:currentLocation];
float speed = currentLocation.speed * 3.6;
if (speed > 0) {
self.labelSpeed.text = [NSString stringWithFormat:#"%.2f Km/h", speed];
[speedArray addObject:[NSNumber numberWithFloat:speed]];
}
CLLocationDistance distance = [startLocation distanceFromLocation:currentLocation];
}
But when I try to use the app it doesn't get a distance. I need the distance to show it in a label and with distance I will calculate the number of steps by using this equation:
steps = distance / length of human step
I know that it's not accurate, but I can't use accelerometer, because it doesn't work while the display of the iPhone is not active. A person suggested me this solution. Why my code doesn't give me a distance?
The callback
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
does give you at least one location, and locations array hold sonly multiple objects if the location update was deferred before. To get the walking/driving distance, you have to store the initial location in a class variable or property. Then, when you want to calculate a distance, do as in your code above, but with the class variable that holds the initial location.
Check below code for getting distance:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
if ([coordArray count]>0) {
CLLocation *currentLocation = manager.location;
CLLocation *startLocation = [coordArray objectAtIndex:0];
[coordArray addObject:currentLocation];
float speed = currentLocation.speed * 3.6;
if (speed > 0) {
NSLog(#"\n speed:%#",[NSString stringWithFormat:#"%.2f Km/h", speed]);
}
CLLocationDistance distance = [startLocation distanceFromLocation:currentLocation];
if (distance>0) {
NSLog(#"Distance:%#",[NSString stringWithFormat:#"%lf meters",distance]);
}
}
else{
[coordArray addObject:manager.location];
}
}
I need to get the exact current address (country,state,city) of user. So I have gone to find latitude and longitude and then find out from it by using reverse geocoding.But unable to get latitude and longitude itself.I m using xcode 4.1 and testing in iphone simulator.
This is the code I m working on:
- (void)viewDidLoad
{
[super viewDidLoad];
locationManager = [[CLLocationManager alloc] init];
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
[locationManager startUpdatingLocation];
NSLog(#"%#", [self deviceLocation]);
}
- (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;
}
How can I find the latitude and longitude and thereby find the address of the user?
EDIT:
Updated my version to Xcode 4.5. But still couldnot see the location ....?Y is it so?
please download this file
In the zip file I attached, there are 4 files:
LocationGetter.h and .m
PhysicalLocation.h and .m
you need to just import
#import "PhysicalLocation.h"
PhysicalLocation *physicalLocation = [[PhysicalLocation alloc] init];
[physicalLocation getPhysicalLocation];
in getPhysicalLocation at PhysicalLocation.m class
#pragma mark MKReverseGeocoder Delegate Methods
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark
{
NSLog(#"%#",placemark);
objcntrAppDelegate = (yourappDeleger *)[[UIApplication sharedApplication]delegate];
objcntrAppDelegate.strCountry=placemark.country;
objcntrAppDelegate.strSuburb=placemark.subAdministrativeArea;
[[NSNotificationCenter defaultCenter] postNotificationName:#"ReceivedAddress" object:nil userInfo:nil];
[geocoder autorelease];
}
You get all of you neat lat, lng, current city, country, all that you need. Hope it helps you.
NOTE:- simulator gives incorrect result, you must test on device.
UPDATE
UpdatedDEMO
Change :
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
Now latitude and longitude should be obtained as float not int.
CLLocation *location = [locationManager location];
// Configure the new event with information from the location
CLLocationCoordinate2D coordinate = [location coordinate];
float longitude=coordinate.longitude;
float latitude=coordinate.latitude;
Find address of the user by latitude and longitude using CLGeocoder.
EDIT : Refer this link.