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

Posted

技术标签:

【中文标题】按最近位置排序 CLGeoCoder geocodeAddressString 的结果【英文标题】:Order results of CLGeoCoder geocodeAddressString by nearest location 【发布时间】:2013-06-17 16:22:59 【问题描述】:

我确信我可以根据我过去在 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 对键进行排序,然后将原始@将 987654325@ 数组元素放入一个输出数组中,该数组按它们在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】:

尝试在每个CLPlacemark 中获取您当前位置与CLLocation 的距离,如下所示:

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;
        
    

执行此代码后,您在placemarks 数组中拥有最近的CLLocation 的索引,在meters 中拥有与它的距离。

【讨论】:

distanceFromLocation 正是我想要的。谢谢!

以上是关于按最近位置排序 CLGeoCoder geocodeAddressString 的结果的主要内容,如果未能解决你的问题,请参考以下文章

从我当前的位置获取最近的位置

PHAsset CLLocation 未提供与照片应用相同的位置

如何等到 CLGeocoder 完成工作

CLGeoCoder 未按正确顺序附加地标

iOS - 没有互联网连接的 CLGeocoder

CLGeocoder 反向地理编码位置。第一次在 [placemarks count = 0]?