[英]Using CLGeocoder instead of private API in map view
I was using google API to obtain the geo co-ordinates. 我正在使用google API获取地理位置坐标。 The code I have been using till now is as below 到目前为止,我一直在使用的代码如下
-(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;
}
I wish to use CLGeocoder
in the place of google API to obtain the location co-ordinates from an address string. 我希望使用CLGeocoder
代替Google API从地址字符串中获取位置坐标。
I have been working with CLGeocoder
seen from examples online. 我一直在与CLGeocoder
合作,从在线示例中可以看到。 I find it a bit hard task working with the CLGeocoder
. 我发现使用CLGeocoder
有点困难。 I tried to use the CLGeocoder
without changing much from my previous code, so that I don't have to make big changes in the existing code. 我尝试使用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;
But what happens is that, the map view gets loaded before the block is executed. 但是发生的是,在执行该块之前加载了地图视图。 The exact value of the location is not returned in this case. 在这种情况下,不会返回位置的确切值。
My question is : 我的问题是:
CLGeocoder
, without making much changes to my previous code. 是否可以使用CLGeocoder
,而无需对我之前的代码进行太多更改。 Or should I need to change the whole structure. 还是我需要更改整个结构。 Edit: The above method is called from viewDidLoad
编辑:从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];
This gets executed after getting the CLLocationCoordinate2D
latitude and longitude values from getGeoLocation method. 从getGeoLocation方法获取CLLocationCoordinate2D
纬度和经度值后,将执行此操作。
CLGeocoder
happens asynchronously (the fact that it's done in a block gives that away), and thus _latitudes
and _longitudes
are not set by the time the method, itself, returns. CLGeocoder
异步发生(事实是在一个块中完成了这一事实),因此_latitudes
和_longitudes
不会在方法本身返回时设置。 So, likely, yes, some slight restructuring of your code will be needed. 因此,很可能,是的,将需要对代码进行一些轻微的重组。 It's hard for us to advise as we don't see the code that calls this routine. 我们很难建议,因为我们看不到调用此例程的代码。 Bottom line, you have to refactor that code so that rather than returning the location
, you have the completionHandler
of geocodeAddressString
invoke whatever you need done. 底线是,你必须重构的代码,这样,而不是返回的location
,你有completionHandler
的geocodeAddressString
调用任何你需要完成。
Looking at your revised code, it appears that your viewDidLoad
is taking the location coordinates and creating an annotation. 查看修改后的代码,看来viewDidLoad
正在获取位置坐标并创建注释。 Just do that adding of the annotation inside the geocoded block. 只需在地理编码块内添加注释即可。
Thus: 从而:
-(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];
}];
}
And then, viewDidLoad
would call it as follows: 然后, viewDidLoad
将按如下方式调用它:
[self geocodeAddressString:fullAddress title:firstName subtitle:lastName];
Nothing of magic, but you have to poke your mapview, inside your block: 没什么神奇的,但是您必须在块内戳地图视图:
self.mapView.centerCoordinate = placeInfo.location.coordinate //or equivalent of this, like latitudes and longitudes change
If you want to avoid the mapview being drawn twice, you need to intercept events of MKMapview (especially mapViewWillStartLoadingMap ), implement them within your code, and put proper flags to avoid the map being drawn till the time reverse geocoding block hasn't been executed. 如果要避免两次绘制mapview,则需要拦截MKMapview的事件(尤其是mapViewWillStartLoadingMap ),在代码中实现它们,并放置适当的标志来避免在未执行时间反向地理编码块之前绘制地图。
Try this answer. 试试这个答案。
Call method with some part of delay (ie 2 seconds). 延迟部分(即2秒)的调用方法。
[self performSelector:@selector(geoCodeUsingAddress:) withObject:userAddress afterDelay:2.0];
Calling GetCurrentLocation function 调用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;
}
Hopefully, it will help you. 希望会对您有所帮助。
Thanks. 谢谢。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.