在地图视图中使用CLGeocoder而不是私有API

时间:2013-03-19 15:25:43

标签: iphone ios mkmapview mapkit 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;
}

我希望在Google API的位置使用CLGeocoder从地址字符串中获取位置坐标。

我一直在使用在线示例中的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. 从我尝试过的第二段代码中,我做错了什么以及如何纠正呢?
  3. 编辑:从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纬度和经度值后执行此操作。

3 个答案:

答案 0 :(得分:1)

CLGeocoder异步发生(它在块中完成的事实就是这样),因此_latitudes_longitudes在方法本身返回时不会被设置。所以,很可能,是的,需要对代码进行一些轻微的重组。由于我们没有看到调用此例程的代码,因此我们很难建议。最重要的是,您必须重构该代码,以便不是返回location,而是completionHandler geocodeAddressString调用您需要做的任何事情。

查看修改后的代码,您的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]; 

答案 1 :(得分:0)

没什么神奇之处,但你必须在你的街区内戳你的mapview:

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

如果你想避免两次绘制mapview,你需要拦截MKMapview的事件(特别是mapViewWillStartLoadingMap),在你的代码中实现它们,并放置适当的标志以避免绘制地图直到没有执行反向地理编码块的时间。

答案 2 :(得分: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;
}

希望它会对你有帮助。

感谢。