我确信我可以根据我过去在 PHP 中实现的代码来解决这个问题,但我希望有人已经做到了这一点并且可以提供一个示例或知道使用 iOS SDK 完成的方法它。
这是我的相关代码:
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
CLLocationDistance dist = _searchDistance;
CLLocationCoordinate2D point = self.locationManager.location.coordinate;
CLRegion *region = [[CLRegion alloc] initCircularRegionWithCenter:point radius:dist identifier:@"Hint Region"];
[geocoder geocodeAddressString:address inRegion:region completionHandler:^(NSArray *placemarks, NSError *error)
{
if( error )
{
// Push errors to the user
}
else
{
NSLog( [NSString stringWithFormat:@"Got results: %@", placemarks] );
}
}];
这会推送到日志中,如下所示:
(
"300 Oak St, Phoenix, OR 97535-5722, United States @ <+42.26953820,-122.81554259> +/- 100.00m, region (identifier <+42.26953820,-122.81554106> radius 27.00) <+42.26953820,-122.81554106> radius 27.00m",
"300 Oak St, Ashland, OR 97520, United States @ <+42.19955633,-122.71289484> +/- 100.00m, region (identifier <+42.19955633,-122.71289484> radius 138.42) <+42.19955633,-122.71289484> radius 138.42m",
"300 Oak St, Jacksonville, OR 97530, United States @ <+42.31236366,-122.97179130> +/- 100.00m, region (identifier <+42.31236366,-122.97179130> radius 138.33) <+42.31236366,-122.97179130> radius 138.33m",
"300 Oak St, Central Point, OR 97502, United States @ <+42.37422514,-122.91427182> +/- 100.00m, region (identifier <+42.37422514,-122.91427182> radius 138.29) <+42.37422514,-122.91427182> radius 138.29m",
"300 Oak St, Rogue River, OR 97537, United States @ <+42.43621216,-123.16864522> +/- 100.00m, region (identifier <+42.43621216,-123.16864522> radius 138.24) <+42.43621216,-123.16864522> radius 138.24m"
)
在这种情况下,第二个结果是最接近我当前位置的结果。我希望此列表按最接近我当前位置的匹配项排序。我有理由相信我知道如何进行数学计算以找出最近的位置,但我希望有一条捷径。遍历这个数组并对结果进行排序会有些繁重,所以如果可能的话,我想避免这种情况。
编辑(完整答案):
@Akash gave me the bit of information I was seeking, so I marked that answer as the correct one. If anyone is interested in sorting the results (rather than just getting the closest location), I put the unsorted results into an NSDictionary
using the distance as a key, then used compare
to sort the keys and then put the original placemark
array elements into an output array ordered by the key to which they were associated in the NSDictionary
. Here's the complete code (and the complete answer to my question):
-(NSMutableArray *)distanceSortPlacemarks:(NSArray *)inputArray fromLocation:(CLLocation *)originLocation
{
NSMutableArray *returnValue = [[NSMutableArray alloc] initWithCapacity:[inputArray count]];
NSMutableDictionary *sortDictionary = [[NSMutableDictionary alloc] initWithCapacity:[inputArray count]];
for( int i = 0; i < [inputArray count]; i++ )
{
CLPlacemark *currentPlacemark = [inputArray objectAtIndex:i];
[sortDictionary
setObject:currentPlacemark
forKey:[NSNumber numberWithDouble:[currentPlacemark.location distanceFromLocation:originLocation]]
];
}
NSArray *sortedKeys = [[sortDictionary allKeys] sortedArrayUsingSelector:@selector(compare:)];
for( int i = 0; i < [sortedKeys count]; i++ )
{
CLPlacemark *currentPlacemark = [sortDictionary objectForKey:[sortedKeys objectAtIndex:i]];
[returnValue insertObject:currentPlacemark atIndex:i];
}
return returnValue;
}
I know this could be a little tighter (some of the variables aren't absolutely necessary), but I tend to err on the side of making code easier to understand at quick glance.