2011-03-07 71 views
1

我有一個MKMapView,我想知道我怎麼能找到最近的5個註釋給用戶,只顯示他們在MKMapView。只加載五個註解MKMapVIew

我的代碼目前是:

- (void)loadFiveAnnotations { 
    NSString *string = [[NSString alloc] initWithContentsOfURL:url]; 
    string = [string stringByReplacingOccurrencesOfString:@"\n" withString:@""]; 
    NSArray *chunks = [string componentsSeparatedByString:@";"]; 
    NSArray *keys = [NSArray arrayWithObjects:@"type", @"name", @"street", @"address1", @"address2", @"town", @"county", @"postcode", @"number", @"coffeeclub", @"latlong", nil]; 
    // max should be a multiple of 12 (number of elements in keys array) 
    NSUInteger max = [chunks count] - ([chunks count] % [keys count]); 
    NSUInteger i = 0; 

    while (i < max) 
    { 
     NSArray *subarray = [chunks subarrayWithRange:NSMakeRange(i, [keys count])]; 
     NSDictionary *dict = [[NSDictionary alloc] initWithObjects:subarray forKeys:keys]; 
     // do something with dict 
     NSArray *latlong = [[dict objectForKey:@"latlong"] componentsSeparatedByString:@","]; 
     NSString *latitude = [[latlong objectAtIndex:0] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 
     NSString *longitude = [[latlong objectAtIndex:1] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 
     CLLocationDegrees lat = [latitude floatValue]; 
     CLLocationDegrees longi = [longitude floatValue]; 
     Annotation *annotation = [[Annotation alloc] initWithCoordinate:CLLocationCoordinate2DMake(lat, longi)]; 
     annotation.title = [dict objectForKey:@"name"]; 
     annotation.subtitle = [NSString stringWithFormat:@"%@, %@, %@",[dict objectForKey:@"street"],[dict objectForKey:@"county"], [dict objectForKey:@"postcode"]]; 
     [mapView addAnnotation:annotation]; 
     [dict release]; 

     i += [keys count]; 
    } 
} 

回答

3

一個很長的答案,當Stephen Poletto發佈幷包含關於如何使用內置方法對數組進行排序的示例代碼時,大部分都是這樣寫的,儘管基本答案是相同的(即,「爲自己選擇最接近的五個,只通過那些」):

您將需要按照距離爲自己排序註釋,並且僅向MKMapView提交最接近的五個註釋。如果您有兩個CLLocations,那麼您可以使用distanceFromLocation:方法(它是getDistanceFrom:在iOS 3.2之前;現在不推薦使用該名稱)獲取它們之間的距離。

因此,舉例來說,假設您的註解類有一個方法「setReferenceLocation:」你傳遞一個CLLocation和吸氣「distanceFromReferenceLocation」返回兩者之間的距離,你可以這樣做:

// create and populate an array containing all potential annotations 
NSMutableArray *allPotentialAnnotations = [NSMutableArray array]; 

for(all potential annotations) 
{ 
    Annotation *annotation = [[Annotation alloc] 
              initWithCoordinate:...whatever...]; 
    [allPotentialAnnotations addObject:annotation]; 
    [annotation release]; 
} 

// set the user's current location as the reference location 
[allPotentialAnnotations 
     makeObjectsPerformSelector:@selector(setReferenceLocation:) 
     withObject:mapView.userLocation.location]; 

// sort the array based on distance from the reference location, by 
// utilising the getter for 'distanceFromReferenceLocation' defined 
// on each annotation (note that the factory method on NSSortDescriptor 
// was introduced in iOS 4.0; use an explicit alloc, init, autorelease 
// if you're aiming earlier) 
NSSortDescriptor *sortDescriptor = 
       [NSSortDescriptor 
        sortDescriptorWithKey:@"distanceFromReferenceLocation" 
        ascending:YES]; 

[allPotentialAnnotations sortUsingDescriptors: 
          [NSArray arrayWithObject:sortDescriptor]]; 

// remove extra annotations if there are more than five 
if([allPotentialAnnotations count] > 5) 
{ 
    [allPotentialAnnotations 
       removeObjectsInRange:NSMakeRange(5, 
          [allPotentialAnnotations count] - 5)]; 
} 

// and, finally, pass on to the MKMapView 
[mapView addAnnotations:allPotentialAnnotations]; 

根據您從哪裏加載,您需要爲註釋創建本地存儲(在內存或磁盤上),並選擇每當用戶移動時最近的五個。您可以在地圖視圖的userLocation屬性中將自己註冊爲CLLocationManager委託或鍵值觀察。如果你有很多潛在的註釋,那麼對它們進行排序會有點浪費,建議你最好使用四叉樹或kd-tree。

+0

'NSRangeMake'應該是'NSMakeRange'。 – jrdioko

2

首先,您需要獲取用戶的當前位置。你可以建立一個CLLocationManager並註冊自己的委託位置更新如下:

locationManager = [[[CLLocationManager alloc] init] autorelease]; 
[locationManager setDelegate:self]; 
[locationManager startUpdatingLocation]; 

設置自己作爲委託後,您會收到以下回調:

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation 

現在,你有用戶的位置(newLocation),您可以找到五個最接近的註釋。 CoreLocation中有一個方便的方法:

- (CLLocationDistance)distanceFromLocation:(const CLLocation *)location 

當您迭代您的註釋時,只需存儲五個最近的位置即可。你可以在你使用的'lat'和'longi'變量中創建一個CLLocation:

- (id)initWithLatitude:(CLLocationDegrees)latitude longitude:(CLLocationDegrees)longitude 

希望這有助於!