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


         目前很多的應用都用到了百度地圖這一版本,不過有些方法是我在網上並沒有找到的,但是這並不意味着就沒有相關的文章介紹,那么這里我所記錄的就是百度地圖獲取地理位置,以及省份,城市,區域,其他的不多說了,直接進入正題吧:

      創建地圖基本圖層

         首先,需要到http://dev.baidu.com/wiki/imap/index.php?title=iOS平台/相關下載下載全部內容,包括文檔,示例代碼和開發包。

         然后獲取自己的API KEY,具體方法按百度的官網申請就行,比較簡單。

         下載的文件應該有三個

         把inc文件夾拖入到項目中去,引入了頭文件,然后如果用真機就把Release-iphoneos里面的.a文件拖拽到項目中去,最后別忘了拖入mapapi.bundle文件,路線節點和圖釘的圖片來源於素材包。

        此 外還要引入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++編譯方式。

       顯示地圖

    - (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");
    }
}

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM