2013-03-19 54 views
1

我使用的是Google API來獲取地理座標。我一直在使用至今一直是代碼如下在地圖視圖中使用CLGeocoder代替私有API

-(CLLocationCoordinate2D) getLocationFromAddressString:(NSString*) addressStr { 

NSString *urlStr = [NSString stringWithFormat:@"http://maps.google.com/maps/geo?q=%@&output=csv", 
        [addressStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; 
NSString *locationStr = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlStr] encoding:NSStringEncodingConversionAllowLossy error:nil]; 
NSArray *items = [locationStr componentsSeparatedByString:@","]; 
double latitude = 0.0; 
double longitude = 0.0; 

//NSLog(@"items array %@", items); 

if([items count] >= 4 && [[items objectAtIndex:0] isEqualToString:@"200"]) { 
    latitude = [[items objectAtIndex:2] doubleValue]; 
    longitude = [[items objectAtIndex:3] doubleValue]; 
} 
else { 
    //NSLog(@"Address, %@ not found: Error %@",addressStr, [items objectAtIndex:0]); 
} 

CLLocationCoordinate2D location; 
location.latitude = latitude; 
location.longitude = longitude; 
return location; 
} 

我希望用CLGeocoder在谷歌API的地方,從一個地址字符串獲得位置座標。

我一直在使用CLGeocoder從網上的例子。我發現與CLGeocoder合作有點困難。我嘗試使用CLGeocoder,而沒有更改我以前的代碼,這樣我就不必對現有代碼進行大的更改。

CLGeocoder *geocoder = [[CLGeocoder alloc] init]; 
[geocoder geocodeAddressString:addressStr completionHandler:^(NSArray *placemarks, NSError *error) { 
    self.placemarksArray = placemarks; 
    CLPlacemark *placeInfo = [placemarks objectAtIndex:0]; 
    NSString *latitudeString = [NSString stringWithFormat:@"%f",placeInfo.location.coordinate.latitude ]; 
    NSString *longitudeString = [NSString stringWithFormat:@"%f",placeInfo.location.coordinate.longitude ]; 
    NSLog(@"latitudeString %@", latitudeString); 
    NSLog(@"longitudeString %@", longitudeString); 

    _latitudes = placeInfo.location.coordinate.latitude; 
    _longitudes = placeInfo.location.coordinate.longitude; 
}]; 
location.latitude = _latitudes; 
location.longitude = _longitudes; 
return location; 

但是會發生什麼,地圖視圖會在塊被執行之前被加載。在這種情況下,該位置的確切值不會返回。

我的問題是:

  1. 是否有可能使用CLGeocoder,未做太大的變化,以我以前的代碼。或者我需要改變整個結構。
  2. 從我試過的第二塊代碼中,我做錯了什麼,我該如何糾正它?

編輯:上述方法是從viewDidLoad

CLLocationCoordinate2D mapCenter = [self getLocationFromAddressString:fullAddress]; 
MKPointAnnotation *annotationPoint = [[MKPointAnnotation alloc] init]; 
      [annotationPoint setCoordinate:mapCenter]; 
      [annotationPointsArray addObject:annotationPoint]; 
addAnnotation = [[[MyAddressAnnotation alloc] initWithCoordinate:mapCenter title:firstName SubTitle:lastName]autorelease]; 

[mapView addAnnotation:addAnnotation]; 

這被執行稱爲從getGeoLocation方法得到CLLocationCoordinate2D緯度和經度值之後。

+1

好吧,看起來你正在從'getLocationFromAddressString'中取得'location'並創建一個註解。你應該(a)改變'getLocationFromAddressString'返回'void',然後(b)將創建註釋的代碼放到'geocodeAddressString'完成塊中。 – Rob 2013-03-20 12:53:50

+0

我和你建議的方式一樣。 – 2013-03-20 14:02:01

回答

1

CLGeocoder異步發生(事實上,它在一個塊中完成了這一事實),因此_latitudes_longitudes不會在方法本身返回時設置。所以,很可能,是的,需要對代碼進行一些輕微的重組。我們很難建議,因爲我們沒有看到調用這個例程的代碼。底線,你必須重構該代碼,以便不要返回location,而是completionHandlergeocodeAddressString可以調用你需要做的任何事情。

看着你的修改代碼,看起來你的viewDidLoad正在獲取位置座標並創建一個註釋。只需在內添加註釋地理編碼塊即可。

這樣:

-(CLLocationCoordinate2D) geocodeAddressString:(NSString*)addressStr title:(NSString *)title subtitle:(NSString *)subtitle 
{ 
    CLGeocoder *geocoder = [[[CLGeocoder alloc] init] autorelease]; 
    [geocoder geocodeAddressString:addressStr completionHandler:^(NSArray *placemarks, NSError *error) { 
     self.placemarksArray = placemarks; 
     CLPlacemark *placeInfo = [placemarks objectAtIndex:0]; 

     id<MKAnnotation> annotation = [[[MyAddressAnnotation alloc] initWithCoordinate:placeInfo.location.coordinate 
                       title:title 
                       SubTitle:subtitle] autorelease]; 

     [self.mapView addAnnotation:addAnnotation]; 
    }]; 
} 

,然後viewDidLoad將如下稱之爲:

[self geocodeAddressString:fullAddress title:firstName subtitle:lastName]; 
+0

我有一個問題是關於標題和字幕信息。唯一的辦法就是,我可以將這些數據傳遞給註釋對象是通過地址字符串參數嗎?或者,還有更好的方法? – 2013-03-20 14:08:35

+0

@XaviValero只需在該方法中添加其他參數即可。看修改後的答案。 – Rob 2013-03-20 14:53:06

0

魔法沒什麼,但你要捅你塊內的MapView類,:

self.mapView.centerCoordinate = placeInfo.location.coordinate //or equivalent of this, like latitudes and longitudes change 

如果你想避免的MapView被繪製兩次,你需要截取的MKMapview(尤其是mapViewWillStartLoadingMap)活動,在你的代碼中實現它們,並且放置適當的標誌以避免地圖被繪製,直到反向地理編碼塊沒有被執行爲止。

0

試試這個答案。

部分延遲(即2秒)的呼叫方法。

[self performSelector:@selector(geoCodeUsingAddress:) withObject:userAddress afterDelay:2.0]; 

調用GetCurrentLocation功能

- (CLLocationCoordinate2D) geoCodeUsingAddress:(NSString *)addressStr 
{ 
    CLGeocoder *geocoder = [[CLGeocoder alloc] init]; 
    [geocoder geocodeAddressString:addressStr completionHandler:^(NSArray *placemarks, NSError *error) { 
     self.placemarksArray = placemarks; 
     CLPlacemark *placeInfo = [placemarks objectAtIndex:0]; 

     NSString *latitudeString = [NSString stringWithFormat:@"%f",placeInfo.location.coordinate.latitude ]; 
     NSString *longitudeString = [NSString stringWithFormat:@"%f",placeInfo.location.coordinate.longitude ]; 

     NSLog(@"latitudeString %@", latitudeString); 
     NSLog(@"longitudeString %@", longitudeString); 

     _latitudes = placeInfo.location.coordinate.latitude; 
     _longitudes = placeInfo.location.coordinate.longitude; 
    }]; 

    location.latitude = _latitudes; 
    location.longitude = _longitudes; 

    return location; 
} 

希望,它會幫助你。

謝謝。

+0

它是一個無效的方法,你正在返回一個值。 如果方法本身在延遲後被調用,它會有什麼幫助? – 2013-03-20 04:27:00

+0

@ XaviValero:對不起,這是我從void函數返回值的錯誤。現在,我已經編輯過,試試它是否對你有幫助。 – 2013-03-20 04:41:05