Checking Proximity of two Locations in IOS - ios

I have an array of locations and when I add another I want to be able to check if the other locations in the array are within a block of the new one. This is the Code I have to find the current location:
//Geocoding Block
[self.geoCoder reverseGeocodeLocation: locationManager.location completionHandler:
^(NSArray *placemarks, NSError *error) {
//Get nearby address
CLPlacemark *placemark = [placemarks objectAtIndex:0];
//String to hold address
locatedAt = [[placemark.addressDictionary valueForKey:#"FormattedAddressLines"] componentsJoinedByString:#", "];
The array has yet to be created because I want to figure this out first, I dont know what should be held in the array (string...). I know how to do a search I just need to know how to compare the locations.

You can get the distance between two locations using the distanceFromLocation: method on CLLocation. (You can get a CLLocation out of a CLPlacemark with myPlacemark.location.) So if you have an array of CLLocation objects, and you want to find the ones that are within one block (1/20 mile, or about 80 meters), you can do this:
NSMutableArray *locationsWithinOneBlock = [NSMutableArray new];
for (CLLocation *location in myLocations) {
if ([location distanceFromLocation:targetLocation] <= 80.0)
[locationsWithinOneBlock addObject:location];
}
This assumes you have an array myLocations of CLLocation objects that you want to filter against a single CLLocation called targetLocation.

Related

convert NSArray to MKPlacemark

I have a forward geocode block. like this:
[_geoCoder geocodeAddressString:searchString completionHandler:^(NSArray *placemarks, NSError *error) {....}];
As is, the geocode data stores in the NSArray * placemarks. Now I would like to do some annotation to the map, The addAnnotation method requires a MKPlacemark, so how do I convert the place mark in NSArrayinto a MKPlacemark? Thanks.
Here's what you want to do: Iterate through the parameters array - meaning, fetch each item from the array. As we're fetching the items, we want to create MKPlacemark objects using the data the items contain.
The Objective-C language gives us a special tool that allows us to iterate through the array - the "forin" loop:
for (CLPlacemark *placemark in placemarks)
{
// insert code here
}
Now, we want to create an MKPlacemark object from "placemark": (Note: An MKPlacemark object is a CLPlacemark object)
MKPlacemark *mkPlacemark = [MKPlacemark initWithCoordinate:(CLLocationCoordinate2D)coordinate
addressDictionary:(NSDictionary<NSString *,id> *)addressDictionary;]

Convert a place String to a CLLocation

I'm having a bug with the convertion of an NSString (which contains a place from a UITextField input) to a CLLocation.
Here is the method supposed to process the convertion:
- (void)geoCodeForAddress:(NSString *)address {
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:address completionHandler:^(NSArray* placemarks, NSError* error){
dispatch_async(dispatch_get_main_queue(), ^{
CLPlacemark *placeMark = [placemarks lastObject];
if (placeMark.location != nil) {
self.actionLocation = placeMark.location;
} else {
self.actionLocation = nil;
}
if(self.event)
[self.tableView reloadData];
});
}];
}
My problem is, this method returns the wrong location for some specific strings. For instance, whenever I try to use "la patache paris" as an input, it returns a location in the wrong city though when I try the same exact string in Maps, it's finding the right place.
The method geocodeAddressString:completionHandler: is a CoreLocation method from the CLGeocoder class so there is no way I can see what's going on in it.
Would someone have some lead to find out why this is behaving weirdly ?
Thank you.

Sending CLLocationCoordinate2D to parameter of incompatible type my code in Xcode 4.5

I am new to Xcode. I am developing a vehicle tracking app for that I need to display more annotation points simultaneously. For this I need to store the coordinates in the array but it shows the error: Sending CLLocationCoordinate2D to parameter of incompatible type
my code is:
NSString *urlMapString=[NSString stringWithFormat:#"http://logix.com/logix_webservice/mapvehiclelist.php?uid=20&format=json"];
NSURL *urlMap=[NSURL URLWithString:urlMapString];
NSData *dataMap=[NSData dataWithContentsOfURL:urlMap];
if(dataMap!=NULL){
NSError *errorMap;
NSMutableArray *coordinates = [[NSMutableArray alloc]init];
NSDictionary *jsonMap = [NSJSONSerialization JSONObjectWithData:dataMap options:kNilOptions error:&errorMap];
NSArray *resultsMap = [jsonMap valueForKey:#"posts"];
for(int count=1;count<resultsMap.count;count++)
{
NSDictionary *resMap = [[resultsMap objectAtIndex:count]valueForKey:#"post"];
NSString *latOrgstring =[resMap valueForKey:#"latitude"];
latitude=[latOrgstring doubleValue];
NSString *longitudeString=[resMap valueForKey:#"longitude"];
longitude=[longitudeString doubleValue];
//Center
CLLocationCoordinate2D center;
center.latitude=latitude;
center.longitude=longitude;
[coordinates addObject:center]; //here it shows the error
}
}
Kindly advice me to solve this problem.
Thank you...
CLLocationCoordinate2D center isn't an object. You can store only objects in NSArray.
Use CLLocation for this.
CLLocation *location = [[CLLocation alloc] initWithLatitude:lat longitude:lon];
As already mentioned, you can only add objects to an NSArray.
CLLocationCoordinate2D is not an object -- it is a C struct.
The code you posted itself has one solution:
Create a NSDictionary with the latitude and longitude as key/value pairs and add the resulting dictionary object to the array.
Another approach is to create a CLLocation as shown in another answer.
A third idea is what #trojanfoe answered previously which is to wrap the struct in an NSValue.
However, note that there is a convenient NSValue addition specifically for MapKit that adds these two useful helper methods:
valueWithMKCoordinate: which returns an NSValue given a CLLocationCoordinate2D
MKCoordinateValue which returns a CLLocationCoordinate2D for the NSValue
For an example, see How to store CLLocationCoordinate2D?.
A final (at least in this answer) alternate approach which I would highly recommend instead of all the above is this...
Why do you want to store only the coordinates in an array?
Wouldn't you want to know what the coordinates are for (which vehicle, place, etc)?
Why not create a custom class that implements, say, the MKAnnotation protocol and has not only the coordinates (as a CLLocationCoordinate2D property) but also all the other information related to the coordinate? The class would be a subclass of NSObject<MKAnnotation>.
You could then conveniently access all the information in one place without using multiple arrays and trying to keep the objects in the same order so they all have the same index, etc.
You could then directly add these objects to an MKMapView since they implement MKAnnotation.
CLLocationCoordinate2D is a C struct, so you need to put it in NSValue container at first.
An NSValue object is a simple container for a single C or Objective-C
data item. It can hold any of the scalar types such as int, float, and
char, as well as pointers, structures, and object id references. Use
this class to work with such data types in collections (such as
NSArray and NSSet), key-value coding, and other APIs that require
Objective-C objects.
[coordinates addObject:[NSValue value:&coordinate withObjCType:#encode(CLLocationCoordinate2D)]];
Try this
CLLocationCoordinate2D new_coordinate = CLLocationCoordinate2DMake(latitude, longitude);
[points addObject:[NSValue valueWithMKCoordinate:new_coordinate]];
Or
CLLocation *location = [[CLLocation alloc] initWithLatitude:lat longitude:lon];
[coordinates addObject: location];
Can't u directly add coordinates to mapview that means Place MKAnnotation on Mapview, instead of taking coordinates to into array ?
SEE Below i commented with lines
for(int count=1;count<resultsMap.count;count++)
{
NSDictionary *resMap = [[resultsMap objectAtIndex:count]valueForKey:#"post"];
NSString *latOrgstring =[resMap valueForKey:#"latitude"];
latitude=[latOrgstring doubleValue];
NSString *longitudeString=[resMap valueForKey:#"longitude"];
longitude=[longitudeString doubleValue];
//Center
CLLocationCoordinate2D center;
center.latitude=latitude;
center.longitude=longitude;
-----------------------------------------
////// Annotation is MKAnnotation Subclass
Annotation * cartAnn = [Annotation new];
cartAnn.coordinate = center;
[self.mapView addAnnotation: cartAnn];
----------------------------------------------------
/////// [coordinates addObject:center]; //here it shows the error
}

How to get the object with the lowest property value from an NSArray

I have an array of CLLocation objects.
If I use
CLLocation *bestLocation = [locations valueForKeyPath:#"#min.horizontalAccuracy"];
I'm getting the lowest horizontalAccuracy value. But I want the OBJECT that contains the lowest value, so that I can later get it's proper coodinates. How can I do that?
I also tried with
CLLocation *bestLocation = [locations valueForKeyPath:#"#min.self.horizontalAccuracy"];
but got the same results.
Thanks
I don't think there is a simple Key-Value Coding method for that, but you can
loop over the array and keep track of the "best" element:
CLLocation *bestLocation = nil;
for (CLLocation *loc in locations) {
if (bestLocation == nil || loc.horizontalAccuracy < bestLocation.horizontalAccuracy)
bestLocation = loc;
}

How do I make an iOS Map app use closest city as database parameter?

I have an app that fetches all data from the db and plots it on a map. Currently it plots everything in my city. So upon opening, it centers around my device location and plots all locations in the CoreData. But the COreData has locations from various cities.
So currently the app centers around Miami and i can see the Miami locations. If I were to drive to New York, it would center around me of course and plot those locations but it would also plot the Miami ones even though I would not see them on the map.
But if I want the user to be able to select a city he/she IS NOT currently in, and have the map center on THAT point and plot its locations, how do I get from the user selected city (a string) to the actual coordinate?
You can use geocoder
Make an addressDictionary based on these keys -
City, Street, Country , ZIP, State - If you only want city make a dictionary like this
NSDictionary *addressDictionary = [[NSDictionary alloc]initWithObjectsAndKeys:#"Miami",#"City", nil];
add CoreLocation.framework and import #import
use the following code to find the location -
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressDictionary:addressDictionary completionHandler:^(NSArray *placemarks, NSError *error) {
if([placemarks count]) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
CLLocation *location = placemark.location;
CLLocationCoordinate2D coordinate = location.coordinate;
[self.googleMap animateToLocation:coordinate];

Resources