随笔 - 35  文章 - 21  trackbacks - 0
<2012年1月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
2930311234

常用链接

留言簿

随笔分类

随笔档案

文章分类

搜索

  •  

最新评论

阅读排行榜

评论排行榜

Apple 提供了一个地址方向解析的服务 MKReverseGeocoder,上传一个经纬度,返回一个详细的地理位置信息。但这个服务在中国不太稳定,时常不可用。
Google map 也提供了一个类似的服务,是访问一个 google map 的 api,这里试图封装了 google map 的服务。使使用 apple 和 google 的服务的接口基本一致,替换起来很容易。Google map 的这个服务在中国的状态比 apple 稍微好一些,但也有不稳定的时候。我猜想,apple 也许是使用 google 的服务封装了自己的 MKReverseGeocoder。若是如此,这里的尝试也就没有什么意义了。

DOUHttpRequest 是对 ASIHTTPRequest 的一个简单封装。这些代码可以 继承自 MKReverseGeocoder。这样,使用方法就和 MKReverseGeocoder 一样了。

static NSString* kGeoServerUrl = @"http://maps.google.com/maps/api/geocode/json?latlng=%f,%f&sensor=true&language=en";
static NSString* kLatitudeUserInfoKey = @"latitudeUserInfoKey";
static NSString* kLongitudeUserInfoKey = @"longitudeUserInfoKey";

//
// It's tje solution for replacing MKReverseGeocoder that has problem in China.
//
- (void)startedReverseGeoderWithLatitude:(double)latitude longitude:(double)longitude {
  NSString *url = [NSString stringWithFormat:kGeoServerUrl, latitude, longitude];
  DOUHttpRequest *req = [DOUHttpRequest requestWithURL:[NSURL URLWithString:url] target:self];
  
  NSNumber *lat = [NSNumber numberWithDouble:latitude];
  NSNumber *lon = [NSNumber numberWithDouble:longitude];
  req.userInfo = [NSDictionary dictionaryWithObjectsAndKeys:lat, kLatitudeUserInfoKey, lon, kLongitudeUserInfoKey, nil];
  
  DOUService *service = [DOUService sharedInstance];  
  [service addRequest:req];
}


- (NSDictionary *)addressDictionary:(NSObject *)obj {
  
  NSArray* ary = nil;
  if (IS_INSTANCE_OF(obj, NSDictionary)) {
    NSObject* data = [(NSDictionary*)obj objectForKey:@"results"];
    if (IS_INSTANCE_OF(data, NSArray)) {
      ary = (NSArray*)data;
      NSDictionary *dic = [ary objectAtIndex:0];
      
      NSArray *addressComps = [dic objectForKey:@"address_components"];
      
      //NSString *streetNumber = @"";
      NSString *route = @"";
      NSString *locality = @"";
      NSString *country = @"";
      for (NSDictionary *comp in addressComps) {
        NSArray *types = [comp objectForKey:@"types"];
        NSString *type = [types objectAtIndex:0];
        
//        if ([type isEqualToString:@"street_number"]) {
//          streetNumber = [comp objectForKey:@"long_name"];
//        }
        
        if ([type isEqualToString:@"route"]) {
          route = [comp objectForKey:@"long_name"];
        }
        
        if ([type isEqualToString:@"locality"]) {
          locality = [comp objectForKey:@"long_name"];
        }
        
        if ([type isEqualToString:@"country"]) {
          country = [comp objectForKey:@"long_name"];
        }        
      }
      
      NSDictionary *addressDic = [NSDictionary dictionaryWithObjectsAndKeys:route, kABPersonAddressStreetKey,
                                  locality, kABPersonAddressCityKey,                                        
                                  country, kABPersonAddressCountryKey, nil];
      return addressDic;
    }
  }
  return nil;
}


- (void)requestFinished:(DOUHttpRequest *)req {
  NSError *error = [req error];
  if (!error) {
    DebugLog(@"str:%@", [req responseString]);
    
    NSObject *obj = [[req responseString] JSONValue];
    NSDictionary *addressDic = [self addressDictionary:obj];
    
    CLLocationCoordinate2D coordinate;
    coordinate.latitude = [[req.userInfo objectForKey:kLatitudeUserInfoKey] doubleValue];
    coordinate.longitude = [[req.userInfo objectForKey:kLongitudeUserInfoKey] doubleValue]; 
    MKPlacemark *placemark = [[[MKPlacemark alloc] initWithCoordinate:coordinate 
                                                   addressDictionary:addressDic] autorelease];
    [self reverseGeocoder:nil didFindPlacemark:placemark];
  }
}

- (void)requestFailed:(DOUHttpRequest *)req { 
  [self reverseGeocoder:nil didFailWithError:[req error]];
}


#pragma mark - MKReverseGeocoderDelegate

static NSString * const AppleLanguagesKey = @"AppleLanguages";

- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark {

  NSArray *array = [[NSUserDefaults standardUserDefaults] objectForKey:AppleLanguagesKey];
  NSString *currentLanguage = [array objectAtIndex:0];
  
  // set current language as english
  [[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"zh-Hans", nil] 
                                            forKey:AppleLanguagesKey];
  NSString *local = [placemark.locality lowercaseString];
 
  [AppContext sharedInstance].currentCityUid = local;
  
  // reset current language
  [[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:currentLanguage, nil] 
                                            forKey:AppleLanguagesKey];
}

- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error {
  TraceLog(@"reverseGeocoder :%@", [error localizedDescription]);  
}
posted on 2012-01-12 21:27 lincode 阅读(1301) 评论(0)  编辑  收藏 所属分类: ios

只有注册用户登录后才能发表评论。


网站导航: