如何使用UISearchBar搜索MKMapView?

Gol*_*les 42 iphone cocoa-touch mkmapview mkreversegeocoder ios

我有一个应用程序需要具有类似的搜索功能,如Apple"地图"应用程序(包括在iPhone,iPod Touch和iPad中).

有问题的功能应该不是一件很难的事情,但我真的对如何在搜索栏中输入街道地址,然后获取该地址的坐标或者可以帮助我实际移动地图的东西毫无头绪在那个地方居中.

我的意思是,我需要查询什么,Apple是否提供"地址搜索API方法"?或者我需要直接使用谷歌地图API?

我很想知道应该怎么做.

Sha*_*een 56

这可能是最简单的方法.它使用苹果服务器进行地理编码.有时苹果服务器提供比谷歌更好的响应.很快(在IOS 6.1中)谷歌地图将完全脱离IOS.因此,如果应用程序保留在苹果提供的功能内,那就太好了.

-(void)searchBarSearchButtonClicked:(UISearchBar *)theSearchBar
{
    [theSearchBar resignFirstResponder];
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    [geocoder geocodeAddressString:theSearchBar.text completionHandler:^(NSArray *placemarks, NSError *error) {
        //Error checking

        CLPlacemark *placemark = [placemarks objectAtIndex:0];
        MKCoordinateRegion region;
        region.center.latitude = placemark.region.center.latitude;
        region.center.longitude = placemark.region.center.longitude;
        MKCoordinateSpan span;
        double radius = placemark.region.radius / 1000; // convert to km

        NSLog(@"[searchBarSearchButtonClicked] Radius is %f", radius);
        span.latitudeDelta = radius / 112.0;

        region.span = span;

        [theMapView setRegion:region animated:YES];
    }];
}
Run Code Online (Sandbox Code Playgroud)


Gol*_*les 39

好的,回答我自己的问题:

如前所述,最好的办法是使用谷歌地图API,它支持很多格式,但出于几个原因我选择使用JSON.

以下是对Google Maps执行JSON查询并获取查询坐标的步骤.请注意,并非所有正确的验证都已完成,这只是一个概念验证.

1)为iPhone下载一个JSON框架/库,有几个,我选择了这个,它非常好,似乎是一个活跃的项目,加上几个商业应用程序似乎正在使用它.所以将它添加到您的项目中(此处的说明).

2)要在Google地图中查询地址,我们需要建立一个请求网址,如下所示:http: //maps.google.com/maps/geo?q = Paris + France

此URL将返回查询"Paris + France"的JSON对象.

3)代码:

//Method to handle the UISearchBar "Search", 
- (void) searchBarSearchButtonClicked:(UISearchBar *)theSearchBar 
{
    //Perform the JSON query.
    [self searchCoordinatesForAddress:[searchBar text]];

    //Hide the keyboard.
    [searchBar resignFirstResponder];
}
Run Code Online (Sandbox Code Playgroud)

在我们处理UISearchBar搜索后,我们必须向Google地图发出请求:

- (void) searchCoordinatesForAddress:(NSString *)inAddress
{
    //Build the string to Query Google Maps.
    NSMutableString *urlString = [NSMutableString stringWithFormat:@"http://maps.google.com/maps/geo?q=%@?output=json",inAddress];

    //Replace Spaces with a '+' character.
    [urlString setString:[urlString stringByReplacingOccurrencesOfString:@" " withString:@"+"]];

    //Create NSURL string from a formate URL string.
    NSURL *url = [NSURL URLWithString:urlString];

    //Setup and start an async download.
    //Note that we should test for reachability!.
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

    [connection release];
    [request release];
}
Run Code Online (Sandbox Code Playgroud)

我们当然必须处理GoogleMaps服务器的响应(注意:缺少许多验证)

//It's called when the results of [[NSURLConnection alloc] initWithRequest:request delegate:self] come back.
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{   
    //The string received from google's servers
    NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

    //JSON Framework magic to obtain a dictionary from the jsonString.
    NSDictionary *results = [jsonString JSONValue];

    //Now we need to obtain our coordinates
    NSArray *placemark  = [results objectForKey:@"Placemark"];
    NSArray *coordinates = [[placemark objectAtIndex:0] valueForKeyPath:@"Point.coordinates"];

    //I put my coordinates in my array.
    double longitude = [[coordinates objectAtIndex:0] doubleValue];
    double latitude = [[coordinates objectAtIndex:1] doubleValue];

    //Debug.
    //NSLog(@"Latitude - Longitude: %f %f", latitude, longitude);

    //I zoom my map to the area in question.
    [self zoomMapAndCenterAtLatitude:latitude andLongitude:longitude];

    [jsonString release];
}
Run Code Online (Sandbox Code Playgroud)

最后缩放我的地图的功能,现在应该是一件微不足道的事情.

- (void) zoomMapAndCenterAtLatitude:(double) latitude andLongitude:(double) longitude
{
    MKCoordinateRegion region;
    region.center.latitude  = latitude;
    region.center.longitude = longitude;

    //Set Zoom level using Span
    MKCoordinateSpan span;
    span.latitudeDelta  = .005;
    span.longitudeDelta = .005;
    region.span = span;

    //Move the map and zoom
    [mapView setRegion:region animated:YES];
}
Run Code Online (Sandbox Code Playgroud)

希望这有助于某人,因为JSON部分是一个真正的痛苦要弄清楚,我认为图书馆的记录不是很好,但它仍然非常好.

编辑:

由于@Leo问题,将一个方法名称修改为"searchCoordinatesForAddress:".我不得不说这种方法很好地作为概念证明,但是如果你打算下载大的JSON文件,你必须附加到NSMutableData对象来保存所有查询到谷歌服务器.(请记住,HTTP查询是分段的.)

  • 我建议使用stringByAddingPercentEscapesUsingEncoding:方法而不是用"+"替换空格?:) (3认同)
  • 很棒的问答.非常感谢! (2认同)
  • 一个建议:使用`http://maps.google.com/maps/geo?q =%@&output = csv`(以CSV模式输出)以避免解析JSON.(无需依赖JSON框架) (2认同)