iOS原生地圖開發進階——使用導航和附近興趣點檢索

iOS原生地圖開發進階——使用導航和附近興趣點檢索

iOS中的mapKit框架對國際化的支持很是出色。在前些篇博客中,對這個地圖框架的基礎用法和標註與覆蓋物的添加進行了詳細的介紹,這篇博客將介紹兩個更加實用的功能的開發:線路導航與興趣點搜索。前幾篇博客的連接以下:數組

地圖基礎用法詳解:http://my.oschina.net/u/2340880/blog/415360服務器

添加大頭針與自定義標註:http://my.oschina.net/u/2340880/blog/415441app

添加地圖覆蓋物:http://my.oschina.net/u/2340880/blog/415611框架

1、線路導航

一、從幾個類的關係提及

(1)MKPlacemark學習

一個地點信息類,以下:編碼

@interface MKPlacemark : CLPlacemark <MKAnnotation>
//初始化方法,經過給定一個經緯度和地點信息字典
- (instancetype)initWithCoordinate:(CLLocationCoordinate2D)coordinate
                 addressDictionary:(NSDictionary *)addressDictionary;
//國家編碼
@property (nonatomic, readonly) NSString *countryCode;
@end

(2)MKMapItematom

地點節點類,包含此節點的許多地點信息,以下:url

@interface MKMapItem : NSObject
//當前節點的地點信息對象
@property (nonatomic, readonly) MKPlacemark *placemark;
//是不是當前位置
@property (nonatomic, readonly) BOOL isCurrentLocation;
//節點名稱
@property (nonatomic, copy) NSString *name;
//電話號碼
@property (nonatomic, copy) NSString *phoneNumber;
//網址
@property (nonatomic, strong) NSURL *url;
//將當前位置建立爲節點
+ (MKMapItem *)mapItemForCurrentLocation;
//由一個位置信息建立節點
- (instancetype)initWithPlacemark:(MKPlacemark *)placemark;

@end

(3)MKDirectionsRequestspa

導航請求類.net

@interface MKDirectionsRequest : NSObject
//起點節點
- (MKMapItem *)source NS_AVAILABLE(10_9, 6_0);
- (void)setSource:(MKMapItem *)source NS_AVAILABLE(10_9, 7_0);
//目的地節點
- (MKMapItem *)destination NS_AVAILABLE(10_9, 6_0);
- (void)setDestination:(MKMapItem *)destination NS_AVAILABLE(10_9, 7_0);

@end

這個類還有一些擴展的設置屬性:

 

@property (nonatomic) MKDirectionsTransportType transportType;

設置路線檢索類型,枚舉以下:

typedef NS_OPTIONS(NSUInteger, MKDirectionsTransportType) {
    MKDirectionsTransportTypeAutomobile     = 1 << 0,//適合駕車時導航
    MKDirectionsTransportTypeWalking        = 1 << 1,//適合步行時導航
    MKDirectionsTransportTypeAny            = 0x0FFFFFFF//任何狀況
};

 

@property (nonatomic) BOOL requestsAlternateRoutes;

設置是否搜索多條線路

 

@property (nonatomic, copy) NSDate *departureDate;

設置出發日期

 

@property (nonatomic, copy) NSDate *arrivalDate;

設置到達日期

 

(4)MKDirections

從apple服務器獲取數據的鏈接類

@interface MKDirections : NSObject
//初始化方法
- (instancetype)initWithRequest:(MKDirectionsRequest *)request NS_DESIGNATED_INITIALIZER;
//開始計算線路信息
- (void)calculateDirectionsWithCompletionHandler:(MKDirectionsHandler)completionHandler;
//開始計算時間信息
- (void)calculateETAWithCompletionHandler:(MKETAHandler)completionHandler;
//取消
- (void)cancel;
//是否正在計算
@property (nonatomic, readonly, getter=isCalculating) BOOL calculating;
@end

(5)MKDirectionsResponse

線路信息結果類

@interface MKDirectionsResponse : NSObject
@property (nonatomic, readonly) MKMapItem *source;//起點
@property (nonatomic, readonly) MKMapItem *destination;//終點
@property (nonatomic, readonly) NSArray *routes; //線路規劃數組
@end

(6)MKETResponse

時間信息結果類

@interface MKETAResponse : NSObject
@property (nonatomic, readonly) MKMapItem *source;//起點
@property (nonatomic, readonly) MKMapItem *destination;//終點
@property (nonatomic, readonly) NSTimeInterval expectedTravelTime;//耗時

@end

(7)MKRoute

線路信息類,導航的線路結果是這個類型的對象

@interface MKRoute : NSObject

@property (nonatomic, readonly) NSString *name; //線路名稱
@property (nonatomic, readonly) NSArray *advisoryNotices; //注意事項
@property (nonatomic, readonly) CLLocationDistance distance; //距離
@property (nonatomic, readonly) NSTimeInterval expectedTravelTime;//耗時
@property (nonatomic, readonly) MKDirectionsTransportType transportType; //檢索的類型

@property (nonatomic, readonly) MKPolyline *polyline; // 線路覆蓋物

@property (nonatomic, readonly) NSArray *steps; // 線路詳情數組

@end

(8)MKRouteStep

線路詳情信息類,線路中每一步的信息都是這個類的對象

@interface MKRouteStep : NSObject

@property (nonatomic, readonly) NSString *instructions; // 節點信息
@property (nonatomic, readonly) NSString *notice; // 注意事項

@property (nonatomic, readonly) MKPolyline *polyline; //線路覆蓋物

@property (nonatomic, readonly) CLLocationDistance distance; // 距離

@property (nonatomic, readonly) MKDirectionsTransportType transportType; // 導航類型

@end

看到上面如此多的類,你可能會以爲一頭霧水,那麼不用着急,類雖然繁雜,但他們之間的邏輯很是清晰,下面就經過一個例子來進行線路導航。

二、進行線路導航

- (void)viewDidLoad {
    [super viewDidLoad];
    //地圖初始化設置
    mapView =[[MKMapView alloc]initWithFrame:self.view.frame];
    mapView.region=MKCoordinateRegionMake(CLLocationCoordinate2DMake(39.26, 116.3), MKCoordinateSpanMake(5, 5));
    mapView.mapType=MKMapTypeStandard;
    mapView.delegate=self;
    [self.view addSubview:mapView];
    
    //導航設置
    CLLocationCoordinate2D fromcoor=CLLocationCoordinate2DMake(39.26, 116.3);
    CLLocationCoordinate2D tocoor = CLLocationCoordinate2DMake(33.33, 113.33);
    //建立出發點和目的點信息
    MKPlacemark *fromPlace = [[MKPlacemark alloc] initWithCoordinate:fromcoor
                                                       addressDictionary:nil];
    MKPlacemark *toPlace = [[MKPlacemark alloc]initWithCoordinate:tocoor addressDictionary:nil];
    //建立出發節點和目的地節點
    MKMapItem * fromItem = [[MKMapItem alloc]initWithPlacemark:fromPlace];
    MKMapItem * toItem = [[MKMapItem alloc]initWithPlacemark:toPlace];
    //初始化導航搜索請求
    MKDirectionsRequest *request = [[MKDirectionsRequest alloc]init];
    request.source=fromItem;
    request.destination=toItem;
    request.requestsAlternateRoutes=YES;
    //初始化請求檢索
    MKDirections *directions = [[MKDirections alloc]initWithRequest:request];
    //開始檢索,結果會返回在block中
    [directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {
        if (error) {
            NSLog(@"error:%@",error);
        }else{
            //提取導航線路結果中的一條線路
            MKRoute *route =response.routes[0];
            //將線路中的每一步詳情提取出來
            NSArray * stepArray = [NSArray arrayWithArray:route.steps];
            //進行遍歷
            for (int i=0; i<stepArray.count; i++) {
                //線路的詳情節點
                MKRouteStep * step = stepArray[i];
                //在此節點處添加一個大頭針
                MKPointAnnotation * point = [[MKPointAnnotation alloc]init];
                point.coordinate=step.polyline.coordinate;
                point.title=step.instructions;
                point.subtitle=step.notice;
                [mapView addAnnotation:point];
                //將此段線路添加到地圖上
                [mapView addOverlay:step.polyline];
            }
        }
    }];  
}
//地圖覆蓋物的代理方法
-(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay{
    MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithPolyline:overlay];
    
    renderer.strokeColor = [UIColor redColor];
    
    renderer.lineWidth = 4.0;
    
    return  renderer;
}
//標註的代理方法
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
    MKPinAnnotationView * view= [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:@"anno"];
    view.canShowCallout=YES;
    return view;
}

效果以下:

2、附近興趣點檢索

興趣點檢索的邏輯和導航線路檢索的邏輯類似,直接經過代碼來演示:

    //建立一個位置信息對象,第一個參數爲經緯度,第二個爲緯度檢索範圍,單位爲米,第三個爲經度檢索範圍,單位爲米
    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(tocoor, 5000, 5000);
    //初始化一個檢索請求對象
    MKLocalSearchRequest * req = [[MKLocalSearchRequest alloc]init];
    //設置檢索參數
    req.region=region;
    //興趣點關鍵字
    req.naturalLanguageQuery=@"hotal";
    //初始化檢索
    MKLocalSearch * ser = [[MKLocalSearch alloc]initWithRequest:req];
    //開始檢索,結果返回在block中
    [ser startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) {
        //興趣點節點數組
        NSArray * array = [NSArray arrayWithArray:response.mapItems];
        for (int i=0; i<array.count; i++) {
            MKMapItem * item=array[i];
            MKPointAnnotation * point = [[MKPointAnnotation alloc]init];
            point.title=item.name;
            point.subtitle=item.phoneNumber;
            point.coordinate=item.placemark.coordinate;
            [mapView addAnnotation:point];
        }
    }];

效果以下:

 

若是疏漏 歡迎指正

學習使用 歡迎轉載

專一技術,熱愛生活,交流技術,也作朋友。

——琿少 QQ羣:203317592

相關文章
相關標籤/搜索