iOS-原生地圖開發進階——使用導航和附近興趣點檢索
iOS中的mapKit框架對國際化的支援非常出色。在前些篇部落格中,對這個地圖框架的基礎用法和標註與覆蓋物的新增進行了詳細的介紹,這篇部落格將介紹兩個更加實用的功能的開發:線路導航與興趣點搜尋。前幾篇部落格的連結如下:
地圖基礎用法詳解:http://my.oschina.net/u/2340880/blog/415360。
新增大頭針與自定義標註:http://my.oschina.net/u/2340880/blog/415441。
新增地圖覆蓋物: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)MKMapItem
地點節點類,包含此節點的許多地點資訊,如下:
@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)MKDirectionsRequest
導航請求類
@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
看到上面如此多的類,你可能會覺得一頭霧水,那麼不用著急,類雖然繁雜,但他們之間的邏輯非常清晰,下面就通過一個例子來進行線路導航。
2、進行線路導航
- (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;
}
效果如下:
二、附近興趣點檢索
興趣點檢索的邏輯和導航線路檢索的邏輯相似,直接通過程式碼來演示:
//建立一個位置資訊物件,第一個引數為經緯度,第二個為緯度檢索範圍,單位為米,第三個為經度檢索範圍,單位為米
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];
}
}];
效果如下:
相關文章
- 【導航】資訊檢索
- ElasticSearch進階檢索Elasticsearch
- 【高階RAG技巧】使用二階段檢索器平衡檢索的效率和精度
- Blazor和Vue對比學習(進階.路由導航一):基本使用BlazorVue路由
- 小程式實現附近三公里搜尋和地圖路線導航(改版)地圖
- UWP 開發初階 Chapter 5 - 實現頁面導航,和頁面內部分割槽域導航APT
- win10資訊和興趣不見了怎麼辦 資訊和興趣開啟辦法Win10
- 百度地圖開發-在地圖上檢索資料 08地圖
- 張高興的 Raspberry Pi AI 開發指南:(二)使用 Python 和 HailoRT 進行實時目標檢測AIPython
- 產業園區智慧化導航地圖開發平臺,如何實現園區內地圖導航?產業地圖
- Android 進階路線(思維導圖)Android
- 抖音興趣電商,豈止於興趣
- ??Java開發者的Python快速進修指南:物件導向進階JavaPython物件
- Flutter開發之路由與導航Flutter路由
- 開發人員網站導航網站
- vue3和百度地圖關鍵字檢索 定位 點選定位Vue地圖
- 使用 Laravel 開發簡易的附近動態功能Laravel
- 有沒有在商場用的導航地圖?如何在商場內進行導航?地圖
- GraphRAG 檢索增強+圖模型模型
- 微博、虎牙挺進興趣社群:同行不同路
- 百度地圖開發-在地圖上實現路線導航 09地圖
- 《iOS之導航控制器的使用圖解》iOS圖解
- 高德地圖導航和路徑規劃地圖
- Flutter開發之導航與路由管理Flutter路由
- [Leetcode]303.區域和檢索&&304.二維區域和檢索LeetCode
- 微軟Windows 10 build 21354 新增"我的興趣"和其他功能的改進!微軟WindowsUI
- 使用 abortNavigation 阻止導航Navigation
- Flutter路由和導航Flutter路由
- 【從零開始擼一個App】Fragment和導航中的使用APPFragment
- PbootCMS導航選單-導航選單的使用教程boot
- 醫院內導航及智慧導醫,懶圖科技“院內導航地圖”為患者指路!地圖
- 如何給廠區做導航地圖?科技園區導航地圖服務地圖
- 導航欄點選選中
- 調查發現大部分遊戲開發者對NFT沒興趣遊戲開發
- 孟子小樣本和檢索式預訓練模型進展模型
- Django進階之路由層和檢視層Django路由
- 【iOS開發進階】-RunTimeiOS
- Web 開發進階指南Web
- ReactNative實現地圖導航React地圖