我有一大组大约 200 个地址,我需要知道它们的纬度和经度。我创建了一个解析地址的方法,现在我尝试使用 CLGeocoder
获取这些地址的坐标。
我目前的方法是并行创建地理编码器并让它们发挥作用。我注意到他们每个人似乎都有一个单独的线程。 (所以我一次看到多达 100 个线程)。
我遇到的问题是在某些时候(大约 50 个地址之后),地理编码停止返回任何地点标记,并且
NSLog(@"Address not recognized: *%@*",[htc objectForKey:kAddressKey]);
被调用。这是对多个线程的限制还是内置的 CLGeocoder 限制?会不会是我没有正确清理地理编码器,需要某种自动释放语句 (ARC)?
-(void)geocodeArray:(NSMutableArray*)数组 {
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 个数组,并尝试以 block 的形式对它们进行地理编码。我注意到第一个请求以及第二个请求的一部分通过了。但是一旦达到 (~50) 的魔数(Magic Number),地理编码就会停止。
对可能发生的事情有什么想法吗? 这是 Apple 对地理编码操作数量施加的限制吗?我应该增加请求之间的延迟还是尝试分别运行该应用 5 次并手动拼凑结果?
-(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 个地理编码,“时间”因素未知。
我遇到过类似的问题,但由于我只需要按顺序向用户呈现地理编码数据,这需要时间,所以我对所有地理编码进行了排队。
实际上,我对 25 个数据 block 进行了地理编码 - 一次向用户显示 1 个结果,每个结果之间的间隔大约为半秒。当我要显示的内容少于 4 个时,我将对接下来的 25 个进行地理编码。这将一直持续到对所有内容进行地理编码(或者在我的情况下,无限期)。
如果您需要一次对所有内容进行地理编码,则需要将您的地理编码与每个 block 之间的延迟链接在一起,并显示某种忙碌指示器,直到完成为止。大量地理编码可能需要一段时间。
关于iPhone iOS5 CLGeocoder 如何对一大组(200)地址进行地理编码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10619879/