2012-05-16 27 views
7

Tôi có một bộ khoảng 200 địa chỉ mà tôi cần biết kinh độ và vĩ độ của họ. Tôi đã tạo một phương thức phân tích các địa chỉ, và bây giờ tôi đang cố gắng để có được tọa độ cho các địa chỉ này bằng cách sử dụng CLGeocoder.CLGeocoder iPhone iOS5 làm cách nào để mã hóa địa lý một tập hợp địa chỉ lớn (200)?

Cách tiếp cận hiện tại của tôi là tạo các trình mã địa lý song song và để chúng thực hiện phép thuật của chúng. Tôi nhận thấy rằng mỗi người trong số họ dường như có một chủ đề riêng biệt. (vì vậy tôi đã thấy tối đa 100 chủ đề tại một thời điểm).

Vấn đề mà tôi đang chạy vào đó là tại một số điểm (sau khoảng 50 địa chỉ), mã địa lý ngừng trả lại bất kỳ dấu vị trí, và

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

được gọi. Đây có phải là giới hạn về một số chủ đề hoặc giới hạn CLGeocoder tích hợp không? Nó có thể được rằng tôi không làm sạch geocoders đúng cách và cần một số loại một tuyên bố autorelease (ARC)?

- (void) geocodeArray: (NSMutableArray *) mảng {

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

} 

Để kiểm tra nếu điều này là một vấn đề luồng, tôi tạo ra phương pháp này, mà chia tập dữ liệu lớn của tôi vào 5 mảng, và cố gắng mã hóa chúng theo từng phần. Tôi nhận thấy rằng yêu cầu đầu tiên đã trôi qua, cũng như một phần của yêu cầu thứ hai. Nhưng một khi số lượng ma thuật (~ 50) đạt được, mã hóa địa lý dừng lại.

Bất kỳ ý tưởng nào về những gì có thể xảy ra? Đây có phải là giới hạn áp đặt của Apple đối với số lượng hoạt động mã hóa địa lý không? Tôi có nên tăng độ trễ giữa các yêu cầu hoặc cố gắng chạy ứng dụng 5 lần riêng biệt và ghép các kết quả bằng tay không?

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

Cảm ơn bạn!

Trả lời

16

Bạn không thể mã hóa địa lý ngay lập tức các tập hợp lớn. iOS điều chỉnh bạn. Tôi đã thấy rằng iOS giới hạn bạn đến 50 mã địa lý tại một thời điểm, với yếu tố "thời gian" là không xác định.

Tôi đã gặp sự cố tương tự, nhưng khi tôi chỉ cần trình bày dữ liệu mã hóa địa lý theo trình tự cho người dùng cần có thời gian, tôi đã xếp hàng tất cả các mã địa lý của mình.

Có hiệu quả, tôi mã hóa địa lý một đoạn 25 - hiển thị kết quả cho người dùng 1 tại một khoảng thời gian khoảng một nửa giây giữa mỗi lần. Khi tôi có ít hơn 4 bên trái để hiển thị, tôi sẽ mã hóa địa lý tiếp theo 25. Điều này tiếp tục cho đến khi mọi thứ được mã hóa địa lý (hoặc trong trường hợp của tôi, vô thời hạn).

Nếu bạn cần phải có mọi thứ được mã hóa địa lý cùng một lúc, bạn sẽ cần phải cố định mã địa lý cùng với sự chậm trễ giữa mỗi đoạn và hiển thị một số chỉ báo bận cho đến khi bạn hoàn thành. Mà có thể là một thời gian với nhiều bộ mã địa lý.

+0

Điều này là tốt, nếu tôi hiểu chính xác, bạn có thể mã hóa địa lý hơn 50 yêu cầu nếu bạn cung cấp độ trễ hợp lý giữa các yêu cầu tiếp theo? –

+0

Yup, cho đến nay tôi có thể tìm thấy. Tôi đã có thể chạy mã hóa địa lý hàng giờ với độ trễ giữa mỗi mã địa lý (hiện tại tôi có độ trễ 3 giây). – NSProgrammer

+6

Tôi nghĩ giới hạn là 50 mỗi phút. Với sự chậm trễ 60s/50 = 1,2s giữa hai yêu cầu, tôi không nhận được lỗi (chỉ với một chút ít hơn, tôi làm!). – LPG

7

Câu trả lời là bạn đang vi phạm TOS cho trình mã hóa địa lý của Apple.

Từ tài liệu CLGeocoder.

Ứng dụng nên ý thức về cách chúng sử dụng mã hóa địa lý. Dưới đây là một số quy tắc chung để sử dụng lớp này một cách hiệu quả:

Gửi tối đa một yêu cầu mã hóa địa lý cho bất kỳ hành động nào của một người dùng. Nếu người dùng thực hiện nhiều hành động liên quan đến mã hóa địa lý cùng một vị trí, hãy sử dụng lại kết quả từ yêu cầu mã hóa địa lý ban đầu thay vì bắt đầu yêu cầu riêng lẻ cho từng hành động. Khi bạn muốn tự động cập nhật vị trí hiện tại của người dùng (chẳng hạn như khi người dùng đang di chuyển), hãy đưa ra yêu cầu mã hóa địa lý mới khi người dùng đã di chuyển một khoảng cách đáng kể và sau một khoảng thời gian hợp lý. Ví dụ: trong một trường hợp điển hình, bạn không nên gửi nhiều hơn một yêu cầu mã hóa địa lý mỗi phút. Không bắt đầu yêu cầu mã hóa địa lý tại thời điểm người dùng sẽ không thấy kết quả ngay lập tức. Ví dụ: không bắt đầu yêu cầu nếu ứng dụng của bạn không hoạt động hoặc ở chế độ nền.

Apple sẽ ở bên trong quyền của họ để ngừng cung cấp câu trả lời, cắt hoàn toàn ứng dụng của bạn hoặc thậm chí thu hồi tài khoản nhà phát triển của bạn.

Nếu bạn cần xử lý một số lượng lớn địa chỉ một cách nhanh chóng, thì bạn nên xem xét việc nhận dịch vụ như Thực tế cho các điểm ưa thích hoặc Bộ công cụ khoa học dữ liệu cho địa chỉ bưu chính và khu vực địa lý.


Cập nhật

Dưới đây là các tài liệu API cho Places API - Resolve, đó là thực tế của nơi geocoder.


Cập nhật 2

Đây là API cho Street Address to Coordinates, đó là vị trí geocoder liệu Khoa học Toolkit.

+0

Thực tế không có dịch vụ mã hóa địa lý, chỉ mã hóa địa lý đảo ngược. –

+0

@CodyC Tôi đã cập nhật câu trả lời của mình để bao gồm API cho dịch vụ mã hóa địa lý của Factual. –

+0

Đó là để định vị các địa điểm (ví dụ: McDonalds) và không phải địa điểm (ví dụ: Seattle, WA). Theo http://developer.factual.com/display/docs/Core+API+-+Geo+Filters "Thực tế không cung cấp Bộ mã hóa địa lý (bộ chuyển đổi địa chỉ sang tọa độ)" –

Các vấn đề liên quan