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

    大功告成,以上代码有什么问题,或者哪位朋友有好的建议或方法,请留下您的痕迹!希望这篇博文能对广大朋友有所帮助!

  • 相关阅读:
    readelf的使用,看函数地址
    Linux 打印堆栈和crash地址转换
    Android mk 添加打印信息
    Linux make file文件中常用的一些定义CPP CXX
    关于Android中RemoveView的错误理解
    Android悬浮窗注意事项
    在有EditText控件的AlertDialog对话框中自动弹出输入法
    联系旭日150安装CentOS5.X版本手记
    ListView配合CheckBox出现position位置错误的解决
    在Android中让Preference的宽度占满整个屏幕的宽度
  • 原文地址:https://www.cnblogs.com/boyuanmeng/p/3872670.html
Copyright © 2020-2023  润新知