【问题标题】:Showing nearby restaurants in MKMap View在 MKMap 视图中显示附近的餐厅
【发布时间】:2013-02-19 06:03:02
【问题描述】:

在我的 iphone 应用程序中,我必须在地图视图中显示附近的餐馆,目前我在网页视图中使用谷歌地图网址。

但是如何使用本地 MKMap 视图显示当前位置 5000 米内附近的餐馆(我发现了我当前的位置 - 纬度和经度)

我想了解如何按照下面的屏幕截图来实现(也可以点击注释转到其详细信息)

有什么帮助吗??提前致谢

【问题讨论】:

  • 谷歌搜索 Google Place API
  • no..我不是在谈论 google place API,我可以在 WEBView 上显示它,我希望在 iOS 地图上实现它
  • 这已经过时了。只需使用现在完全内置于 iOS 的 MKMapKit。只是几行代码

标签: iphone ios mkmapview mapkit


【解决方案1】:

在 iOS 6.1 中,您可以使用 MKLocalSearch,它是标准 iOS MapKit.framework 的一部分:

MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = @"restaurant";
request.region = mapView.region;

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

    NSMutableArray *annotations = [NSMutableArray array];

    [response.mapItems enumerateObjectsUsingBlock:^(MKMapItem *item, NSUInteger idx, BOOL *stop) {
        CustomAnnotation *annotation = [[CustomAnnotation alloc] initWithPlacemark:item.placemark];

        annotation.title = item.name;
        annotation.subtitle = item.placemark.addressDictionary[(NSString *)kABPersonAddressStreetKey];
        annotation.phone = item.phoneNumber;

        [annotations addObject:annotation];
    }];

    [self.mapView addAnnotations:annotations];
}];

我的自定义注解只是一个MKPlacemark 加上一个标题和副标题:

@interface CustomAnnotation : MKPlacemark

@property (strong, nonatomic) NSString *title;
@property (strong, nonatomic) NSString *subtitle;
@property (strong, nonatomic) NSString *phone;

@end

如果您想在标注上看到披露指示符(以便您可以转换到另一个控制器以查看详细信息,您可以:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    if (![annotation isKindOfClass:[CustomAnnotation class]])
        return nil;

    MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation
                                                                       reuseIdentifier:@"CustomAnnotationView"];
    annotationView.canShowCallout = YES;
    annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];

    return annotationView;
}

如果您想在用户单击标注附件时打开其他视图:

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    if (![view.annotation isKindOfClass:[CustomAnnotation class]])
        return;
    CustomAnnotation *annotation = (CustomAnnotation *)view.annotation;

    ABRecordRef person = ABPersonCreate();
    ABRecordSetValue(person, kABPersonOrganizationProperty, (__bridge CFStringRef) annotation.title, NULL);

    if (annotation.phone)
    {
        ABMutableMultiValueRef phoneNumberMultiValue = ABMultiValueCreateMutable(kABMultiStringPropertyType);
        ABMultiValueAddValueAndLabel(phoneNumberMultiValue, (__bridge CFStringRef) annotation.phone, kABPersonPhoneMainLabel, NULL);
        ABRecordSetValue(person, kABPersonPhoneProperty, phoneNumberMultiValue, nil);
        CFRelease(phoneNumberMultiValue);
    }

    ABMutableMultiValueRef address = ABMultiValueCreateMutable(kABMultiDictionaryPropertyType);
    ABMultiValueAddValueAndLabel(address, (__bridge CFDictionaryRef) annotation.addressDictionary, kABWorkLabel, NULL);
    ABRecordSetValue(person, kABPersonAddressProperty, address, NULL);
    ABUnknownPersonViewController *personView = [[ABUnknownPersonViewController alloc] init];

    personView.unknownPersonViewDelegate = self;
    personView.displayedPerson = person;
    personView.allowsAddingToAddressBook = YES;

    [self.navigationController pushViewController:personView animated:YES];

    CFRelease(address);
    CFRelease(person);
}

- (void)unknownPersonViewController:(ABUnknownPersonViewController *)unknownPersonView didResolveToPerson:(ABRecordRef)person
{

}

有关更多信息(例如自定义注释视图、确定设备位置等),请参阅Location Awareness Programming Guide

有关简单示例,请参阅https://github.com/robertmryan/MKMapView-custom-annotations

【讨论】:

  • 谢谢它的工作... :) 我可以将标题传递给详细信息页面,如下所示,如何传递字幕?请看这个问题stackoverflow.com/questions/14954240/…
  • @NithinMK 你会像传递标题一样传递它。就个人而言,我认为传递annotation 本身更容易,这样详细信息页面就可以访问注释的所有属性。如果您仍然遇到问题,请在您的代码中发布一个新问题以创建注释以及您的代码以启动详细信息页面,我们可以为您提供进一步的帮助。请随时在此处添加指向新问题的链接,以便在您发布时我可以看到。
【解决方案2】:

首先参考这个 Google API Link https://developers.google.com/places/documentation/search 然后获取 id 并将其添加到 googleId 的参数中,然后将 radious 参数设置为 5000 值和 类型 设置值餐厅..

看我下面的例子..

NSString *str=[NSString  stringWithFormat:@"https://maps.googleapis.com/maps/api/place/search/json?location=%f,%f&radius=5000&types=%@&sensor=false&key=%@",currentLocation.latitude,currentLocation.longitude,@"restaurant",@"AIzaSyB7YTFTYyk9eb8ULNGxoy06-b_0DUOqdrY"];
NSLog(@"\n\n URL %@",str);
NSURL *strurl=[NSURL URLWithString:[str stringByReplacingOccurrencesOfString:@"|" withString:@"%7C"]];
//    NSURL *strurl = [NSURL URLWithString:@"https://maps.googleapis.com/maps/api/place/search/json?location=-33.8670522,151.1957362&radius=500&types=food&name=harbour&sensor=false&key=AIzaSyB7YTFTYyk9eb8ULNGxoy06-b_0DUOqdrY"];

ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:strurl];  
[request setDelegate:self];
[request startAsynchronous]; 

并在MKMapView 上实现这些完整记录,如下所示...

- (void)requestFinished:(ASIHTTPRequest *)request {

    // Use when fetching text data
    NSString *responseString = [request responseString];
    NSLog(@"\n\n>>>>......Response String >>> %@",responseString);

    if(responseString)
    {
        SBJSON *json = [[SBJSON alloc] init];
        NSError *error = nil;
        id result = [json objectWithString:responseString error:&error];

        if ([result isKindOfClass:[NSMutableArray class]]) 
        {
            NSLog(@"\n\n.......This is Mutable Array");
        }
        else 
        {
            if ([[result objectForKey:@"results"] count]>0) 
            {
                NSLog(@">>>>>>>> dict keys :%d \nFull Address : %@\n LatLong : %@ \n total result : %d", [[result objectForKey:@"results"] count],[[result objectForKey:@"results"]valueForKey:@"vicinity"],[[[result objectForKey:@"results"]valueForKey:@"geometry"]valueForKey:@"location"],[[result objectForKey:@"results"]count]);


                for (int i=0; i<[[result objectForKey:@"results"] count]; i++)     
                {
                    ann = [[MyAnnotation alloc] init];
                    ann.title = [[[result objectForKey:@"results"]objectAtIndex:i]valueForKey:@"name"];
                    ann.subtitle = [[[result objectForKey:@"results"]objectAtIndex:i]valueForKey:@"vicinity"];   

                    ann.annReferance=[[[result objectForKey:@"results"]objectAtIndex:i]valueForKey:@"reference"];

                    CLLocationCoordinate2D location;
                    location.latitude = [[[[[[result objectForKey:@"results"]objectAtIndex:i]valueForKey:@"geometry"]valueForKey:@"location"] valueForKey:@"lat"]doubleValue];
                    location.longitude = [[[[[[result objectForKey:@"results"]objectAtIndex:i]valueForKey:@"geometry"]valueForKey:@"location"] valueForKey:@"lng"] doubleValue];
                    ann.coordinate=location;
                    ann.annLocation=[NSString stringWithFormat:@"%f,%f",location.latitude,location.longitude];

                    //                    NSLog(@"\n\n rating %@",ann.annrating);
                    if ([[[[result objectForKey:@"results"]objectAtIndex:i] allKeys] containsObject:@"rating"]) 
                    {
                        // contains key
                        ann.annrating=[[[[result objectForKey:@"results"]objectAtIndex:i]valueForKey:@"rating"]stringValue];
                        NSLog(@"\n\n rating %@",ann.annrating);
                    }
                    else
                    {
                        ann.annrating=@"";
                    }
                    ann.annaddress=[[[result objectForKey:@"results"]objectAtIndex:i]valueForKey:@"vicinity"];
                    [mapView addAnnotation:ann];
                }
            }
        }
    }
}

这是我在我的应用程序中使用的代码,只需根据您的要求进行一些更改,您就会得到输出..

希望对你有帮助...

【讨论】:

  • 你最欢迎 :) 只需创建 MyAnnotation 类或你想用其他参数显示的东西..
  • 但是...什么是 ASIFormDataRequest??
  • 哦,我使用 ASIHTTPRequest 发送请求并从 api 获取数据 .. 只需添加 ASIHTTPRequest 并在当前类的 .m 文件中添加 .h 文件,它是一个用于向服务器发送请求并获取的类数据返回...
猜你喜欢
  • 1970-01-01
  • 2017-06-01
  • 1970-01-01
  • 2016-07-14
  • 2012-08-11
  • 1970-01-01
  • 2020-11-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多