Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios CLGeocoder是否返回一个placemark_Ios_Clgeocoder - Fatal编程技术网

Ios CLGeocoder是否返回一个placemark

Ios CLGeocoder是否返回一个placemark,ios,clgeocoder,Ios,Clgeocoder,我想重新思考和提问,因为这个问题对我来说仍然存在,所以我写了一个新问题 这是我的代码: - (SVGeocoder*)initWithParameters:(NSMutableDictionary*)parameters completion:(SVGeocoderCompletionHandler)block { self = [super init]; self.operationCompletionBlock = block; Class cl = NSClassFromString(

我想重新思考和提问,因为这个问题对我来说仍然存在,所以我写了一个新问题

这是我的代码:

- (SVGeocoder*)initWithParameters:(NSMutableDictionary*)parameters completion:(SVGeocoderCompletionHandler)block {
self = [super init];

self.operationCompletionBlock = block;

Class cl = NSClassFromString(@"CLGeocoder");
if (cl != nil)
{
    if (self.geocoder_5_1 == nil) {
        self.geocoder_5_1 = [[cl alloc] init];
    }

    NSString *address = [parameters objectForKey:kGeocoderAddress];
    [self.geocoder_5_1 geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {
        NSMutableArray *svplacemarks = [NSMutableArray arrayWithCapacity:1];
        SVPlacemark *placemark;
        NSLog(@"placemarks[count] = %i", [placemarks count]);
        for (CLPlacemark *mark in placemarks) {
            placemark = [[SVPlacemark alloc] initWithPlacemark:mark];
            [svplacemarks addObject:placemark];
        }

        self.operationCompletionBlock([NSArray arrayWithArray:svplacemarks],nil,error);
    }];

}
else
{
    self.operationRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://maps.googleapis.com/maps/api/geocode/json"]];
    [self.operationRequest setTimeoutInterval:kSVGeocoderTimeoutInterval];

    [parameters setValue:@"true" forKey:kGeocoderSensor];
    [parameters setValue:[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode] forKey:kGeocoderLanguage];
    [self addParametersToRequest:parameters];

    self.state = SVGeocoderStateReady;
}
return self;
}
这是我个人版本(相当粗糙)的SVGeocoder,使用CLGeocoder进行前向地理编码,具有iOS<5.1的可追溯性

我之所以使用这个解决方案,是因为谷歌的术语阻止在不在谷歌地图上显示结果的情况下使用地图API

问题与前面提到的问题相同:CLGeocoder只返回一个placemark,而日志会打印一个漂亮的字符

“placemarks[计数]=1”

我的问题是,有没有人知道是否有其他方法可以检索正向地理编码,或者其他神奇的东西(例如,苹果地图应用程序为我做的同一个查询显示多个标记,“通过罗马”)


编辑ROB的解决方案

Class mkLocalSearch = NSClassFromString(@"MKLocalSearch");

if (mkLocalSearch != nil)
{
    NSString *address = [parameters objectForKey:kGeocoderAddress];
    MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];

    request.region = MKCoordinateRegionForMapRect(MKMapRectWorld);

    request.naturalLanguageQuery = address;

    MKLocalSearch *localsearch = [[MKLocalSearch alloc] initWithRequest:request];
    [localsearch startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) {

        NSMutableArray *svplacemarks = [NSMutableArray arrayWithCapacity:1];
        SVPlacemark *placemark;
        NSLog(@"response.mapItems[count] = %i", [response.mapItems count]);

        for (MKMapItem *item in response.mapItems)
        {
            placemark = [[SVPlacemark alloc] initWithPlacemark:item.placemark];
            [svplacemarks addObject:placemark];
        }

        self.operationCompletionBlock([NSArray arrayWithArray:svplacemarks],nil,error);
    }];
}
这是一个有趣的解决方案,提供了另一种观点。不幸的是,即使我将区域设置为“全球”,我仍然会得到一个很好的日志

response.mapItems[count]=1

问题是“via roma”,这是意大利一个非常常见的街道名称,我想我们几乎可以在任何意大利城市找到它

也许我做错了什么


编辑2-新测试:

将World Rect转换为CLRegion,代码来自


。。。我得到了通常的“placemark[count]=1”

显然,
CLGeocoder
会在地址多次点击时返回多个placemark(即,该区域足够大,以至于简单的街道地址不明确),但是,如果区域足够小或者提供的地址足够唯一,它通常只会找到一个匹配项

虽然它不是一个通用的解决方案,有效的iOS 6.1,但您有
MKLocalSearch
,它可以进行更一般的查找(包括企业名称等):


我想这完全取决于您希望收到的多个点击类型。

有些地址的CLGeocoder会返回多个位置标记。我发现的一个例子是“Herzel 13,以色列海法”。我使用
geocodeAddressDictionary:completionHandler:
方法,得到地址的两个相同结果(它可以设置为street/city/country,也可以设置为street-结果相同)


很难找到这样的例子,当然,它们将来可能会改变。出于某种原因,Apple maps应用程序会显示“你的意思是……”对话框以查看更多地址。

感谢Rob的回答。该应用程序的目的类似于卫星导航器。我将编辑我的帖子以显示您的解决方案的实现。无论我使用的是哪种解决方案(无论是
CLGeoCoder
还是
MKLocalSearch
),我总是只得到一个结果。我在德国柏林,在搜索“旧金山”时,我得到的是“加州圣地亚哥”,而不是“加州旧金山”。我希望他们两个(地球上有很多圣人…)@Julian-我同意。这两个都不会返回详尽的列表。使用
CLGeocoder
我不会看到超过1或2个条目。这感觉像是一种“最佳猜测”方法,返回两三个条目。使用
MKLocalSearch
,您将获得更多的点击率(例如,尝试搜索任何特定城市的“餐厅”,您将获得一个餐厅列表),但这绝对不是一个详尽的列表(稍微更改区域,您可能会得到一个非常不同的结果列表)。是的。经过更多的阅读、测试和印象,我很确定它只搜索兴趣点,因为大城市总是有自己的“地址”,你会找到它们。地址查找肯定需要一些不同的东西,据我所知,他们没有内置任何东西…是的。。。问题只是:“苹果是怎么做到的?”直到今天我还没有找到答案
    NSString *address = [parameters objectForKey:kGeocoderAddress];

    // make a conversion from MKMapRectWorld to a regular CLRegion
    MKMapRect mRect = MKMapRectWorld;
    MKMapPoint neMapPoint = MKMapPointMake(MKMapRectGetMaxX(mRect), mRect.origin.y);
    MKMapPoint swMapPoint = MKMapPointMake(mRect.origin.x, MKMapRectGetMaxY(mRect));

    float ewDelta= neMapPoint.x - swMapPoint.x;
    float nsDelta= swMapPoint.y - neMapPoint.y;

    MKMapPoint cMapPoint = MKMapPointMake(ewDelta / 2 + swMapPoint.x, nsDelta / 2 + neMapPoint.y);

    CLLocationCoordinate2D neCoord = MKCoordinateForMapPoint(neMapPoint);
    CLLocationCoordinate2D swCoord = MKCoordinateForMapPoint(swMapPoint);

    CLLocationCoordinate2D centerCoord = MKCoordinateForMapPoint(cMapPoint);

    CLLocationDistance diameter = [self getDistanceFrom:neCoord to:swCoord];

// i don't have the map like showed in the example so i'm trying to center the search area to the hypothetical center of the world
    CLRegion *clRegion = [[CLRegion alloc] initCircularRegionWithCenter:centerCoord radius:(diameter/2) identifier:@"worldwide"];
    [self.geocoder_5_1 geocodeAddressString:address inRegion: clRegion completionHandler:^(NSArray *placemarks, NSError *error) {
        NSMutableArray *svplacemarks = [NSMutableArray arrayWithCapacity:1];
        SVPlacemark *placemark;
        NSLog(@"placemarks[count] = %i", [placemarks count]);
        for (CLPlacemark *mark in placemarks) {
            placemark = [[SVPlacemark alloc] initWithPlacemark:mark];
            [svplacemarks addObject:placemark];
        }

        self.operationCompletionBlock([NSArray arrayWithArray:svplacemarks],nil,error);
    }];
MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
request.region = self.mapView.region;
request.naturalLanguageQuery = textField.text;

MKLocalSearch *localsearch = [[MKLocalSearch alloc] initWithRequest:request];
[localsearch startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) {
    for (MKMapItem *item in response.mapItems)
    {
        Annotation *annotation = [[Annotation alloc] initWithPlacemark:item.placemark];
        annotation.title = item.name;
        annotation.phone = item.phoneNumber;
        annotation.subtitle = item.placemark.addressDictionary[(NSString *)kABPersonAddressStreetKey];
        [self.mapView addAnnotation:annotation];
    }
}];