仅向MKMapVIew加载五个注释 [英] Load only five annotations to MKMapVIew

查看:54
本文介绍了仅向MKMapVIew加载五个注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个MKMapView,我想知道如何找到最接近用户的5个注释,并且只在MKMapView上显示它们。

I have a MKMapView, and I would like to know how I can find the nearest 5 annotations to the user, and only display them on the MKMapView.

My代码目前是:

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


推荐答案

A很长的答案,已经大部分是在Stephen Poletto发布并包含如何使用内置方法对数组进行排序的示例代码时编写的,所以我虽然仍然值得发帖虽然基本答案是相同的(即选择五个最接近你自己,只传递那些):

A long answer, already mostly written when Stephen Poletto posted and containing example code on how to use the built-in methods for sorting an array, so I though it was still worth posting though the essential answer is the same (ie, "pick the five closest for yourself, pass only those on"):

你需要为自己按距离对注释进行排序,并且只向MKMapView提交最接近的五个注释。如果您有两个CLLocations,那么您可以使用 distanceFromLocation:方法(这是getDistanceFrom:在iOS 3.2之前;该名称现已弃用)。

You're going to need to sort your annotations by distance for yourself, and submit only the closest five to the MKMapView. If you have two CLLocations then you can get the distance between them using the distanceFromLocation: method (which was getDistanceFrom: prior to iOS 3.2; that name is now deprecated).

因此,例如,假设您的Annotation类有一个方法'setReferenceLocation:',您传递一个CLLocation和一个getter'distanceFromReferenceLocation',它返回两者之间的距离,您可以这样做:

So, for example, supposing your Annotation class had a method 'setReferenceLocation:' to which you pass a CLLocation and a getter 'distanceFromReferenceLocation' which returns the distance between the two, you could do:

// 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树。

Depending on where you're loading from, you made need to create a local store (in memory or on disk) for annotations and select the five nearest whenever the user moves. Either register yourself as a CLLocationManager delegate or key-value observe on the map view's userLocation property. If you have quite a lot of potential annotations then sorting all of them is a bit wasteful and you'd be better advised to use a quadtree or a kd-tree.

这篇关于仅向MKMapVIew加载五个注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆