按最近位置对CLGeoCoder geocodeAddressString的结果进行排序

时间:2013-06-17 16:23:00

标签: ios ios6 geolocation geocoding

我确信我可以根据我过去在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给了我一些我正在寻找的信息,所以我把答案标记为正确答案。如果有人有兴趣对结果进行排序(而不是仅仅获取最近的位置),我将未排序的结果放入NSDictionary,使用距离作为键,然后使用compare对键进行排序,然后将原始placemark数组元素放入由NSDictionary中与之关联的键排序的输出数组中。这是完整的代码(以及我的问题的完整答案):

-(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;
}

我知道这可能会有点紧张(有些变量并非绝对必要),但我倾向于在快速浏览时更容易理解代码。

1 个答案:

答案 0 :(得分:2)

尝试从CLLocation CLPlacemark中获取当前位置的距离,如下所示:

for(int i = 0; i < placemarks.count; i++)
{
    double distance = [placemarks[i].location distanceFromLocation:yourCurrentLocation];

    if(i == 0)
    {
        indexOfClosestLocation = i;
        distanceFromClosestLocation = distance;
    }
    else
    {
        if(distance < distanceFromClosestLocation)
        {
            distanceFromClosestLocation = distance;
            indexOfClosestLocation = i;
        }
    }
}

执行此代码后,您在CLLocation数组中的索引最接近placemarks,并在meters中与该距离保持距离。