Objective-C - 根据用户输入的查询搜索街道

Posted

技术标签:

【中文标题】Objective-C - 根据用户输入的查询搜索街道【英文标题】:Objective-C - Search for streets based on user-entered query 【发布时间】:2015-05-26 14:47:22 【问题描述】:

我想让用户搜索街道名称并将结果显示在 UITableView 中。 目前地区并不重要,可以来自任何地区。

我在搜索中找不到任何相关示例,我不知道应该使用 CLLocation 还是 MKLocalSearch。

根据文档,我应该使用 MKLocalSearch:

虽然本地搜索和地理编码类似,但它们支持 不同的用例。当您想要在两者之间进行转换时使用地理编码 地图坐标和结构化地址,例如地址簿 地址。当您想查找一组位置时使用本地搜索 匹配用户的输入。

但是我已经尝试了这两种方法,它只给了我 1 个结果(即使返回了一个 NSArray。

这是 CLGeocoder 方法:

CLGeocoder *geocoding = [[CLGeocoder alloc] init];
[geocoding geocodeAddressString:theTextField.text completionHandler:^(NSArray *placemarks, NSError *error) 
    if (error) 
        NSLog(@"%@", error);
     else 
        NSLog(@"%i", [placemarks count]);
        for(CLPlacemark *myStr in placemarks) 
            NSLog(@"%@", myStr);
    
    
];

这是我的 MKLocalSearch 尝试:

MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = theTextField.text;
request.region = self.region;

localSearch = [[MKLocalSearch alloc] initWithRequest:request];

[localSearch startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error)

    if (error != nil) 
        [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Map Error",nil)
                                    message:[error localizedDescription]
                                   delegate:nil
                          cancelButtonTitle:NSLocalizedString(@"OK",nil) otherButtonTitles:nil] show];
        return;
    

    if ([response.mapItems count] == 0) 
        [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"No Results",nil)
                                    message:nil
                                   delegate:nil
                          cancelButtonTitle:NSLocalizedString(@"OK",nil) otherButtonTitles:nil] show];
        return;
    
    self.streets = response;
    [self.streetsTableView reloadData];
];

在某些情况下,MKLocalSearch 似乎返回超过 1 个响应,但这些响应与地点而非街道名称搜索有关。

提前致谢。

【问题讨论】:

您是否尝试将区域设置为零?或者您可以分享有关您的 self.region 的更多详细信息吗? 我有一个 MapView,我使用 MapView.region 作为 self.region 根据我的经验,MKLocalSearch 非常原始。您是否会出于任何原因反对使用 Google Places API? google 有一个more useful api,MKLocalSearch 仅用于简单的任务 【参考方案1】:

这是我能得到的最接近的。这涉及使用google places API Web Service。 注意:您可能会使用他们的 Google Maps API 等。我相信还有其他方法可以从各种 Google API 获取此信息。

 NSURL *googlePlacesURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/place/autocomplete/json?input=%@&location=%f,%f&sensor=true&key=API_KEY", formattedSearchText, location.coordinate.latitude,
                                                   location.coordinate.longitude]];

响应是一个 JSON 对象。将其转换为字典。

 NSDictionary *response = [NSJSONSerialization JSONObjectWithData:_googlePlacesResponse
                                                                    options:NSJSONReadingMutableContainers error:&error];

if([[response objectForKey:@"status"] isEqualToString:@"OK"])

    NSArray *predictions = [response objectForKey:@"predictions"];
    for(NSDictionary *prediction in predictions)
    
        NSArray *addressTypes = [prediction objectForKey:@"types"];
        if([addressTypes containsObject:@"route"])
        
            //This search result contains a street name. 
            //Now get the street name.
            NSArray *terms = [prediction objectForKey:@"terms"];
            NSDictionary *streetNameKeyValuePair = [terms objectAtIndex:0];
            NSLog(@"%@",[streetNameKeyValuePair objectForKey@"value"]);
        
    

可能的types 似乎是

路线 -> 街道名称 地区 -> 城市/位置名称 政治 -> 国家等 地理编码 -> 经纬度可用

您可以使用那些 ONLY 包含route 作为地址类型的predictions 填充表格视图。这可以工作。

【讨论】:

是的,就是这样。在阅读您的答案之前,我也做了同样的事情:)。这个帮助了我:***.com/a/25318167/347807【参考方案2】:

CLGeocoder 只返回地址格式。 在你的代码中添加这个并使用 mapitems 的内容

MKLocalSearchRequest *request = [MKLocalSearchRequest new];
request.naturalLanguageQuery = @"Pizza";
request.region = MKCoordinateRegionMake(location.coordinate, MKCoordinateSpanMake(.01, .01));
MKLocalSearch *search = [[MKLocalSearch alloc]initWithRequest:request];
[search startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) 
    NSArray *mapItems = response.mapItems;
    for (MKMapItem *mapItem in mapItems) 
        MKPointAnnotation *point = [MKPointAnnotation new];
        point.coordinate = mapItem.placemark.coordinate;`
    
];

【讨论】:

【参考方案3】:

返回的数组包含mapItems,你可以像这样遍历数组来拉出所有的mapItems:

myMatchingItems = [[NSMutableArray alloc] init];
for (MKMapItem *item in response.mapItems)
                    [myMatchingItems addObject:item];
    

每个mapItem.placemark.thoroughfare 都包含所找到位置的街道。

【讨论】:

以上是关于Objective-C - 根据用户输入的查询搜索街道的主要内容,如果未能解决你的问题,请参考以下文章

ElasticSearch-常用搜索

用户搜索策略移动开发

资料查询

我如何优化这个搜索结构?

用例建模Use Case Modeling

了解搜索引擎的工作原理是什么