問題描述
我有大量的大約 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)組地址進行地理編碼?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!