iOS 百度地圖獲取地理位置名稱

         目前不少的應用都用到了百度地圖這一版本,不過有些方法是我在網上並無找到的,可是這並不意味着就沒有相關的文章介紹,那麼這裏我所記錄的就是百度地圖獲取地理位置,以及省份,城市,區域,其餘的很少說了,直接進入正題吧: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");
    }
}

大功告成,以上代碼有什麼問題,或者哪位朋友有好的建議或方法,請留下您的痕跡!但願這篇博文能對廣大朋友有所幫助!

相關文章
相關標籤/搜索