目前不少的應用都用到了百度地圖這一版本,不過有些方法是我在網上並無找到的,可是這並不意味着就沒有相關的文章介紹,那麼這裏我所記錄的就是百度地圖獲取地理位置,以及省份,城市,區域,其餘的很少說了,直接進入正題吧:php
建立地圖基本圖層git
首先,須要到http://dev.baidu.com/wiki/imap/index.php?title=iOS平臺/相關下載下載所有內容,包括文檔,示例代碼和開發包。api
而後獲取本身的API KEY,具體方法按百度的官網申請就行,比較簡單。緩存
下載的文件應該有三個網絡
把inc文件夾拖入到項目中去,引入了頭文件,而後若是用真機就把Release-iphoneos裏面的.a文件拖拽到項目中去,最後別忘了拖入mapapi.bundle文件,路線節點和圖釘的圖片來源於素材包。app
此 外還要引入CoreLocation.framework和QuartzCore.framework,這樣引入工做就大功告成,可是要注意一點 很重要的,靜態庫中採用ObjectC++實現,所以須要保證工程中至少有一個.mm後綴的源文件(您能夠將任意一個.m後綴的文件更名爲.mm),或者 在工程屬性中指定編譯方式,即將XCode的Project -> Edit Active Target -> Build -> GCC4.2 – Language -> Compile Sources As設置爲」Objective-C++」。框架
經 過實踐,我推薦不這麼幹,默認是根據文件類型來選擇編譯的方式,文件要是.m就用Objective-C,要是.mm就是Objective- C++,手動改變會讓整個項目都用一種編譯方式,很容易出錯或者不兼容,好比NavigationItem實例化的時候就會出錯,既然百度地圖如此特立獨 行,那麼最好的方式就是把地圖相關的類改成.mm,其餘的依舊,這樣只有這個類會用Objective-C++編譯方式。iphone
顯示地圖ide
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 要使用百度地圖,請先啓動BaiduMapManager _mapManager = [[BMKMapManager alloc]init]; // 若是要關注網絡及受權驗證事件,請設定generalDelegate參數 BOOL ret = [_mapManager start:@"C5DCEBF3F591FCB69EE0A0B9B1BB4C948C3FA3CC" generalDelegate:nil]; if (!ret) { NSLog(@」manager start failed!」); } self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; // Override point for customization after application launch. self.viewController = [[[ViewController alloc] initWithNibName:@」ViewController」 bundle:nil] autorelease]; self.window.rootViewController = self.viewController; [self.window makeKeyAndVisible]; return YES; }
固然,這僅僅是個準備工做,還不可以讓地圖圖層顯示出來:函數
//建立一張百度地圖 myMapView=[[BMKMapView alloc] initWithFrame:CGRectMake(0, 64, WIDTH,HEIGHT-44-64)]; [myMapView setMapType:BMKMapTypeStandard]; myMapView.delegate=self; myMapView.zoomLevel=17;//地圖級別 myMapView.showsUserLocation=YES;//能夠顯示用戶位置 [self.view addSubview:myMapView];
這幾句話寫完後,地圖就能正常顯示,不過值得注意的就是key值,不少時候因爲key值的緣由致使地圖沒法正常顯示!
在地圖使用完成後,記得要釋放,不然會影響內存的管理制度:
-(void)viewWillAppear:(BOOL)animated { [btnBack setHidden:NO]; [btnAddressType setHidden:NO]; [myMapView viewWillAppear]; myMapView.delegate = self; // 此處記得不用的時候須要置nil,不然影響內存的釋放 _search.delegate=self;//BMKSearch的協議 } -(void)viewWillDisappear:(BOOL)animated { [btnBack setHidden:YES]; [btnAddressType setHidden:YES]; [myMapView viewWillDisappear]; myMapView.delegate = nil; // 不用時,置nil _search.delegate=nil; }
圖層成功顯示後,接下來就是要獲取地址位置的名稱了。簡單的說就是反地理編碼:
//開始定位 -(void)mapViewWillStartLocatingUser:(BMKMapView *)mapView{ NSLog(@"開始定位"); } /** *用戶位置更新後,會調用此函數 *@param mapView 地圖View *@param userLocation 新的用戶位置 */ -(void)mapView:(BMKMapView *)mapView didUpdateUserLocation:(BMKUserLocation *)userLocation{ NSLog(@"latitude--%f,longtitude---%f",userLocation.location.coordinate.latitude,userLocation.location.coordinate.longitude); locaLatitude=userLocation.location.coordinate.latitude;//緯度 locaLongitude=userLocation.location.coordinate.longitude;//精度 BMKCoordinateRegion region; //將定位的點居中顯示 region.center.latitude=locaLatitude; region.center.longitude=locaLongitude; //反地理編碼出地理位置 CLLocationCoordinate2D pt=(CLLocationCoordinate2D){0,0}; pt=(CLLocationCoordinate2D){locaLatitude,locaLongitude}; BOOL flag=[_search reverseGeocode:pt]; if (flag) { myMapView.showsUserLocation=NO;//不顯示本身的位置 self.btnDone.enabled=YES; } //當前位置標註和地圖的比例(註釋爲可不用) // BMKCoordinateSpan spans; // spans.latitudeDelta=0.01; // spans.longitudeDelta=0.01; // region.span=spans; myMapView.region=region; }
在使用[_search reverseGeocode:pt]的時候,會調用它的一個協議方法,也就是下面的方法:
//反地理編碼 -(void)onGetAddrResult:(BMKAddrInfo *)result errorCode:(int)error{ if (error==0) { BMKPointAnnotation *item=[[BMKPointAnnotation alloc] init]; item.coordinate=result.geoPt;//地理座標 item.title=result.strAddr;//地理名稱 [myMapView addAnnotation:item]; myMapView.centerCoordinate=result.geoPt; self.lalAddress.text=[result.strAddr stringByReplacingOccurrencesOfString:@"-" withString:@""]; if (![self.lalAddress.text isEqualToString:@""]) { strProvince=result.addressComponent.province;//省份 strCity=result.addressComponent.city;//城市 strDistrict=result.addressComponent.district;//地區 } // CLGeocoder *geocoder=[[CLGeocoder alloc] init]; // CLGeocodeCompletionHandler handle=^(NSArray *palce,NSError *error){ // for (CLPlacemark *placemark in palce) { // NSLog(@"%@1-%@2-%@3-%@4-%@5-%@6-%@7-%@8-%@9-%@10-%@11-%@12",placemark.name,placemark.thoroughfare,placemark.subThoroughfare,placemark.locality,placemark.subLocality,placemark.administrativeArea,placemark.postalCode,placemark.ISOcountryCode,placemark.country,placemark.inlandWater,placemark.ocean,placemark.areasOfInterest); // break; // } // }; // CLLocation *loc = [[CLLocation alloc] initWithLatitude:locaLatitude longitude:locaLongitude]; // [geocoder reverseGeocodeLocation:loc completionHandler:handle]; } }
這樣我所獲取的地理位置名稱,省份,城市,地區就能成功顯示出來,到這裏,就已經大功告成!
不過,有發現上面代碼中被註釋掉的部分嗎?這一部分代碼的功能也是可以獲取到省份,城市,地區的,只不過CLGeocoder是CoreLocation系統框架中的定位,應該說是谷歌定位吧,百度地圖的經緯度有誤差,因此定位的位置和實際位置有所不一樣。再者,CLGeocoder所定位出來的內容有很大一部分爲空,我還未找到緣由所在,但願知道的朋友可以爲我解決這一煩惱啊!在此先謝過了!
到這裏,記錄尚未完呢!想要優化一下標註的效果吧,就看下面的代碼吧:
- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id <BMKAnnotation>)annotation{ // 生成重用標示identifier NSString *AnnotationViewID = @"xidanMark"; // 檢查是否有重用的緩存 BMKAnnotationView* annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID]; // 緩存沒有命中,本身構造一個,通常首次添加annotation代碼會運行到此處 if (annotationView == nil) { annotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID]; ((BMKPinAnnotationView*)annotationView).pinColor = BMKPinAnnotationColorRed; // 設置重天上掉下的效果(annotation) ((BMKPinAnnotationView*)annotationView).animatesDrop = YES; } // 設置位置 annotationView.centerOffset = CGPointMake(0, -(annotationView.frame.size.height * 0.5)); annotationView.annotation = annotation; // 單擊彈出泡泡,彈出泡泡前提annotation必須實現title屬性 annotationView.canShowCallout = YES; // 設置是否能夠拖拽 annotationView.draggable = NO; return annotationView; }
附加一個長按事件吧!
//地圖長按事件 -(void)mapview:(BMKMapView *)mapView onLongClick:(CLLocationCoordinate2D)coordinate{ //長按以前刪除全部標註 NSArray *arrayAnmation=[[NSArray alloc] initWithArray:myMapView.annotations]; [myMapView removeAnnotations:arrayAnmation]; //獲得經緯度 locaLatitude=coordinate.latitude; locaLongitude=coordinate.longitude; CLLocationCoordinate2D pt=(CLLocationCoordinate2D){0,0}; pt=(CLLocationCoordinate2D){coordinate.latitude,coordinate.longitude}; BOOL flag= [_search reverseGeocode:pt]; if (flag) { NSLog(@"success"); }else{ NSLog(@"falied"); } }
大功告成,以上代碼有什麼問題,或者哪位朋友有好的建議或方法,請留下您的痕跡!但願這篇博文能對廣大朋友有所幫助!