Calculating MAX and MIN Latitude and Longitude with distance from Location - Objective C
up vote
6
down vote
favorite
I need to compute MAX and MIN Latitude and Longitude values from a location with certain distance.
I have thousands of locations stored in CoreData, and I want to show only the ones within 5km from users location.
How can I approach this problem?
ios objective-c swift macos maps
add a comment |
up vote
6
down vote
favorite
I need to compute MAX and MIN Latitude and Longitude values from a location with certain distance.
I have thousands of locations stored in CoreData, and I want to show only the ones within 5km from users location.
How can I approach this problem?
ios objective-c swift macos maps
add a comment |
up vote
6
down vote
favorite
up vote
6
down vote
favorite
I need to compute MAX and MIN Latitude and Longitude values from a location with certain distance.
I have thousands of locations stored in CoreData, and I want to show only the ones within 5km from users location.
How can I approach this problem?
ios objective-c swift macos maps
I need to compute MAX and MIN Latitude and Longitude values from a location with certain distance.
I have thousands of locations stored in CoreData, and I want to show only the ones within 5km from users location.
How can I approach this problem?
ios objective-c swift macos maps
ios objective-c swift macos maps
edited Apr 20 '16 at 8:36
asked Apr 11 '14 at 14:30
Pancho
3,21911630
3,21911630
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
up vote
8
down vote
accepted
Here's a possible solution:
macros to convert Degrees to Radians
#define deg2rad(degrees) ((degrees) / 180.0 M_PI)
macros to hold my searching distance
#define searchDistance 5.00 //float value in KM
set the minimum and maximum Latitude, Longitude values
float minLat = userLocation.coordinate.latitude - (searchDistance / 69);
float maxLat = userLocation.coordinate.latitude + (searchDistance / 69);
float minLon = userLocation.coordinate.latitude - searchDistance / fabs(cos(deg2rad(userLocation.coordinate.latitude))*69);
float maxLon = userLocation.coordinate.longitude + searchDistance / fabs(cos(deg2rad(userLocation.coordinate.latitude))*69);
create predicate as follows
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"latitude <= %f AND latitude >= %f AND longitude <= %f AND longitude >= %f", maxLat, minLat, maxLon, minLon];
This will create a square around userLocation
and check if a given location falls into its coordinates.
Update: Swift 2.* implementation
First create a function to compute degrees to radians
func deg2rad(degrees:Double) -> Double{
return degrees * M_PI / 180
}
Compute and create minimum and maximum Latitude
and Longitude
values
let searchDistance:Double = 5.00 //float value in KM
let minLat = userLocation.coordinate.latitude - (searchDistance / 69)
let maxLat = userLocation.coordinate.latitude + (searchDistance / 69)
let minLon = userLocation.coordinate.longitude - searchDistance / fabs(cos(deg2rad(userLocation.coordinate.latitude))*69)
let maxLon = userLocation.coordinate.longitude + searchDistance / fabs(cos(deg2rad(userLocation.coordinate.latitude))*69)
Last create NSPredicate
to query CoreData
for locations. In my case I am querying for values latitude
and longitude
but you should change this to match your CoreData
object
let predicate = NSPredicate(format: "latitude <= (maxLat) AND latitude >= (minLat) AND longitude <= (maxLon) AND longitude >= (minLon)")
See the comments above, this is probably an excellent solution for your use case unless it really matters that you only get results that are less than "exactly" 5km.
– David Berry
Apr 11 '14 at 16:44
Thank you for you comment. I simply needed location within approximate distance. I am not relying on exact distance at all, but wanted to filter big database to only few dozens without selecting the entire database.
– Pancho
Apr 14 '14 at 8:14
I think there is a typo, e.g.float minLon = userLocation.coordinate.latitude...
should befloat minLon = userLocation.coordinate.longitude...
, or?
– Sebastian Dressler
Jul 27 '14 at 17:16
This won't work when the 5km radius is crossing the 180th meridian.
– JustSid
Mar 4 '16 at 11:07
I know. I never said it is as accurate asdistanceFromLocation()
the only purpose of this calculation is to build a query and only loop through the returned result instead of selecting the entire database and check each entry, which could be huge overhead if you have thousands of records like in my case.
– Pancho
Mar 4 '16 at 14:04
|
show 1 more comment
up vote
0
down vote
Use the CoreLocation method distanceFromLocation:
which returns the distance (in meters) between two points as such:
CLLocation* location = [[CLLocation alloc] initWithLatitude:lat longitude:lon];
if([userLocation distanceFromLocation:location) < searchDistance)
// do something with close point
A suitable predicate can be constructed as:
NSPredicate* predicate = [NSPredicate predicateWithBlock:(BOOL (^)(NSDictionary* target, NSDictionary *bindings)) {
CLLocation* location = [[CLLocation alloc] initWithLatitude:[target[@"lat"] doubleValue] longitude:[target[@"lon"] doubleValue]];
return [userLocation distanceFromLocation:location] < searchDistance;
}];
This has the advantage that it returns the items actually within range, as opposed to the items in a square approximating the range. It's also (probably, we don't know the details) using a more accurate approximation of the range itself. It has the disadvantage that the predicate requires loading every object since it can't be expressed as an sqlite query.
Would this be more efficient than only selecting lat and lon between minimum and maximum values?
– Pancho
Apr 11 '14 at 16:33
1
No, the math used by distanceFromLocation is more complex (by an order of magnitude) than an optimized version of Panayot's math. If you're using an NSPredicate to fetch data from CoreData, Panayot's method has the added advantage that the predicate will generate an sqlite query so not all items will be loaded.
– David Berry
Apr 11 '14 at 16:35
1
My order of magnitude estimate is based on the belief that distanceFromLocation uses haversine great circle approximation. Panayot's method has the added disadvantage that the assumption that long lines are parallel makes for degrading results with larger radiuses (should be fine for 5 km assuming you're not sitting on or very close to the pole) To get an answer that has both optimal performance and highest accuracy, use a combination of the two. Use Panayot's for a rough filter and then apply distanceFromLocation filtering.
– David Berry
Apr 11 '14 at 16:42
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
8
down vote
accepted
Here's a possible solution:
macros to convert Degrees to Radians
#define deg2rad(degrees) ((degrees) / 180.0 M_PI)
macros to hold my searching distance
#define searchDistance 5.00 //float value in KM
set the minimum and maximum Latitude, Longitude values
float minLat = userLocation.coordinate.latitude - (searchDistance / 69);
float maxLat = userLocation.coordinate.latitude + (searchDistance / 69);
float minLon = userLocation.coordinate.latitude - searchDistance / fabs(cos(deg2rad(userLocation.coordinate.latitude))*69);
float maxLon = userLocation.coordinate.longitude + searchDistance / fabs(cos(deg2rad(userLocation.coordinate.latitude))*69);
create predicate as follows
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"latitude <= %f AND latitude >= %f AND longitude <= %f AND longitude >= %f", maxLat, minLat, maxLon, minLon];
This will create a square around userLocation
and check if a given location falls into its coordinates.
Update: Swift 2.* implementation
First create a function to compute degrees to radians
func deg2rad(degrees:Double) -> Double{
return degrees * M_PI / 180
}
Compute and create minimum and maximum Latitude
and Longitude
values
let searchDistance:Double = 5.00 //float value in KM
let minLat = userLocation.coordinate.latitude - (searchDistance / 69)
let maxLat = userLocation.coordinate.latitude + (searchDistance / 69)
let minLon = userLocation.coordinate.longitude - searchDistance / fabs(cos(deg2rad(userLocation.coordinate.latitude))*69)
let maxLon = userLocation.coordinate.longitude + searchDistance / fabs(cos(deg2rad(userLocation.coordinate.latitude))*69)
Last create NSPredicate
to query CoreData
for locations. In my case I am querying for values latitude
and longitude
but you should change this to match your CoreData
object
let predicate = NSPredicate(format: "latitude <= (maxLat) AND latitude >= (minLat) AND longitude <= (maxLon) AND longitude >= (minLon)")
See the comments above, this is probably an excellent solution for your use case unless it really matters that you only get results that are less than "exactly" 5km.
– David Berry
Apr 11 '14 at 16:44
Thank you for you comment. I simply needed location within approximate distance. I am not relying on exact distance at all, but wanted to filter big database to only few dozens without selecting the entire database.
– Pancho
Apr 14 '14 at 8:14
I think there is a typo, e.g.float minLon = userLocation.coordinate.latitude...
should befloat minLon = userLocation.coordinate.longitude...
, or?
– Sebastian Dressler
Jul 27 '14 at 17:16
This won't work when the 5km radius is crossing the 180th meridian.
– JustSid
Mar 4 '16 at 11:07
I know. I never said it is as accurate asdistanceFromLocation()
the only purpose of this calculation is to build a query and only loop through the returned result instead of selecting the entire database and check each entry, which could be huge overhead if you have thousands of records like in my case.
– Pancho
Mar 4 '16 at 14:04
|
show 1 more comment
up vote
8
down vote
accepted
Here's a possible solution:
macros to convert Degrees to Radians
#define deg2rad(degrees) ((degrees) / 180.0 M_PI)
macros to hold my searching distance
#define searchDistance 5.00 //float value in KM
set the minimum and maximum Latitude, Longitude values
float minLat = userLocation.coordinate.latitude - (searchDistance / 69);
float maxLat = userLocation.coordinate.latitude + (searchDistance / 69);
float minLon = userLocation.coordinate.latitude - searchDistance / fabs(cos(deg2rad(userLocation.coordinate.latitude))*69);
float maxLon = userLocation.coordinate.longitude + searchDistance / fabs(cos(deg2rad(userLocation.coordinate.latitude))*69);
create predicate as follows
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"latitude <= %f AND latitude >= %f AND longitude <= %f AND longitude >= %f", maxLat, minLat, maxLon, minLon];
This will create a square around userLocation
and check if a given location falls into its coordinates.
Update: Swift 2.* implementation
First create a function to compute degrees to radians
func deg2rad(degrees:Double) -> Double{
return degrees * M_PI / 180
}
Compute and create minimum and maximum Latitude
and Longitude
values
let searchDistance:Double = 5.00 //float value in KM
let minLat = userLocation.coordinate.latitude - (searchDistance / 69)
let maxLat = userLocation.coordinate.latitude + (searchDistance / 69)
let minLon = userLocation.coordinate.longitude - searchDistance / fabs(cos(deg2rad(userLocation.coordinate.latitude))*69)
let maxLon = userLocation.coordinate.longitude + searchDistance / fabs(cos(deg2rad(userLocation.coordinate.latitude))*69)
Last create NSPredicate
to query CoreData
for locations. In my case I am querying for values latitude
and longitude
but you should change this to match your CoreData
object
let predicate = NSPredicate(format: "latitude <= (maxLat) AND latitude >= (minLat) AND longitude <= (maxLon) AND longitude >= (minLon)")
See the comments above, this is probably an excellent solution for your use case unless it really matters that you only get results that are less than "exactly" 5km.
– David Berry
Apr 11 '14 at 16:44
Thank you for you comment. I simply needed location within approximate distance. I am not relying on exact distance at all, but wanted to filter big database to only few dozens without selecting the entire database.
– Pancho
Apr 14 '14 at 8:14
I think there is a typo, e.g.float minLon = userLocation.coordinate.latitude...
should befloat minLon = userLocation.coordinate.longitude...
, or?
– Sebastian Dressler
Jul 27 '14 at 17:16
This won't work when the 5km radius is crossing the 180th meridian.
– JustSid
Mar 4 '16 at 11:07
I know. I never said it is as accurate asdistanceFromLocation()
the only purpose of this calculation is to build a query and only loop through the returned result instead of selecting the entire database and check each entry, which could be huge overhead if you have thousands of records like in my case.
– Pancho
Mar 4 '16 at 14:04
|
show 1 more comment
up vote
8
down vote
accepted
up vote
8
down vote
accepted
Here's a possible solution:
macros to convert Degrees to Radians
#define deg2rad(degrees) ((degrees) / 180.0 M_PI)
macros to hold my searching distance
#define searchDistance 5.00 //float value in KM
set the minimum and maximum Latitude, Longitude values
float minLat = userLocation.coordinate.latitude - (searchDistance / 69);
float maxLat = userLocation.coordinate.latitude + (searchDistance / 69);
float minLon = userLocation.coordinate.latitude - searchDistance / fabs(cos(deg2rad(userLocation.coordinate.latitude))*69);
float maxLon = userLocation.coordinate.longitude + searchDistance / fabs(cos(deg2rad(userLocation.coordinate.latitude))*69);
create predicate as follows
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"latitude <= %f AND latitude >= %f AND longitude <= %f AND longitude >= %f", maxLat, minLat, maxLon, minLon];
This will create a square around userLocation
and check if a given location falls into its coordinates.
Update: Swift 2.* implementation
First create a function to compute degrees to radians
func deg2rad(degrees:Double) -> Double{
return degrees * M_PI / 180
}
Compute and create minimum and maximum Latitude
and Longitude
values
let searchDistance:Double = 5.00 //float value in KM
let minLat = userLocation.coordinate.latitude - (searchDistance / 69)
let maxLat = userLocation.coordinate.latitude + (searchDistance / 69)
let minLon = userLocation.coordinate.longitude - searchDistance / fabs(cos(deg2rad(userLocation.coordinate.latitude))*69)
let maxLon = userLocation.coordinate.longitude + searchDistance / fabs(cos(deg2rad(userLocation.coordinate.latitude))*69)
Last create NSPredicate
to query CoreData
for locations. In my case I am querying for values latitude
and longitude
but you should change this to match your CoreData
object
let predicate = NSPredicate(format: "latitude <= (maxLat) AND latitude >= (minLat) AND longitude <= (maxLon) AND longitude >= (minLon)")
Here's a possible solution:
macros to convert Degrees to Radians
#define deg2rad(degrees) ((degrees) / 180.0 M_PI)
macros to hold my searching distance
#define searchDistance 5.00 //float value in KM
set the minimum and maximum Latitude, Longitude values
float minLat = userLocation.coordinate.latitude - (searchDistance / 69);
float maxLat = userLocation.coordinate.latitude + (searchDistance / 69);
float minLon = userLocation.coordinate.latitude - searchDistance / fabs(cos(deg2rad(userLocation.coordinate.latitude))*69);
float maxLon = userLocation.coordinate.longitude + searchDistance / fabs(cos(deg2rad(userLocation.coordinate.latitude))*69);
create predicate as follows
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"latitude <= %f AND latitude >= %f AND longitude <= %f AND longitude >= %f", maxLat, minLat, maxLon, minLon];
This will create a square around userLocation
and check if a given location falls into its coordinates.
Update: Swift 2.* implementation
First create a function to compute degrees to radians
func deg2rad(degrees:Double) -> Double{
return degrees * M_PI / 180
}
Compute and create minimum and maximum Latitude
and Longitude
values
let searchDistance:Double = 5.00 //float value in KM
let minLat = userLocation.coordinate.latitude - (searchDistance / 69)
let maxLat = userLocation.coordinate.latitude + (searchDistance / 69)
let minLon = userLocation.coordinate.longitude - searchDistance / fabs(cos(deg2rad(userLocation.coordinate.latitude))*69)
let maxLon = userLocation.coordinate.longitude + searchDistance / fabs(cos(deg2rad(userLocation.coordinate.latitude))*69)
Last create NSPredicate
to query CoreData
for locations. In my case I am querying for values latitude
and longitude
but you should change this to match your CoreData
object
let predicate = NSPredicate(format: "latitude <= (maxLat) AND latitude >= (minLat) AND longitude <= (maxLon) AND longitude >= (minLon)")
edited Mar 4 '16 at 10:58
answered Apr 11 '14 at 14:40
Pancho
3,21911630
3,21911630
See the comments above, this is probably an excellent solution for your use case unless it really matters that you only get results that are less than "exactly" 5km.
– David Berry
Apr 11 '14 at 16:44
Thank you for you comment. I simply needed location within approximate distance. I am not relying on exact distance at all, but wanted to filter big database to only few dozens without selecting the entire database.
– Pancho
Apr 14 '14 at 8:14
I think there is a typo, e.g.float minLon = userLocation.coordinate.latitude...
should befloat minLon = userLocation.coordinate.longitude...
, or?
– Sebastian Dressler
Jul 27 '14 at 17:16
This won't work when the 5km radius is crossing the 180th meridian.
– JustSid
Mar 4 '16 at 11:07
I know. I never said it is as accurate asdistanceFromLocation()
the only purpose of this calculation is to build a query and only loop through the returned result instead of selecting the entire database and check each entry, which could be huge overhead if you have thousands of records like in my case.
– Pancho
Mar 4 '16 at 14:04
|
show 1 more comment
See the comments above, this is probably an excellent solution for your use case unless it really matters that you only get results that are less than "exactly" 5km.
– David Berry
Apr 11 '14 at 16:44
Thank you for you comment. I simply needed location within approximate distance. I am not relying on exact distance at all, but wanted to filter big database to only few dozens without selecting the entire database.
– Pancho
Apr 14 '14 at 8:14
I think there is a typo, e.g.float minLon = userLocation.coordinate.latitude...
should befloat minLon = userLocation.coordinate.longitude...
, or?
– Sebastian Dressler
Jul 27 '14 at 17:16
This won't work when the 5km radius is crossing the 180th meridian.
– JustSid
Mar 4 '16 at 11:07
I know. I never said it is as accurate asdistanceFromLocation()
the only purpose of this calculation is to build a query and only loop through the returned result instead of selecting the entire database and check each entry, which could be huge overhead if you have thousands of records like in my case.
– Pancho
Mar 4 '16 at 14:04
See the comments above, this is probably an excellent solution for your use case unless it really matters that you only get results that are less than "exactly" 5km.
– David Berry
Apr 11 '14 at 16:44
See the comments above, this is probably an excellent solution for your use case unless it really matters that you only get results that are less than "exactly" 5km.
– David Berry
Apr 11 '14 at 16:44
Thank you for you comment. I simply needed location within approximate distance. I am not relying on exact distance at all, but wanted to filter big database to only few dozens without selecting the entire database.
– Pancho
Apr 14 '14 at 8:14
Thank you for you comment. I simply needed location within approximate distance. I am not relying on exact distance at all, but wanted to filter big database to only few dozens without selecting the entire database.
– Pancho
Apr 14 '14 at 8:14
I think there is a typo, e.g.
float minLon = userLocation.coordinate.latitude...
should be float minLon = userLocation.coordinate.longitude...
, or?– Sebastian Dressler
Jul 27 '14 at 17:16
I think there is a typo, e.g.
float minLon = userLocation.coordinate.latitude...
should be float minLon = userLocation.coordinate.longitude...
, or?– Sebastian Dressler
Jul 27 '14 at 17:16
This won't work when the 5km radius is crossing the 180th meridian.
– JustSid
Mar 4 '16 at 11:07
This won't work when the 5km radius is crossing the 180th meridian.
– JustSid
Mar 4 '16 at 11:07
I know. I never said it is as accurate as
distanceFromLocation()
the only purpose of this calculation is to build a query and only loop through the returned result instead of selecting the entire database and check each entry, which could be huge overhead if you have thousands of records like in my case.– Pancho
Mar 4 '16 at 14:04
I know. I never said it is as accurate as
distanceFromLocation()
the only purpose of this calculation is to build a query and only loop through the returned result instead of selecting the entire database and check each entry, which could be huge overhead if you have thousands of records like in my case.– Pancho
Mar 4 '16 at 14:04
|
show 1 more comment
up vote
0
down vote
Use the CoreLocation method distanceFromLocation:
which returns the distance (in meters) between two points as such:
CLLocation* location = [[CLLocation alloc] initWithLatitude:lat longitude:lon];
if([userLocation distanceFromLocation:location) < searchDistance)
// do something with close point
A suitable predicate can be constructed as:
NSPredicate* predicate = [NSPredicate predicateWithBlock:(BOOL (^)(NSDictionary* target, NSDictionary *bindings)) {
CLLocation* location = [[CLLocation alloc] initWithLatitude:[target[@"lat"] doubleValue] longitude:[target[@"lon"] doubleValue]];
return [userLocation distanceFromLocation:location] < searchDistance;
}];
This has the advantage that it returns the items actually within range, as opposed to the items in a square approximating the range. It's also (probably, we don't know the details) using a more accurate approximation of the range itself. It has the disadvantage that the predicate requires loading every object since it can't be expressed as an sqlite query.
Would this be more efficient than only selecting lat and lon between minimum and maximum values?
– Pancho
Apr 11 '14 at 16:33
1
No, the math used by distanceFromLocation is more complex (by an order of magnitude) than an optimized version of Panayot's math. If you're using an NSPredicate to fetch data from CoreData, Panayot's method has the added advantage that the predicate will generate an sqlite query so not all items will be loaded.
– David Berry
Apr 11 '14 at 16:35
1
My order of magnitude estimate is based on the belief that distanceFromLocation uses haversine great circle approximation. Panayot's method has the added disadvantage that the assumption that long lines are parallel makes for degrading results with larger radiuses (should be fine for 5 km assuming you're not sitting on or very close to the pole) To get an answer that has both optimal performance and highest accuracy, use a combination of the two. Use Panayot's for a rough filter and then apply distanceFromLocation filtering.
– David Berry
Apr 11 '14 at 16:42
add a comment |
up vote
0
down vote
Use the CoreLocation method distanceFromLocation:
which returns the distance (in meters) between two points as such:
CLLocation* location = [[CLLocation alloc] initWithLatitude:lat longitude:lon];
if([userLocation distanceFromLocation:location) < searchDistance)
// do something with close point
A suitable predicate can be constructed as:
NSPredicate* predicate = [NSPredicate predicateWithBlock:(BOOL (^)(NSDictionary* target, NSDictionary *bindings)) {
CLLocation* location = [[CLLocation alloc] initWithLatitude:[target[@"lat"] doubleValue] longitude:[target[@"lon"] doubleValue]];
return [userLocation distanceFromLocation:location] < searchDistance;
}];
This has the advantage that it returns the items actually within range, as opposed to the items in a square approximating the range. It's also (probably, we don't know the details) using a more accurate approximation of the range itself. It has the disadvantage that the predicate requires loading every object since it can't be expressed as an sqlite query.
Would this be more efficient than only selecting lat and lon between minimum and maximum values?
– Pancho
Apr 11 '14 at 16:33
1
No, the math used by distanceFromLocation is more complex (by an order of magnitude) than an optimized version of Panayot's math. If you're using an NSPredicate to fetch data from CoreData, Panayot's method has the added advantage that the predicate will generate an sqlite query so not all items will be loaded.
– David Berry
Apr 11 '14 at 16:35
1
My order of magnitude estimate is based on the belief that distanceFromLocation uses haversine great circle approximation. Panayot's method has the added disadvantage that the assumption that long lines are parallel makes for degrading results with larger radiuses (should be fine for 5 km assuming you're not sitting on or very close to the pole) To get an answer that has both optimal performance and highest accuracy, use a combination of the two. Use Panayot's for a rough filter and then apply distanceFromLocation filtering.
– David Berry
Apr 11 '14 at 16:42
add a comment |
up vote
0
down vote
up vote
0
down vote
Use the CoreLocation method distanceFromLocation:
which returns the distance (in meters) between two points as such:
CLLocation* location = [[CLLocation alloc] initWithLatitude:lat longitude:lon];
if([userLocation distanceFromLocation:location) < searchDistance)
// do something with close point
A suitable predicate can be constructed as:
NSPredicate* predicate = [NSPredicate predicateWithBlock:(BOOL (^)(NSDictionary* target, NSDictionary *bindings)) {
CLLocation* location = [[CLLocation alloc] initWithLatitude:[target[@"lat"] doubleValue] longitude:[target[@"lon"] doubleValue]];
return [userLocation distanceFromLocation:location] < searchDistance;
}];
This has the advantage that it returns the items actually within range, as opposed to the items in a square approximating the range. It's also (probably, we don't know the details) using a more accurate approximation of the range itself. It has the disadvantage that the predicate requires loading every object since it can't be expressed as an sqlite query.
Use the CoreLocation method distanceFromLocation:
which returns the distance (in meters) between two points as such:
CLLocation* location = [[CLLocation alloc] initWithLatitude:lat longitude:lon];
if([userLocation distanceFromLocation:location) < searchDistance)
// do something with close point
A suitable predicate can be constructed as:
NSPredicate* predicate = [NSPredicate predicateWithBlock:(BOOL (^)(NSDictionary* target, NSDictionary *bindings)) {
CLLocation* location = [[CLLocation alloc] initWithLatitude:[target[@"lat"] doubleValue] longitude:[target[@"lon"] doubleValue]];
return [userLocation distanceFromLocation:location] < searchDistance;
}];
This has the advantage that it returns the items actually within range, as opposed to the items in a square approximating the range. It's also (probably, we don't know the details) using a more accurate approximation of the range itself. It has the disadvantage that the predicate requires loading every object since it can't be expressed as an sqlite query.
answered Apr 11 '14 at 16:29
David Berry
31.2k106881
31.2k106881
Would this be more efficient than only selecting lat and lon between minimum and maximum values?
– Pancho
Apr 11 '14 at 16:33
1
No, the math used by distanceFromLocation is more complex (by an order of magnitude) than an optimized version of Panayot's math. If you're using an NSPredicate to fetch data from CoreData, Panayot's method has the added advantage that the predicate will generate an sqlite query so not all items will be loaded.
– David Berry
Apr 11 '14 at 16:35
1
My order of magnitude estimate is based on the belief that distanceFromLocation uses haversine great circle approximation. Panayot's method has the added disadvantage that the assumption that long lines are parallel makes for degrading results with larger radiuses (should be fine for 5 km assuming you're not sitting on or very close to the pole) To get an answer that has both optimal performance and highest accuracy, use a combination of the two. Use Panayot's for a rough filter and then apply distanceFromLocation filtering.
– David Berry
Apr 11 '14 at 16:42
add a comment |
Would this be more efficient than only selecting lat and lon between minimum and maximum values?
– Pancho
Apr 11 '14 at 16:33
1
No, the math used by distanceFromLocation is more complex (by an order of magnitude) than an optimized version of Panayot's math. If you're using an NSPredicate to fetch data from CoreData, Panayot's method has the added advantage that the predicate will generate an sqlite query so not all items will be loaded.
– David Berry
Apr 11 '14 at 16:35
1
My order of magnitude estimate is based on the belief that distanceFromLocation uses haversine great circle approximation. Panayot's method has the added disadvantage that the assumption that long lines are parallel makes for degrading results with larger radiuses (should be fine for 5 km assuming you're not sitting on or very close to the pole) To get an answer that has both optimal performance and highest accuracy, use a combination of the two. Use Panayot's for a rough filter and then apply distanceFromLocation filtering.
– David Berry
Apr 11 '14 at 16:42
Would this be more efficient than only selecting lat and lon between minimum and maximum values?
– Pancho
Apr 11 '14 at 16:33
Would this be more efficient than only selecting lat and lon between minimum and maximum values?
– Pancho
Apr 11 '14 at 16:33
1
1
No, the math used by distanceFromLocation is more complex (by an order of magnitude) than an optimized version of Panayot's math. If you're using an NSPredicate to fetch data from CoreData, Panayot's method has the added advantage that the predicate will generate an sqlite query so not all items will be loaded.
– David Berry
Apr 11 '14 at 16:35
No, the math used by distanceFromLocation is more complex (by an order of magnitude) than an optimized version of Panayot's math. If you're using an NSPredicate to fetch data from CoreData, Panayot's method has the added advantage that the predicate will generate an sqlite query so not all items will be loaded.
– David Berry
Apr 11 '14 at 16:35
1
1
My order of magnitude estimate is based on the belief that distanceFromLocation uses haversine great circle approximation. Panayot's method has the added disadvantage that the assumption that long lines are parallel makes for degrading results with larger radiuses (should be fine for 5 km assuming you're not sitting on or very close to the pole) To get an answer that has both optimal performance and highest accuracy, use a combination of the two. Use Panayot's for a rough filter and then apply distanceFromLocation filtering.
– David Berry
Apr 11 '14 at 16:42
My order of magnitude estimate is based on the belief that distanceFromLocation uses haversine great circle approximation. Panayot's method has the added disadvantage that the assumption that long lines are parallel makes for degrading results with larger radiuses (should be fine for 5 km assuming you're not sitting on or very close to the pole) To get an answer that has both optimal performance and highest accuracy, use a combination of the two. Use Panayot's for a rough filter and then apply distanceFromLocation filtering.
– David Berry
Apr 11 '14 at 16:42
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f23015484%2fcalculating-max-and-min-latitude-and-longitude-with-distance-from-location-obj%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown