我有一个MKMapView,我想知道如何找到最接近用户的5个注释,并且只在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];
}
}
答案 0 :(得分:3)
一个很长的答案,主要是在Stephen Poletto发布并包含如何使用内置方法对数组进行排序的示例代码时编写的,所以尽管基本答案是相同的(即, “为自己选择最接近的五个,只通过那些”):
您需要为自己按距离对注释进行排序,并仅向MKMapView提交最接近的五个注释。如果您有两个CLLocations,那么您可以使用distanceFromLocation:方法获取它们之间的距离(这是getDistanceFrom:在iOS 3.2之前;该名称现已弃用)。
因此,例如,假设您的Annotation类有一个方法'setReferenceLocation:',您将CLLocation传递给它,而getter'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树。
答案 1 :(得分: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
希望这有帮助!