CLGeocoder 曾经返回一个地标

2023-12-30

我想复活this https://stackoverflow.com/questions/10417022/how-to-get-multiple-placemarks-from-clgeocoder and this https://stackoverflow.com/questions/11344188/clgeocoder-only-returning-one-placemark问题,因为问题仍然存在,所以我正在写一个新问题。

这是我的代码:

- (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

我使用此解决方案是因为 Google 条款禁止使用地图 API,而不在 Google 地图上显示结果。

该问题与前面提到的问题相同:CLGeocoder 仅返回一个地标,并且日志打印出漂亮的

“地标[计数] = 1”。

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


编辑罗布的解决方案

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);
    }];
}

这是一个有趣的解决方案,提供了另一种观点。不幸的是,即使我将区域设置为全球,我仍然得到一个不错的日志

响应.mapItems[计数] = 1

查询是“via roma”,这是意大利非常常见的街道名称,以至于我认为我们几乎可以在任何意大利城市找到它。

也许我做错了什么?


编辑 2 - 新测试:

将 World Rect 转换为 CLRegion,代码来自here https://gist.github.com/esromneb/3402711

    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);
    }];

...我得到通常的“地标 [count] = 1”


明显地,CLGeocoder如果地址获得多次命中(即该区域足够大,以至于简单的街道地址不明确),将返回多个地标,但如果该区域足够小或者提供的地址足够唯一,它通常只会找到一个匹配项。

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

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];
    }
}];

我想这完全取决于您期望收到什么样的多次点击。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CLGeocoder 曾经返回一个地标 的相关文章

  • 如何使用 iOS 可达性

    我正在开发一个使用网络的 iPhone 应用程序 iPhone 通过 HTTP 请求与我的服务器通信 并且应该可以在 WiFi 和 3G 上运行 我目前使用NSURLConnection initWithRequest向我的服务器发送异步请
  • 为什么在尝试编译此代码时会收到错误“错误:未知类型名称'虚拟'”?

    Code struct IRenderingEngine virtual void Initialize int width int height 0 virtual void Render const 0 virtual void Upd
  • NSCalendar 返回明年第一周上周一的错误日期

    我使用下面的代码使用随机日期来计算上周一 哪个工作文件但我的代码在明年日期中断 下面是相同的代码 NSDate date NSDate dateWithTimeIntervalSince1970 1483620311 228 NSLog c
  • scntool:无法转换文件,失败原因:*** -[__NSSingleObjectArrayI objectAtIndex:]:索引 1 超出范围

    我正在 Xcode 9 3 下开发一个基于 iOS 11 3 SceneKit 的项目 我有几个 dae 文件格式的 3D 模型 每当我构建项目时 其中一个模型不会被复制到最终的 iOS 包中 深入研究错误 我在复制捆绑资源构建阶段收到以下
  • 如何在 Swift 中使用indexesOfObjectsPassingTest:

    IndexOfObjectsPassingTest 的声明在 Swift 中看起来像这样 func indexesOfObjectsPassingTest predicate AnyObject Int CMutablePointer
  • 如何在 iOS 中通过 Twitter API 获取用户电子邮件地址?

    我尝试了多个 SDK 但无法从任何资源获取电子邮件 ID 我努力了FHSTwitterEngine为此目的 但我没有得到解决方案 FHSTwitterEngine twitterEngine FHSTwitterEngine sharedE
  • UIStackView分布均匀填充

    所以 我有一个UIStackView其中包含四 4 UIViews 如果我删除其中一 1 个UIViews 其他三 3 个将填满UIStackView 我的问题 如何添加最大高度UIView这样它就不会填满整个空间UIStackView即使
  • Admob 广告无法快速显示

    您好 我正在尝试将 admob 广告添加到已使用 swift 上传到应用商店的应用程序中 我在 admob 中制作了一个应用程序并复制了 appid 和广告 id 并显示了各自的横幅广告和插页式广告 这里的问题是当我写这行时 request
  • AFNetworking XML 请求问题

    我在用着AFNetworking 2使用 JSON 响应 它工作正常 现在我必须将其转换为 XML 而不是使用 JSON 因为服务器响应是 XML 格式的 在我搜索之后 我找到了这段代码 但它不起作用 与 Charles 我发现请求是错误的
  • 如何在 Swift 中将文件名与文件扩展名分开?

    给定包中文件的名称 我想将该文件加载到我的 Swift 应用程序中 所以我需要使用这个方法 let soundURL NSBundle mainBundle URLForResource fname withExtension ext 无论
  • locationOfTouch 和 numberOfTouches

    你好 我有这个识别器 设置为 2 次触摸 但它只返回一个 而不是两个 CGPoint void gestureLoad UIGestureRecognizer recognizer recognizer UITapGestureRecogn
  • 如何制作带有 SWIFT 图像的弹出窗口

    我想知道如何制作类似于此示例的弹出窗口 原始窗口充满了按钮 选择这些按钮后将拉出我想要使用的图像 我会简单地创建一个可重用的UIView组件以及作为子视图所需的一切 例如UIImageView为了你的形象 UILabel or a UIBu
  • Objective-C UILabel 作为超链接

    我正在尝试做一个UILabel一个链接UIWebView 我怎样才能做一个UILabel作为超链接 您可以使用 UITapGestureRecognizer 它将实现与您想要的类似的功能 UILabel myLabel UILabel al
  • (Kiss)XML xpath 和默认命名空间

    我正在开发一个 iPhone 项目 需要解析一些 xml xml 可能包含也可能不包含默认名称空间 我需要知道如何解析 xml 以防它使用默认命名空间 由于我需要读取和写入 xml 因此我倾向于使用 KissXML 但我愿意接受建议 这是我
  • ios swift parse:从 3 个类收集数据

    我有这样的结构 User CardSet 带有指向 User objectId 的指针 user 和 col name 带有点 cards 的卡片到 Card Set objectId 和列 name 我想选择所有卡数据 包括当前用户的卡集
  • 从按钮执行 Segue 时应用程序冻结

    我的故事板中有一个按钮 它呈现一个带有模式序列的视图控制器 每次按下此按钮时 应用程序都会冻结 没有崩溃 也没有错误消息 prepareForSegue被调用 所有应该存在的视图控制器都在代码中prepareForSegue 但它们不会出现
  • 在 iPhone 3GS 与 iPhone 4 上为 Mobile Safari 嵌入 HTML5 视频

    我在服务器上的 mp4 文件中有 H 264 AAC 编码的视频 mime 类型的视频 mp4 添加到 Web 服务器 IIS 7 并且我有一个带有视频标签的页面
  • 如何解决 Xcode 5 中的红色(已移动)文件?

    在 Xcode 4 中 当您要移动文件时 可以通过单击右侧菜单中的按钮并通过 Finder 选择新位置来解析文件的新位置 在 Xcode 5 中 右侧菜单中没有按钮 我还没有找到任何方法通过右键单击文件或顶部菜单栏选项来指定文件的新位置 在
  • CoreBluetooth:检测设备超出范围/连接超时

    我正在设计一个 iOS 框架来处理多个 BLE 设备 均为同一类型 目前一切都运行良好 除了一件事 客户想要一个包含可用设备的列表 但是 我如何检测过去发现的设备何时不再可用 当我尝试连接到不再可用的设备时 会出现另一个问题 文档说 连接尝
  • 是否可以跨 2 个不同的 iOS 应用程序访问数据?

    假设我在 App1 中存储了一些 ID 数据 并希望在同一设备上的 App2 中访问它 平台上可以这样吗 如果没有的话有什么解决方法吗 您可以使用iOS 钥匙扣 http developer apple com library ios do

随机推荐