How to use iPhone method -(CLLocationDistance)distanceFromLocation:(const CLLocation *)location - iphone

I am a new iPhone developer learning Objective-C, and am trying to dynamically calculate the distances between the users latitude/longitude coordinates, with latitude/longitude coordinates in a SQLite table. I know that we can use CLLocations method:
(CLLocationDistance)distanceFromLocation:(const CLLocation *)location
to do this, but I'm not sure how to use it given the data that I have. How does one use the above method using pairs of latitude/longitude coordinates, considering the above method only deals with location objects of type CLLocation? Can anyone give me a simple example of how to use this method using two pairs of latitude/longitude coordinates?

Just create CLLocation objects from your data:
// Assumption: lat1, lon1 and lat2, lon2 are double values containing the coordinates
CLLocation *firstLocation = [[[CLLocation alloc] initWithLatitude:lat1 longitude:lon1] autorelease];
CLLocation *secondLocation = [[[CLLocation alloc] initWithLatitude:lat2 longitude:lon2] autorelease];
CLLocationDistance distance = [secondLocation distanceFromLocation:firstLocation];

Related

iOS MapKit show nearest annotations within certain distance

Currently i am working on a Location based application for iPhone/iPad . I have several annotations in my MapKit , what i want to do is to track the location of the user and shows the annotations that are within the 3km . Can somebody give me a start ?
Sorry for the delayed response... the question just fell off my radar.
I'm going to suppose that you have a method that returns a set of NSValue-wrapped CLLocationCoordinate2D structs (the basic approach is the same regardless of what your internal data representations are). You can then filter the list using a method something akin to the following (warning: typed in browser):
NSSet *locations = ...;
CLLocation centerLocation = ...; // Reference location for comparison, maybe from CLLocationManager
CLLocationDistance radius = 3000.; // Radius in meters
NSSet *nearbyLocations = [locations objectsPassingTest:^(id obj, BOOL *stop) {
CLLocationCoordinate2D testCoordinate;
[obj getValue:&testCoordinate];
CLLocation *testLocation = [[CLLocation alloc] initWithLatitude:testCoordinate.latitude
longitude:testCoordinate.longitude];
BOOL returnValue = ([centerLocation distanceFromLocation:testLocation] <= radius);
[testLocation release];
return returnValue;
}
];
With the filtered set of coordinates in hand, you can create MKAnnotation instances and add them to the map in the usual manner, as described in Apple's documentation.
If you have many thousands of test locations then I suppose this approach could start to incur performance issues. You would then want to switch your point storage approach to use, e.g., quadtrees, to reduce the number of points that need to be precision-filtered. But don't optimize prematurely!
Hope that helps!

iPhone App: Calculate Distance of path in Google maps

I am developing an iPhone app. here in my App I have included Google maps.I am showing the highlighted path in map.
Now my Question is how to calculate distance between two point as per path as Apple"s native map App is showing routes with distance.
Thanks in Advance.
CLLocation *loc1 = [[CLLocation alloc] initWithLatitude:oldLocation.coordinate.latitude longitude:oldLocation.coordinate.longitude];
CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:newLocation.coordinate.latitude longitude:newLocation.coordinate.latitude];
CLLocationDistance distance = ([loc2 distanceFromLocation:loc1]) * 0.000621371192;
This may help you.
When running in the simulator, Core Location assigns a fixed set of coordinate values to this property. You must run your application on an iOS-based device to get real location values.
CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:newLocation.coordinate.latitude longitude:newLocation.coordinate.latitude];

read latitude and longitude from sqlite iphone

I have been struggling with this for long. I read many resources but still not able to find a clear way around it.
I have a Sqlite table with rows of latitudes and longitudes. My task is to fetch those latitudes and longitudes and put them in an array and then use later for displaying on map with all the pins. I do these "reading from database" in my AppDelegate (is this advisable or is it better to do in view controller which has the map?)
I fetch the lat and long as double values as shown below
while (sqlite3_step(selectStmt)==SQLITE_ROW){
double latitude= sqlite3_column_double(selectStmt, 1);
double longitude= sqlite3_column_double(selectStmt, 2);
CLLocationCoordinate2D coord=CLLocationCoordinate2DMake(latitude,longitude);
// I want to add this to an array, so that i can use later for annotations
}
However when i try to add "Incompatible type for argument 1 off addObject".
Is this the right way of fetching multiple coordinates from sqlite to display on maps?
Help would be appreciated
You need to use CLLocation class to store your location data.
http://developer.apple.com/library/ios/#DOCUMENTATION/CoreLocation/Reference/CLLocation_Class/CLLocation/CLLocation.html#//apple_ref/doc/uid/TP40007126
CLLocation *location = [[CLLocation alloc] initWithLatitude:latitude longitude:longitude];
[array addObject:location];
[location release];
CLLocationCoordinate2D is a struct not an object and you need objects for addObject methods.
You can use the CLLocation as Evgeniy suggest or create your own object to store/retrieve those values.

CLLocation distanceFromLocation

I am using CLLocation to work out the distance from the current user location, and an annotation. However I just wanted to know if this would be correct. I am currently using iPhone Simulator for this and according to the MKMapView the iPhone Simulator is situated here:
Lat: 0 Long: -1067024384
The annotation's position is:
workingCoordinate.latitude = 40.763856;
workingCoordinate.longitude = -73.973034;
However if you take a look in google maps you will find out how close these distances are, yet so far apart according to CLLocation. I am using the following code to determine the distance between them both.
CLLocation *loc = [[CLLocation alloc] initWithLatitude:annotation.coordinate.latitude longitude:annotation.coordinate.longitude];
CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:self.mapView.userLocation.coordinate.latitude longitude:self.mapView.userLocation.coordinate.longitude];
CLLocationDistance dist = [loc distanceFromLocation:loc2];
int distance = dist
NSLog(#"%i", distance);
The distance being NSLogged is 12769908. I believe that this is incorrect, and therefore there must be a problem with my code.
If there is please can you point it out!
You have two bad habits.
You should not depend on simulator in situations need hardware censor status. Especially when you want correct test.
You're handling types incorrectly. So you can't check values correctly. How is the longitude -1067024384? Longitude value is degrees. This means it's valid range is limited -90.0 ~ +90.0 by definition of longitude.
Your longitude value is out of range. This means one of these. You printed the value wrongly or the real value was wrong. Simulator can print wrong value. Or you printed the value with wrong method. You have to try:
Test on real device which has real hardware censors.
If bad result continues after that,
Review ALL of your application code.
Especially for printing, handling values. Check you're using correct types and castings in > each situations. Because you may did buggy operation in somewhere habitually.
And also, I recommend checking all of intermediate values like this.
CLLocationCoordinate2D annocoord = annotation.coordinate;
CLLocationCoordinate2D usercoord = self.mapView.userLocation.coordinate;
NSLog(#"ANNO = %f, %f", annocoord.latitude, annocoord.longitude);
NSLog(#"USER = %f, %f", usercoord.latitude, usercoord.longitude);
CLLocation *loc = [[CLLocation alloc] initWithLatitude:annotation.coordinate.latitude longitude:annotation.coordinate.longitude];
CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:self.mapView.userLocation.coordinate.latitude longitude:self.mapView.userLocation.coordinate.longitude];
NSLog(#"LOC = %f, %f", loc.coordinate.latitude, loc.coordinate.longitude);
NSLog(#"LOC2 = %f, %f", loc2.coordinate.latitude, loc2.coordinate.longitude);
CLLocationDistance dist = [loc distanceFromLocation:loc2];
NSLog(#"DIST: %f", dist); // Wrong formatting may show wrong value!
Try #"%f" and don't cast it that way.
In CLLocation.h
typedef double CLLocationDistance;

Determining distance using mapkit

How is a 1000ft or 1/2 mile distance determined with mapkit? Either a radius from some pin or the distance between two pins.
For example, I center the map on pin A. Pins B, C, and D are also on the map at various distances from pin A. B and C are within 1/2 mile from A but D is 1 mile away. I'd like to know that B and C are within 1/2 mile from A. How can I calculate that?
Since you've stated that the two different points are "pins", I'm going to assume you're using MKPinAnnotationView (or some other annotation view). If not, you're going to have to get the location some other way.
If you have pointers to the annotation objects for these locations, then you can easily call -coordinate on them, create CLLocations from these coordinates (using -initWithLatitude:longitude:), and then use the method -getDistanceFrom to retrieve the distance in meters. From there, it's an easy conversion to miles. All told, the code would look something like this:
CLLocationCoordinate2D pointACoordinate = [pointAAnnotation coordinate];
CLLocation *pointALocation = [[CLLocation alloc] initWithLatitude:pointACoordinate.latitude longitude:pointACoordinate.longitude];
CLLocationCoordinate2D pointBCoordinate = [pointBAnnotation coordinate];
CLLocation *pointBLocation = [[CLLocation alloc] initWithLatitude:pointBCoordinate.latitude longitude:pointBCoordinate.longitude];
double distanceMeters = [pointALocation getDistanceFrom:pointBLocation];
double distanceMiles = (distanceMeters / 1609.344);
You'll end up with the distance in miles, and can compare it from there. Hope this helps.
getDistanceFrom is now deprecated so here's an alternative answer for anyone looking to do this.
CLLocationCoordinate2D pointACoordinate = [pointAAnnotation coordinate];
CLLocation *pointALocation = [[CLLocation alloc] initWithLatitude:pointACoordinate.latitude longitude:pointACoordinate.longitude];
CLLocationCoordinate2D pointBCoordinate = [pointBAnnotation coordinate];
CLLocation *pointBLocation = [[CLLocation alloc] initWithLatitude:pointBCoordinate.latitude longitude:pointBCoordinate.longitude];
float distanceMeters = [pointALocation distanceFromLocation:pointBLocation];
float distanceMiles = (distanceMeters / 1609.344);
[pointALocation release];
[pointBLocation release];
As above, you could use float instead of double and you could cast the results to an int if you don't require the precision of the float like so:
int distanceCastToInt = (int) [pointALocation distanceFromLocation:pointBLocation];
The int is handy if you wanted to give a rough idea of distance in the annotation like so:
pointAAnnotation.title = #"Point A";
pointAAnnotation.subtitle = [NSString stringWithFormat: #"Distance: %im",distanceCastToInt];
The subtitle of the annotation would read "Distance: 50m" for example.
This is Swift 3 equivalent of the given answer:
let pointACoordinate = pointAAnnotation.coordinate
let pointALocation = CLLocation(latitude: pointACoordinate.latitude, longitude: pointACoordinate.longitude)
let pointBCoordinate = pointBAnnotation.coordinate
let pointBLocation = CLLocation(latitude: pointBCoordinate.latitude, longitude: pointBCoordinate.longitude)
let distanceMeters = pointALocation.distance(from: pointBLocation)
let distanceMiles = (distanceMeters / 1609.344)