In a swift project I was able to do this easily. I have an array of CLLocationCoordinate2D's and CLLocationDistances
Here is the swift code (inside a PFQuery) It works just fine
if let returnedLocation = object["location"] as? PFGeoPoint
{
let requestLocation = CLLocationCoordinate2DMake(returnedLocation.latitude, returnedLocation.longitude)
self.locations.append(requestLocation)
let requestCLLocation = CLLocation(latitude: requestLocation.latitude, longitude: requestLocation.longitude)
let driverCLLocation = CLLocation(latitude: location.latitude, longitude: location.longitude)
let distance = driverCLLocation.distanceFromLocation(requestCLLocation)
self.distances.append(distance/1000)
}
When I try to add them in Objective C to the locations and distance arrays I get an error because I'm adding an object without a pointer. What would be the best way to get around this? Thank you
Objective C code (they're both NSMutableArrays)
if (object[#"driverResponded"] == nil) {
NSString *username = object[#"username"];
[self.usernames addObject:username];
PFGeoPoint *returnedLocation = object[#"location"];
CLLocationCoordinate2D requestLocation = CLLocationCoordinate2DMake(returnedLocation.latitude, returnedLocation.longitude);
//FIX!
[self.locations addObject:requestLocation];
CLLocation *requestCLLocation = [[CLLocation alloc]initWithLatitude:requestLocation.latitude longitude:requestLocation.longitude];
CLLocation *driverCLLocation = [[CLLocation alloc]initWithLatitude:location.latitude longitude:location.longitude];
CLLocationDistance distance = [driverCLLocation distanceFromLocation:requestCLLocation];
[self.distances addObject:distance/1000];
}
You can do this to store it as a CLLocationCoordinate doing this:
CLLocationCoordinate2D new_coordinate = CLLocationCoordinate2DMake(returnedLocation.latitude, returnedLocation.longitude);
[self.locations addObject:[NSValue valueWithMKCoordinate:new_coordinate]];
Pull it back out like this:
CLLocationCoordinate2D coordinate = [[self.locations objectAtIndex:0] MKCoordinateValue];
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 am trying to search in a text file (available on a url) , there is latitude, longitude and other information separated by commas.
I need to search lat lon which is nearest to user's selected lat lon in app.
Code is done to read that file and search but it do not work perfectly.
Please let me know , how should I approach in this type of situation.
1)File get updated in real time , so I need to call url and read file every time user select location and click to get information.
2)And then search for nearest lat lon to the user's selected lat lon.
NSDICTIONARY DATA GETTING :-
(
{
"altitude_m" = "90.0";
engName = “Station 1”;
grkName = "\U039d\U03ad\U03b1 \U039c\U03ac\U03ba\U03c1\U03b7 \U0391\U03c4\U03c4\U03b9\U03ba\U03ae\U03c2";
"humidity_P" = "50.0";
lat = "38.058873";
"local_time" = "16:20";
lon = "23.976741";
"pressure_hPA" = "1019.9";
"rain_mm" = "0.0";
"tem_C" = "17.2";
"wind_Gusts_khm" = "51.5";
"wind_degrees" = "22.5";
"wind_kmh" = "25.7";
}
{
"altitude_m" = "90.0";
engName = “Station 2”;
grkName = "\U039d\U03ad\U03b1 \U039c\U03ac\U03ba\U03c1\U03b7 \U0391\U03c4\U03c4\U03b9\U03ba\U03ae\U03c2";
"humidity_P" = "50.0";
lat = "38.048873";
"local_time" = "16:20";
lon = "23.876741";
"pressure_hPA" = "1019.9";
"rain_mm" = "0.0";
"tem_C" = "17.2";
"wind_Gusts_khm" = "51.5";
"wind_degrees" = "22.5";
"wind_kmh" = "25.7";
}
{
"altitude_m" = "90.0";
engName = “Station 3”;
grkName = "\U039d\U03ad\U03b1 \U039c\U03ac\U03ba\U03c1\U03b7 \U0391\U03c4\U03c4\U03b9\U03ba\U03ae\U03c2";
"humidity_P" = "50.0";
lat = "38.059873";
"local_time" = "16:20";
lon = "23.986741";
"pressure_hPA" = "1019.9";
"rain_mm" = "0.0";
"tem_C" = "17.2";
"wind_Gusts_khm" = "51.5";
"wind_degrees" = "22.5";
"wind_kmh" = "25.7";
}
// MATCHING FUNCTION :-
-(void)matchLAtLongNow: (NSString *)latitude :(NSString *)longitude {
CLLocationCoordinate2D pinlocation;
pinlocation.latitude = [latitude doubleValue];
pinlocation.longitude = [longitude doubleValue];
float minLat = pinlocation.latitude - (searchDistance / 69);
float maxLat = pinlocation.latitude + (searchDistance / 69);
float minLon = pinlocation.longitude - searchDistance / fabs(cos(deg2rad(pinlocation.latitude))*69);
float maxLon = pinlocation.longitude + searchDistance / fabs(cos(deg2rad(pinlocation.longitude))*69);
NSPredicate *predicate = [NSPredicate predicateWithFormat:
#"lat <= %f AND lat >= %f AND lon <= %f AND lon >= %f",
maxLat, minLat, maxLon, minLon];
MatchedTxtArray = [myArray filteredArrayUsingPredicate:applePred];
}
//GETTING ERROR
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber _fastCStringContents]: unrecognized selector sent to instance 0x175426460'
* First throw call stack:
NSDictionaries return NSNumbers. Check where you call matchAtLongNow: You probably have NSNumbers where you're expecting strings.
It sounds like you need a geo search, as opposed inclusion within some thresholds. I'd reformulate to something like this:
NSArray *objects; // this is your parsed file, an array of dictionaries
CLLocation *userLocation; // this is your user location
// sort the dictionary in order of distance to the userLocation
NSArray *sortedObjects = [objects sortedArrayUsingComparator:^(NSDictionary *objA,NSDictionary *objB) {
CLLocationDistance distanceA = [self distanceToObject:objA from:userLocation];
CLLocationDistance distanceB = [self distanceToObject:objB from:userLocation];
return (NSComparisonResult)(distanceB-distanceA);
}];
sortedObjects will contain the dictionaries sorted from nearest to farthest from the userLocation We just need a function that produces the distance from the lat/lon values in the dictionary to the userLocation...
- (CLLocationDistance)distanceToObject:(NSDictionary *)object from:(CLLocation *)location {
CLLocationDegrees latitude = [object[#"lat"] doubleValue];
CLLocationDegrees longitude = [object[#"lob"] doubleValue];
CLLocation *objectLocation = [[CLLocation alloc] initWithLatitude:latitude longitude:longitude];
return [objectLocation distanceFromLocation:location];
}
i am working on a project in which i have to show the distance of multiple locations from user's locations. locations are based on latitude and longitude.
i am using the following code to get the distance between two locations is shows nearly same distance
CLLocation *locA = [[CLLocation alloc] initWithLatitude:28.6379 longitude: 77.2432];
CLLocation *locB = [[CLLocation alloc] initWithLatitude:28.6562 longitude:77.2410];
CLLocationDistance distance = [locA distanceFromLocation:locB];
NSLog(#"Distance is %f",distance);
float i = distance/1000;
NSLog(#"distance between two places is %f KM", i);
but now i am struct to get the distance of multiple locations from my location: locaA.
for example i take NSarray for latitude and longitude as
NSArray * latArray = [[NSArray alloc]initWithObjects:#"28.6129",#"28.6020",#"28.5244", nil];
NSArray * longArray = [[NSArray alloc]initWithObjects:#"77.2295",#"77.2478",#"77.1855", nil];
Please help me to resolve it
Take locaA as user's location
You can use below method to find distance
#define DEG2RAD(degrees) (degrees * 0.01745327)
double currentLatitudeRad = DEG2RAD(currentLatitude);
double currentLongitudeRad = DEG2RAD(currentLongitude);
double destinationLatitudeRad = DEG2RAD(destinationLatitude);
double destinationLongitudeRad = DEG2RAD(destinationLongitude);
double distance = acos(sin(currentLatitudeRad) * sin(destinationLatitudeRad) + cos(currentLatitudeRad) * cos(destinationLatitudeRad) * cos(currentLongitudeRad - destinationLongitudeRad)) * 6880.1295896;
Here, currentLatitude and currentLongitude is user's location. destinationLatitude and destinationLongitude is each object from your array "latArray" and "longArray" which you can iterate via for loop. distance is the distance between user's location and locations in array. Obtained distance will be in kilometres.
CLLocation *currentLocation = ... // This is a reference to your current location as a CLLocation
NSArray *arrayOfOtherCLLocationObjects = ... // This is an array that contains all of the other points you want to calculate the distance to as CLLocations
NSMutableArray *distancesFromCurrentLocation = [[NSMutableArray alloc] initWithCapacity:arrayOfOtherCLLocationObjects.count]; // We will add all of the calculated distances to this array
for (CLLocation *location in arrayOfOtherCLLocationObjects) // Iterate through each location object
{
CLLocationDistance distance = [location distanceFromLocation:currentLocation]; // Calculate distance
[distancesFromCurrentLocation addObject:#(distance)]; // Append distance to array. You need to wrap the distance object as an NSNumber so you can append it to the array.
}
// At this point, you have the distance for each location point in the array distancesFromCurrentLocation
Swift version:
let currentLocation: CLLocation = //current location
let otherLocations: [CLLocation] = //the locations you want to know their distance to currentLocation
let distances = otherLocations.map { $0.distanceFromLocation(currentLocation) }
I have an app that uses MKMapView. In my app, I have declared an array that will hold the response from the API. The data from the API are the jobs to be pinned in the map (clustered annotations). The array that holds the jobs from the API will/needs to be filtered by the jobs pins that are visible in the map. I am able to filter the coordinates (visible or not visible in the map) but I am having troubles on storing the data (coordinates that are visible) in a new array.
Here's what I have so far:
In regionDidChangeAnimated in my mapview
[ar objectAtIndex:0];
NSMutableDictionary *visibleJobs;
for(NSDictionary *loc in ar)
{
CLLocationDegrees Lat = [[[loc objectForKey:#"sub_slots"] objectForKey:#"latitude"] doubleValue];
CLLocationDegrees longTitude = [[[loc objectForKey:#"sub_slots"] objectForKey:#"longitude"] doubleValue];
CLLocationCoordinate2D point = CLLocationCoordinate2DMake(Lat, longTitude);
MKMapPoint mkPoint = MKMapPointForCoordinate(point);
BOOL contains = MKMapRectContainsPoint(mapView.visibleMapRect, mkPoint);
if(contains)
{
NSLog(#"Contains:1");
}
else
{
NSLog(#"Contains:0");
}
}
Any help will be very much appreciated.
Thanks!
why don't you use NSMutableArray
try this
NSMutableArray *visibleJobs = [[NSMutableArray alloc]init];
for(NSDictionary *loc in ar)
{
CLLocationDegrees Lat = [[[loc objectForKey:#"sub_slots"] objectForKey:#"latitude"] doubleValue];
CLLocationDegrees longTitude = [[[loc objectForKey:#"sub_slots"] objectForKey:#"longitude"] doubleValue];
CLLocationCoordinate2D point = CLLocationCoordinate2DMake(Lat, longTitude);
MKMapPoint mkPoint = MKMapPointForCoordinate(point);
BOOL contains = MKMapRectContainsPoint(mapView.visibleMapRect, mkPoint);
if(contains)
{
NSLog(#"Contains:1");
[visibleJobs addObject:loc];
}
else
{
NSLog(#"Contains:0");
}
}
Now visible jobs array contains dictionary of all pin data which in currently visible on map
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 ?