1

地理座標を取得するためにGoogle 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;
}

CLGeocoderGoogle API の代わりに使用して、住所文字列から位置座標を取得したいと考えています。

CLGeocoder私はオンラインの例から見た作業を行ってきました。で作業するのは少し難しい作業だと思いますCLGeocoderCLGeocoder既存のコードに大きな変更を加える必要がないように、以前のコードからあまり変更せずに を使用しようとしました。

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. 私が試した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];

これはCLLocationCoordinate2D、getGeoLocation メソッドから緯度と経度の値を取得した後に実行されます。

4

3 に答える 3

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]; 
于 2013-03-19T18:49:20.737 に答える
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;
}

うまくいけば、それはあなたを助けるでしょう。

ありがとう。

于 2013-03-20T04:10:27.727 に答える
0

魔法は何もありませんが、ブロック内でマップビューを突く必要があります:

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

マップビューが 2 回描画されるのを避けたい場合は、MKMapview (特にmapViewWillStartLoadingMap ) のイベントをインターセプトし、それらをコード内に実装し、リバース ジオコーディング ブロックが実行されるまでマップが描画されないように適切なフラグを設定する必要があります。 .

于 2013-03-19T18:40:25.537 に答える