開篇
最近寫簡(jiǎn)書不多,除了前段時(shí)間一篇匆匆的FFMPEG的理論學(xué)習(xí)基本沒(méi)寫多少,主要是最近比較忙,又是硬件設(shè)備的調(diào)試,又是新需求的加入,今天就來(lái)寫一下項(xiàng)目中的一個(gè)知識(shí),閑話少敘直入正題吧。
百度地圖的使用
百度地圖API的導(dǎo)入網(wǎng)上說(shuō)了許多坑,不過(guò)我遇到的比較少,這里就放兩個(gè)比較常見(jiàn)的吧。
坑一:
如上圖所示,在infoplist里加入這個(gè)字段,而且這里還可以設(shè)置提示的內(nèi)容。不加的話,嘿嘿嘿,期待你的嘗試。
坑二:如下圖
導(dǎo)入百度地圖API運(yùn)行之后報(bào)上圖錯(cuò)誤大約18到20個(gè)左右,解決方法添加libstdc++.6.0.9 的庫(kù)。
填完坑之后看一下我們今天要演示的效果吧。
這里實(shí)現(xiàn)的內(nèi)容就是在定位到的當(dāng)前城市內(nèi)的路徑規(guī)劃,實(shí)現(xiàn)駕車,公交,步行三種規(guī)劃方式。
注意要點(diǎn):
這里我們采用的是地點(diǎn)到地點(diǎn)之間的路徑規(guī)劃,所以我們?cè)诓樵兊倪^(guò)程中一定要設(shè)置查詢的城市,不然無(wú)法查找成功(當(dāng)然也可以用經(jīng)緯度的方式,那就另說(shuō)了)。
方式切換問(wèn)題,如果我們想要像上圖所示的不同路徑規(guī)劃間的切換,我們要注意的就是地圖上已經(jīng)存在的路線軌跡和標(biāo)注的清除問(wèn)題。
我們?cè)诓煌瑮l件下規(guī)劃路徑要注意他們是不同的查詢方法,以及他們不同的協(xié)議方法,這個(gè)我們可以具體點(diǎn)進(jìn)百度地圖靜態(tài)庫(kù)的方法去查看。
代碼的實(shí)現(xiàn)
由于在項(xiàng)目中,并沒(méi)有整理出來(lái),這里我們就貼一些主要的代碼。
因?yàn)槿N路徑規(guī)劃其實(shí)原理一致這里我們以駕車的路徑規(guī)劃做一個(gè)例子。
因?yàn)橐櫦暗皆诖酥笆欠裼熊壽E和標(biāo)注因此我們要先做清除處理,代碼如下
[_mapView removeOverlays:_mapView.overlays];
NSArray *annArray = [[NSArray alloc]initWithArray:_mapView.annotations];
[_mapView removeAnnotations: annArray];
之后我們創(chuàng)建路徑規(guī)劃的方法
_searcher = [[BMKRouteSearch alloc]init];
_searcher.delegate = self;
//發(fā)起檢索
BMKPlanNode* start = [[BMKPlanNode alloc]init] ;
start.name = _startFiled.text;
BMKPlanNode* end = [[BMKPlanNode alloc]init];
end.name = _endFiled.text;
start.cityName = self.city;
end.cityName = self.city;
BMKDrivingRoutePlanOption *driveRouteSearchOption =[[BMKDrivingRoutePlanOption alloc]init];
driveRouteSearchOption.from = start;
driveRouteSearchOption.to = end;
這里要注意的就是因?yàn)槲覀兪邱{車路徑規(guī)劃,所以創(chuàng)建的是BMKDrivingRoutePlanOption,我們進(jìn)入到內(nèi)部方法可以看到,入過(guò)我們是公交和步行對(duì)應(yīng)的則是他們各自的Option,發(fā)起檢索成功后會(huì)調(diào)取他的協(xié)議方法,這里的前提是要遵循BMKRouteSearchDelegate協(xié)議
- (void)onGetDrivingRouteResult:(BMKRouteSearch*)searcher result:(BMKDrivingRouteResult*)result errorCode:(BMKSearchErrorCode)error
在上述的協(xié)議方法中,我們?cè)O(shè)置起點(diǎn),終點(diǎn),以及路段入口信息和各軌跡點(diǎn)的總數(shù)
for (int i = 0; i < size; i++) {
BMKDrivingStep *tansitStep = [plan.steps objectAtIndex:i];
if (i == 0 ) {
BMKPointAnnotation* annotation = [[BMKPointAnnotation alloc]init];
annotation.coordinate = plan.terminal.location;
annotation.title = @"起點(diǎn)";
[_mapView addAnnotation:annotation];
} else if (i == size - 1) {
BMKPointAnnotation* annotation = [[BMKPointAnnotation alloc]init];
annotation.coordinate = plan.terminal.location;
annotation.title = @"終點(diǎn)";
[_mapView addAnnotation:annotation];
}
BMKPointAnnotation* annotation = [[BMKPointAnnotation alloc]init];
annotation.coordinate = tansitStep.entrace.location; //路段入口信息
annotation.title = tansitStep.instruction; //路程換成說(shuō)明
[_mapView addAnnotation:annotation];
//軌跡點(diǎn)總數(shù)累計(jì)
planPointCounts += tansitStep.pointsCount;
}
//軌跡點(diǎn)
BMKMapPoint * temppoints = new BMKMapPoint[planPointCounts]; //文件后綴名改為mm
int i = 0;
for (int j = 0; j < size; j++) {
BMKTransitStep *transitStep = [plan.steps objectAtIndex:j];
int k = 0;
for (k = 0; k < transitStep.pointsCount; k++) {
temppoints[i].x = transitStep.points[k].x;
temppoints[i].y = transitStep.points[k].y;
i++;
}
}
//通過(guò)points構(gòu)建BMKPolyline
BMKPolyline *polyLine = [BMKPolyline polylineWithPoints:temppoints count:planPointCounts];
[_mapView addOverlay:polyLine]; //添加路線overlay
delete []temppoints;
[self mapViewFitPolyLine:polyLine];
這樣我們就完成了路徑規(guī)劃的主要設(shè)置。
POI檢索
百度地圖提供了詳細(xì)的POI檢索,如下圖我們?cè)O(shè)置一個(gè)界面選擇我們想要檢索的內(nèi)容,然后根據(jù)我們選擇的內(nèi)容去在地圖上標(biāo)記處各個(gè)對(duì)應(yīng)的點(diǎn),并顯示出他的詳細(xì)信息。然后我們點(diǎn)擊具體的cell,然后我們根據(jù)模型中的數(shù)據(jù)地點(diǎn)或者經(jīng)緯度,可以規(guī)劃處我們所在地到目的地的線路規(guī)劃,一樣有駕車,公交,步行,三種。這里不得不吐槽一下為啥那么多電話都沒(méi)有嘞。
我們要進(jìn)行POI檢索,首先要遵循BMKPoiSearchDelegate協(xié)議,然后進(jìn)行檢索
_searcher2 =[[BMKPoiSearch alloc]init];
_searcher2.delegate = self;
//發(fā)起檢索
BMKNearbySearchOption *option = [[BMKNearbySearchOption alloc]init];
option.pageIndex = 1; //當(dāng)前索引頁(yè)
option.pageCapacity = 10; //分頁(yè)量
option.location = CLLocationCoordinate2DMake(self.lat2, self.lon2);
option.keyword = self.str;
option.radius = 3000;
BOOL flag = [_searcher2 poiSearchNearBy:option];
if(flag)
{
NSLog(@"周邊檢索發(fā)送成功");
}
else
{
NSLog(@"周邊檢索發(fā)送失敗");
}
檢索成功后會(huì)走到協(xié)議方法
- (void)onGetPoiResult:(BMKPoiSearch*)searcher result:(BMKPoiResult*)poiResultList errorCode:(BMKSearchErrorCode)error
在這里我們得到了包含詳細(xì)信息的一個(gè)數(shù)組,然后我們?nèi)〕鯞MKPoiInfo對(duì)象中的uid,去進(jìn)行詳細(xì)檢索,同時(shí)并把它轉(zhuǎn)換為一個(gè)model,去創(chuàng)建我們的tableview,然后把得到的對(duì)應(yīng)數(shù)據(jù)展示到下半部的列表中,在點(diǎn)擊tableview的詳細(xì)事件中進(jìn)行傳值,實(shí)現(xiàn)路線的規(guī)劃。model中的部分屬性如下:
@interface GSMapModel : NSObject
///POI名稱
@property (nonatomic, strong) NSString* name;
///POIuid
@property (nonatomic, strong) NSString* uid;
///POI地址
@property (nonatomic, strong) NSString* address;
///POI所在城市
@property (nonatomic, strong) NSString* city;
///POI電話號(hào)碼
@property (nonatomic, strong) NSString* phone;
///POI郵編
@property (nonatomic, strong) NSString* postcode;
詳情檢索對(duì)應(yīng)的協(xié)議方法
//搜索的詳細(xì)結(jié)果
- (void)onGetPoiDetailResult:(BMKPoiSearch*)searcher result:(BMKPoiDetailResult*)poiDetailResult errorCode:(BMKSearchErrorCode)errorCode{
if (errorCode == BMK_SEARCH_NO_ERROR) {
//在此處理正常結(jié)果
}
else if (errorCode == BMK_SEARCH_AMBIGUOUS_KEYWORD){
//當(dāng)在設(shè)置城市未找到結(jié)果,但在其他城市找到結(jié)果時(shí),回調(diào)建議檢索城市列表
// result.cityList;
NSLog(@"起始點(diǎn)有歧義");
} else {
NSLog(@"抱歉,未找到結(jié)果");
}
大頭針的自定義
我們想要自己定義我們想要看到的大頭針模樣,就要對(duì)他進(jìn)行自定義。下面介紹一種簡(jiǎn)單的處理大頭針樣式的方法,如果想要具體的根據(jù)不同的情形來(lái)進(jìn)行自定義,就要進(jìn)行判斷,根據(jù)他們不同的情況去給定相應(yīng)的標(biāo)注圖片
- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id<BMKAnnotation>)annotation{
BMKPinAnnotationView *newAnnotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"myAnnotation"];
newAnnotationView.pinColor = BMKPinAnnotationColorPurple;
newAnnotationView.animatesDrop = NO;// 設(shè)置該標(biāo)注點(diǎn)動(dòng)畫顯示
newAnnotationView.annotation=annotation;
newAnnotationView.image = [UIImage imageNamed:@"mapicon"]; //把大頭針換成別的圖片
newAnnotationView.size = CGSizeMake(20, 33);
return newAnnotationView;
}
后記
地圖中我們用的比較多的就是定位,POI檢索和路徑規(guī)劃了,定位的話,相信不管是官方SDK還是網(wǎng)上各種資料都?jí)蛟敿?xì)的了,我就不再重復(fù)了,這里主要對(duì)路徑規(guī)劃和POI檢索做出說(shuō)明,希望對(duì)大家有所幫助。
補(bǔ)充內(nèi)容
今天有小伙伴問(wèn)看了文章想知道百度地圖的模糊搜索是怎么做的,輸入地名就能自動(dòng)聯(lián)想好厲害的樣子,這里就補(bǔ)充一下吧,其實(shí)也是POI搜索的一部分,是城市內(nèi)搜索根據(jù)輸入的地名發(fā)起搜索,然后把搜索內(nèi)容展示到tableview上罷了。如下圖:
當(dāng)我們改變輸入框的內(nèi)容時(shí)其實(shí)內(nèi)部的操作是什么呢,下面我們一點(diǎn)點(diǎn)介紹一下他。
這里我們要做的是POI檢索,因此首先要遵循BMKPoiSearchDelegate協(xié)議,創(chuàng)建搜索的代碼如下:
_poisearcher = [[BMKPoiSearch alloc]init];
_poisearcher.delegate = self;
BMKCitySearchOption *citySearchOption = [[BMKCitySearchOption alloc]init];
citySearchOption.pageIndex = 0;
citySearchOption.pageCapacity = 20;
citySearchOption.city= self.city;
citySearchOption.keyword = _inputFiled.text;
成功之后會(huì)走下面這個(gè)協(xié)議方法
-(void)onGetPoiResult:(BMKPoiSearch *)searcher result:(BMKPoiResult *)poiResult errorCode:(BMKSearchErrorCode)errorCode
這里我們就得到了返回的內(nèi)容,然后把它里面的數(shù)據(jù)取到轉(zhuǎn)換為模型展示到tableview上就好了,但是,為什么是但是呢,因?yàn)槟氵@樣做并不能得到想要的結(jié)果,因?yàn)槟氵@里做的檢索只是一次的,并不能實(shí)現(xiàn)每改變一個(gè)字就重新檢索展示出地點(diǎn),我們要對(duì)輸入框做處理
[_inputFiled addTarget:self action:@selector(inputaction:) forControlEvents:UIControlEventEditingChanged];
添加事件,實(shí)現(xiàn)對(duì)輸入框變化的監(jiān)聽,然后實(shí)現(xiàn)方法。
#pragma mark - 輸入框的實(shí)時(shí)監(jiān)聽
-(void)inputaction:(UITextField *)textField{
[self performSelector:@selector(delay) withObject:self afterDelay:0.5];
}
這里我們監(jiān)聽輸入框的變化,然后把相應(yīng)的檢索寫到delay方法中就可以了。這樣就實(shí)現(xiàn)了數(shù)據(jù)的展示,然后點(diǎn)擊對(duì)應(yīng)的cell的時(shí)候,把數(shù)據(jù)傳給上個(gè)界面接Ok了啊,這里為了用戶體驗(yàn)我們可以監(jiān)聽tableview的滾動(dòng),當(dāng)滾動(dòng)的時(shí)候讓輸入框的鍵盤消失,代碼如下:
#pragma mark -滾動(dòng)隱藏鍵盤
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
[self.view endEditing:YES];
}
這樣我們就實(shí)現(xiàn)了模糊搜索了,是不是還是比較簡(jiǎn)單的。有別的問(wèn)題以后再接著補(bǔ)充吧。