iPhone iOS5 CLGeocoder 如何对大量(200)组地址进行地理编码? [英] iPhone iOS5 CLGeocoder how to geocode a large (200) set of addresses?

查看:15
本文介绍了iPhone iOS5 CLGeocoder 如何对大量(200)组地址进行地理编码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有大量的大约 200 个地址,我需要知道它们的纬度和经度.我创建了一个解析地址的方法,现在我正在尝试使用 CLGeocoder 获取这些地址的坐标.

I got a large set of about 200 addresses for which I need to know their latitude and longitude. I've created a method that parses the addresses, and now I'm trying to get coordinates for these addresses using CLGeocoder.

我目前的方法是并行创建地理编码器并让它们发挥作用.我注意到他们每个人似乎都有一个单独的线程.(所以我一次看到多达 100 个线程).

My current approach is to create geocoders in parallel and let them do their magic. I noticed that each one of them seems to take a separate thread. (so I saw up to 100 threads at one point).

我遇到的问题是,在某个时间点(大约 50 个地址之后),地理编码停止返回任何地点标记,并且

NSLog(@"Address not recognized: *%@*",[htc objectForKey:kAddressKey]);

被调用.这是对线程数量的限制还是内置的 CLGeocoder 限制?可能是我没有正确清理地理编码器并需要某种自动释放语句 (ARC)?

gets called. Is this a limitation on a number of threads or a built-in CLGeocoder limitation? Could it be that I'm not cleaning up geocoders properly and need some sort of an autorelease statement(ARC)?

-(void)geocodeArray:(NSMutableArray*)array{

-(void)geocodeArray:(NSMutableArray*)array {

    NSMutableDictionary* htc = nil;
    objectsToGeocode = array.count;

    NSDictionary *htcDictionary =nil;
     for (int i = 0; i<array.count;i++) {
         htcDictionary = [array objectAtIndex:i];

        //create an updated dictionary that would hold the reverse geocoding location
        htc = [[NSMutableDictionary alloc] initWithDictionary:htcDictionary];
        NSLog(@"geocoding: %@",[htc objectForKey:kAddressKey]);

        CLGeocoder* geoCoder = [[CLGeocoder alloc] init];
        [geoCoder geocodeAddressString:[htc objectForKey:kAddressKey] completionHandler:^(NSArray *placemarks, NSError *error) {

            if(placemarks.count>0)
            {
                NSLog(@"Found placemarks for %@",[htc objectForKey:kAddressKey]);
                CLPlacemark* placemark =  [placemarks objectAtIndex:0];
                MyLocation *annotation = [[MyLocation alloc]
                                          initWithName:[htcDictionary objectForKey:kNameKey]
                                          address:[htcDictionary objectForKey:kAddressKey]
                                          coordinate:placemark.location.coordinate] ;
                annotation.faxNumber = [htc objectForKey:kFaxKey];
                annotation.phoneNumber = [htc objectForKey:kPhoneKey];
                annotation.website = [htc objectForKey:kWebsiteKey];
                annotation.type = [htc objectForKey:kFacilityTypeKey];
                [_mapView addAnnotation:annotation];  


                double placemarkToUserDistance = [self._mapView.userLocation.location distanceFromLocation:placemark.location] ;
                //convert distance to miles
                placemarkToUserDistance =placemarkToUserDistance/ 1000/ kKilometersPerMile;

                [htc setObject:[NSNumber numberWithDouble:placemarkToUserDistance] forKey:kDistanceToUserKey];
                [htc setObject:[NSNumber numberWithDouble:placemark.location.coordinate.latitude] forKey:kLatitudeKey];
                 [htc setObject:[NSNumber numberWithDouble:placemark.location.coordinate.longitude] forKey:kLongitudeKey];
                NSAssert([htc objectForKey:kLatitudeKey]!=nil,@"kLatitudeKey is not saved!");
                NSAssert([htc objectForKey:kLongitudeKey]!=nil,@"kLongitudeKey is not saved!");

            }else {
                NSLog(@"Address not recognized: *%@*",[htc objectForKey:kAddressKey]);
            }


            [self.dataSource addObject:htc];

            if(++geocodingCount >=objectsToGeocode){
                NSLog(@"%@",self.dataSource);
                    [self saveGeocoding];

            }

        } ];


        //        [temp addObject:htcDictionary];
    }

}

为了测试这是否是线程问题,我创建了这个方法,它将我的大型数据集拆分为 5 个数组,并尝试对它们进行地理编码.我注意到第一个请求以及第二个请求的一部分都通过了.但是一旦达到 (~50) 的幻数,地理编码就会停止.

To test if this is a threading issue, I created this method, which splits my large dataset into 5 arrays, and attempts to geocode them in chunks. I noticed that the first request passes, as well as a part of a second one. But once the magic number of (~50) is reached, the geocoding stops.

对可能发生的事情有任何想法吗?这是 Apple 对地理编码操作数量施加的限制吗?我应该增加请求之间的延迟还是尝试单独运行应用 5 次并手动拼凑结果?

Any ideas of what may be happening? Is this an Apple imposed limit on the number of geocoding operations? Should I increase the delay between requests or try to run the app 5 separate times and piece together the results by hand?

-(void)geocodeDatasource
{

        //I'm trying to build a file with coordinates of addresses and include it with the app
        geocodingCount = 0;
        self.dataSource = [[NSMutableArray alloc] initWithCapacity:self.arrayForGeocodingInitialJSON.count+5];
        haveToEmailInitialResults = YES;


    //attempt to geocode in batches

     float numberOfArrays = 5.0;
    NSMutableArray* array1 = [[NSMutableArray alloc] initWithCapacity:arrayForGeocodingInitialJSON.count/numberOfArrays];
    NSMutableArray* array2 = [[NSMutableArray alloc] initWithCapacity:arrayForGeocodingInitialJSON.count/numberOfArrays];
    NSMutableArray* array3 = [[NSMutableArray alloc] initWithCapacity:arrayForGeocodingInitialJSON.count/numberOfArrays];
    NSMutableArray* array4 = [[NSMutableArray alloc] initWithCapacity:arrayForGeocodingInitialJSON.count/numberOfArrays];
    NSMutableArray* array5 = [[NSMutableArray alloc] initWithCapacity:arrayForGeocodingInitialJSON.count/numberOfArrays];

    for(int i = 0 ;i<arrayForGeocodingInitialJSON.count;i++)
    {
        id object = [arrayForGeocodingInitialJSON objectAtIndex:i];
        if(i<arrayForGeocodingInitialJSON.count*(1/numberOfArrays))
        {
            [array1 addObject:object];
        }else if(i>=arrayForGeocodingInitialJSON.count/numberOfArrays && i<arrayForGeocodingInitialJSON.count*(2/numberOfArrays))
        {
            [array2 addObject:object];
        }else if(i>=arrayForGeocodingInitialJSON.count*(2/numberOfArrays) && i<arrayForGeocodingInitialJSON.count*(3/numberOfArrays))
        {
            [array3 addObject:object];
        }else if(i>=arrayForGeocodingInitialJSON.count*(3/numberOfArrays) && i<arrayForGeocodingInitialJSON.count*(4/numberOfArrays))
        {
            [array4 addObject:object];
        }else if(i>=arrayForGeocodingInitialJSON.count*(4/numberOfArrays) && i<arrayForGeocodingInitialJSON.count)
        {
            [array5 addObject:object];
        }



    }

    //simple delays eliminate the need for extra variables and notifications
        [self geocodeArray:array2];

        [self performSelector:@selector(geocodeArray:) withObject:array1 afterDelay:15];
        [self performSelector:@selector(geocodeArray:) withObject:array3 afterDelay:30];
        [self performSelector:@selector(geocodeArray:) withObject:array4 afterDelay:45];
        [self performSelector:@selector(geocodeArray:) withObject:array5 afterDelay:45];
}

谢谢!

推荐答案

您不能立即对大型集进行地理编码.iOS 会限制你.我已经看到 iOS 一次将您限制为 50 个地理编码,时间"因素是未知的.

You can't immediately geocode large sets. iOS throttles you. I have seen that iOS limits you to 50 geocodes at a time, with the "time" factor being an unknown.

我遇到过类似的问题,但由于我只需要将地理编码数据按顺序呈现给用户,这需要时间,因此我将所有地理编码都排入队列.

I've had a similar problem, but as I needed only to present the geocoding data in a sequence to the user that takes time, I queued all my geocodings.

实际上,我对 25 个数据块进行地理编码 - 一次向用户 1 显示结果,每次显示结果之间的间隔约为半秒.当我要显示的内容少于 4 个时,我将对接下来的 25 个进行地理编码.这种情况一直持续到所有内容都被地理编码(或者在我的情况下,无限期).

Effectively, I geocode a chunk of 25 - display the results to the user 1 at a time at about an interval of a half second between each. When I have fewer than 4 left to display, I will geocode the next 25. This continues until everything is geocoded (or in my case, indefinitely).

如果您需要一次对所有内容进行地理编码,则需要将地理编码与每个块之间的延迟链接在一起,并在完成之前显示某种忙碌指示符.这可能需要一些时间来处理大量的地理编码.

If you need to have everything geocoded at once, you'll need to chain your geocodings together with delays between each chunk and show some sort of busy indicator until you are done. Which could be some time with large sets of geocodings.

这篇关于iPhone iOS5 CLGeocoder 如何对大量(200)组地址进行地理编码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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