码迷,mamicode.com
首页 > 移动开发 > 详细

IOS百度地图使用基础指南+原生分享&友盟分享

时间:2015-09-19 01:05:53      阅读:662      评论:0      收藏:1      [点我收藏+]

标签:

1.地图

1.获取用户的经纬度(CLLocationManager)

创建属性:CLLocationManager *mgr;

遵守协议:<CLLocationManagerDelegate>

 a>创建定位管理器

self.mgr = [[CLLocationManager alloc] init];

 b>设置代理

self.mgr.delegate = self;

 c>开始定位

[self.mgr startUpdatingLocation];

代理方法:

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{

    //获取用户的位置

    CLLocation *local = [locations firstObject]; 

    //停止定位

//    [self.mgr stopUpdatingLocation];

    CLLocationCoordinate2D coordinate = local.coordinate;

    NSLog(@"纬度:%f,经度:%f",coordinate.latitude,coordinate.longitude);   

}

 2.计算两个经纬度之间的距离

   //拿到两个点

    CLLocation *lcoal1 = [[CLLocation alloc] initWithLatitude:39.54 longitude:116.28];

    CLLocation *local2 = [[CLLocation alloc] initWithLatitude:22.27 longitude:113.46];

    //开始计算距离

    CLLocationDistance distance = [local2 distanceFromLocation:lcoal1];

    NSLog(@"北京到深圳的距离是:%f",distance);


3.地理编码与反编码

3.1地里编码

    a>初始化地理编码类对象

CLGeocoder *geo = [[CLGeocoder alloc] init];

    b>通过地址名称,获得地标数组(一个名称,多个地址)

    //开始地理编码

    [geo geocodeAddressString:self.addressField.text completionHandler:^(NSArray *placemarks, NSError *error) { 

        if (placemarks.count == 0 || error) return;

        

        //获取地标 

        NSLog(@"%lu",(unsigned long)placemarks.count); 

        NSString *temp = @""

        for (CLPlacemark *pm in placemarks) { 

            CLLocationCoordinate2D coordinate = pm.location.coordinate;

          //纬度 coordinate.latitude;

          //经度  coordinate.longitude;

//同名的 多个地址追加

 temp = [temp stringByAppendingString:[NSString stringWithFormat:@"%@\n",pm.name]];

 

 }

}];

  1. c>地标对象(CLPlacemark)封装了经纬度,国家,街道等地址信息

CLPlacemark 属性图如下


CLLocation *location;

CLRegion *region;



3.2反地理编码

              a>初始化地理编码对象

CLGeocoder *geo = [[CLGeocoder alloc] init];

              b>初始化经纬度定位对象(CLLocation)


CLLocation *local = [[CLLocation alloc]      initWithLatitude:[self.latitudeField.text floatValue] longitude:[self.longitudeField.text floatValue]];

             c>传入CLLocation,获得地标

    

    [geo reverseGeocodeLocation:local completionHandler:^(NSArray *placemarks, NSError *error) {

         //获取地标

        CLPlacemark *pm = [placemarks firstObject];

        self.addressDetail.text = pm.name;

   

 }];

4.MapKit地图的基本展示

需要:

        1.导入头文件 #import <MapKit/MapKit.h>

      2.导入framework   MapKit

4.1简单的地图显示

a>自定义-简单的地图展示

    MKMapView *mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];

self.view = mapView;

4.2 Map视图控制器的使用

     a>使用视图控制器,遵守协议。使用代理< MKMapViewDelegate>


IBOutlet MKMapView *mapView;

//是否显示用户位置

self.mapView.showsUserLocation = YES;

//地图类型

    /**

     *  MKMapTypeStandard = 0, 标准地图

     MKMapTypeSatellite,    卫星

     MKMapTypeHybrid    混合地图

     */

 self.mapView.mapType = MKMapTypeHybrid;


    b>通过代理方法,更新用户位置

-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{

  

//设置地图展示范围setRegion : coordinate & span

    [self.mapView setRegion:MKCoordinateRegionMake(userLocation.location.coordinate, MKCoordinateSpanMake(5.067069, 3.835159))];

   // 通过经纬度获得地标。 

CLGeocoder *geo = [[CLGeocoder alloc] init];

[geo reverseGeocodeLocation:userLocation.location completionHandler:^(NSArray *placemarks, NSError *error) {

  //获取地标

        CLPlacemark *pm = [placemarks firstObject];

        userLocation.title = pm.country;

        userLocation.subtitle = pm.name;

}];

 

}


/**

 *  当地图显示的范围发生改变的时候

 *

 */

-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{

    

    NSLog(@"维度的跨度:%f,经度的跨度:%f",mapView.region.span.latitudeDelta,mapView.region.span.longitudeDelta);

}

4.3 IOS8.0+ 中的地图设置

判断设备系统版本

if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {

        [self.mgr requestAlwaysAuthorization];

    }



//跟踪用户位置(iOS8,地图会自动设置一个合适的显示范围)

    self.mapView.userTrackingMode = MKUserTrackingModeFollow;

5.大头针

IOS8中,显示用户的大头针,需要先定位


5.1在地图添加大头针

    a>使用Map视图控制器

    b>创建大头针,设置相关属性


MyAnnotation *anno = [[MyAnnotation alloc] init];

 //设置大头针的title

anno.title = @"北京";

anno.subtitle = @"中国";

//设置添加大头针的位置

anno.coordinate = CLLocationCoordinate2DMake(39.54, 116.28);


  1. c>将大头针显示到地图视图

[self.mapView addAnnotation:anno];

//添加多个大头针

[self.mapView addAnnotations:@[anno,anno1]];


5.2 touch每点击地图添加大头针

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    

    //1.获取屏幕上的点

    CGPoint p = [[touches anyObject] locationInView:self.mapView];

    //2.把点转化为经纬度

    CLLocationCoordinate2D coordinate = [self.mapView convertPoint:p toCoordinateFromView:self.mapView];

    

    //3.添加大头针

    MyAnnotation *anno = [[MyAnnotation alloc] init];

    

    //设置大头针的title

    anno.title = @"北京";

    anno.subtitle = @"中国";

    

    //设置添加大头针的位置

    anno.coordinate = coordinate;

    

    [self.mapView addAnnotation:anno];

   

}


5.3 大头针触发的代理方法

-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{

// 如果是系统添加大头针的操作,则返回nil,仍然是系统的 圆点大头针

// 如果是自定义的大头针。继续执行

    if ([annotation isKindOfClass:[MKUserLocation class]]) {

        return nil;

    }

    

    //如果返回空,就是用系统自带的大头针

//    return nil;


//这里是 自定义大头针 的设置

    static NSString *ID = @"anno";

    MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:ID];

    

    if (annotationView == nil) {

        annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:ID];

    

    }

    

    //设置大头针的颜色

    annotationView.pinColor = MKPinAnnotationColorPurple;

    

    //设置大头针的动画

    annotationView.animatesDrop = YES;

    

// 返回大头针 视图

    return annotationView;

    

}

5.4 自定义大头针的视图

思路:每次在对大头针操作的时候 会触发代理方法,代理方法 返回一个大头针的视图对象。如果 重新定义一个大头针对象返回,则可以 达到自定义大头针显示的目的。

    a>定义类,继承大头针类

    b>重写类属性

    c>viewForAnnotation代理方法中创建自定义大头针类对象

// 添加大头针后 执行这个方法

-(void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views{

    

    // 可以同过遍历views,设置初始位置,设置动画

    for (UIView *view2 in views) {

        CGRect rec = view2.frame;

view2.frame = CGRectMake(rec.origin.x, 0, rec.size.width, rec.size.height);

        [UIView animateWithDuration:1.0 animations:^{

           

            view2.frame = rec;

        }];

        

    }

    

}

思路2:直接在代理方法中,给大头针设置图片img

annotationView.image = [UIImage imageNamed:@"category_3"];

6.使用系统自带导航

流程:

用户输入需要去的位置,

通过位置计算地标,地标转地图标记,地图标记转地图item

获取当前用户的item。开启导航。


    a>初始化地理编码类

CLGeocoder *geo = [[CLGeocoder alloc] init];

    b>通过地址拿到地标

[geo geocodeAddressString:self.destinationField.text completionHandler:^(NSArray *placemarks, NSError *error) {

// 需要处理没有 地标的情况

       if (placemarks.count == 0 || error) return

        //地理编码后拿到地标

        CLPlacemark *pm = [placemarks firstObject];

        

        //创建MKPlacemark

        MKPlacemark *mkp = [[MKPlacemark alloc] initWithPlacemark:pm];

        //目的地Item

        MKMapItem *destinationItem = [[MKMapItem alloc] initWithPlacemark:mkp];

        

        //用户当前的item

        MKMapItem *currentItem = [MKMapItem mapItemForCurrentLocation];

        

        

        //2.开启导航

        NSDictionary *option = @{MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving,/*驾车*/

    MKLaunchOptionsMapTypeKey:@0,      /*地图类型 0标准,1卫星,2混合*/

    MKLaunchOptionsShowsTrafficKey:@NO /*交通状况*/

                                 

          };

        

        [MKMapItem openMapsWithItems:@[currentItem,destinationItem] launchOptions:option];

    }];


6.1自定义画线

通过目标位置,用户当前位置行程画线

在上节中已经有了获得目标位置item的方法

info : NSLocatonAlwaysUsageDescription

-(void)startDrawLineWithDestinationItem:(MKMapItem *)desItem userItem:(MKMapItem *)userItem{

    

    //1.创建一个路线请求

    MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];

    

    //2.设置起点

    request.source = userItem;

    

    //3.设置终点

    request.destination = desItem;

    

    //4.创建一个路线管理器

    MKDirections *direction = [[MKDirections alloc] initWithRequest:request];

    

    //5.画线

    //5.1算路

    [direction calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {

        

        //5.2遍历请求响应后的路线

        for (MKRoute *route in response.routes) {

            

            //5.3拿到画在地图上的线

            MKPolyline *line = route.polyline;

            

            //5.4把线添加到地图上

            [self.mapView addOverlay:line];

       }

   }];

  }


// 渲染线段的代理方法

-(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay{

    

    //创建渲染器

    MKPolylineRenderer *render = [[MKPolylineRenderer alloc]initWithOverlay:overlay];

    

    //设置线段的颜色

    render.strokeColor = [UIColor redColor];

    

    //设置线宽

    render.lineWidth = 5;

    

    

    

    return render;

    

    

}

7.自定义导航提示框

已知,当点击大头针的时候,可以显示设置的标题和小标题。

这里需求是,点击大头针,在大头针上显示信息框


点击大头针会触发didSelectAnnotationView 的代理方法

在这里添加 信息框,但是信息框不会跟随地图移动,它使相对于屏幕的。

所以信息框 也需要用大头针来做


当点击大头针,触发代理方法时,给mapView添加大头针,

这个大头针需要自定义大头针view.

添加大头针会触发viewForAnnotation 代理方法,在这个代理方法中

创建大头针view


所以现在的问题是怎样写它的大头针view


创建类,继承大头针view。在初始化方法中initWithFrame

初始化一个uiview,这个uiview返回一个xib(addsubview)



8.百度地图集成

1.导入组件

BaiduMapAPI.framework

  mapapi.bundle //  没导包会-> 引擎加载失败

MessageUI.framework

OpenGLES.framework

QuartzCore.framework

CoreLocation.framework

SystemConfiguration.framework

CoreGraphics.framework

Security.framework


appdelegate 声明全局的管理类static BMKMapManager * _manager;

2.开启百度地图管理

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    

    _manager = [[BMKMapManager alloc]init];

    BOOL ret =  [_manager start:@"XWkZFy5el0rx5PzVAVjfDF2k" generalDelegate:self];

    

    if (!ret) {

        NSLog(@"manager start failed");

    }

    

    

    return YES;

}


3.地图集成的状态判断协议方法:

- (void)onGetNetworkState:(int)iError{

    if (iError != 0) {

        NSLog(@"网络连接错误");

    }

}


/**

 *返回授权验证错误

 *@param iError 错误号 : 0时验证通过,具体参加BMKPermissionCheckResultCode

 */

- (void)onGetPermissionState:(int)iError{

    if (iError != 0) {

        NSLog(@"授权出错");

    }

}



组件中有c++程序,需要修改  ViewController.mm

4.创建百度地图

在创建的百度地图上 添加一个按钮

点击按钮 触发查找方法(调用百度POI)point of intersting


初始化地图,添加按钮

- (void)viewDidLoad {

    [super viewDidLoad];

    // 创建百度地图,添加到view

    BMKMapView * bdView = [[BMKMapView alloc]initWithFrame:self.view.bounds];

    

    self.mapView = bdView;

    

    

    [self.view addSubview:bdView];

    

    UIButton * btn = [[UIButton alloc]initWithFrame:CGRectMake(10, 10, 100, 30)];

    

    btn.backgroundColor = [UIColor redColor];

    [btn addTarget:self action:@selector(searchPOI) forControlEvents:UIControlEventTouchUpInside];

    

    [self.view addSubview:btn];

}


// 按钮点击方法

-(void)searchPOI{

    

    //创建POI

    

    

    BMKCitySearchOption *city = [[BMKCitySearchOption alloc]init];

    city.city = @"昌平区";

    city.keyword = @"电影院";

    city.pageIndex = 0; //分页索引,默认0

    city.pageCapacity = 50; //分页数

    

    

    BMKPoiSearch *searchRegin = [[BMKPoiSearch alloc]init];

    searchRegin.delegate = self;

    [searchRegin poiSearchInCity:city];

    

    

}

5.POI的代理方法

// 获得POI结果

-(void)onGetPoiResult:(BMKPoiSearch *)searcher result:(BMKPoiResult *)poiResult errorCode:(BMKSearchErrorCode)errorCode{

   

    NSLog(@"总结果数:%d",poiResult.totalPoiNum);

    for (BMKPoiInfo *info in poiResult.poiInfoList) {

        

        NSLog(@"[ %@ , %@ , %@ , %@ , %@ ]",info.name,info.uid,info.address,info.city,info.phone);

  

        // 添加大头针

        BMKPointAnnotation *anno = [[BMKPointAnnotation alloc]init];

        anno.coordinate = info.pt;

        anno.title = info.name;

        anno.subtitle = info.address;

        

        [self.mapView addAnnotation:anno];

        

    }

}




// 详细搜索

-(void)onGetPoiDetailResult:(BMKPoiSearch *)searcher result:(BMKPoiDetailResult *)poiDetailResult errorCode:(BMKSearchErrorCode)errorCode{

    

    NSLog(@".....BMKPoiDetailResult.....");

}



6.POI相关的搜索结果类


/*    ??BMKPoiResult

 ///本次POI搜索的总结果数

 @property (nonatomic) int totalPoiNum;

 ///当前页的POI结果数

 @property (nonatomic) int currPoiNum;

 ///本次POI搜索的总页数

 @property (nonatomic) int pageNum;

 ///当前页的索引

 @property (nonatomic) int pageIndex;

 ///POI列表,成员是BMKPoiInfo

 @property (nonatomic, strong) NSArray* poiInfoList;

 ///城市列表,成员是BMKCityListInfo

 @property (nonatomic, strong) NSArray* cityList;

 */



/*     ??BMKPoiInfo-poiInfoList

 ///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电话号码

 @property (nonatomic, strong) NSString* phone;

 ///POI邮编

 @property (nonatomic, strong) NSString* postcode;

 ///POI类型,0:普通点 1:公交站 2:公交线路 3:地铁站 4:地铁线路

 @property (nonatomic) int epoitype;

 ///POI坐标

 @property (nonatomic) CLLocationCoordinate2D pt;

 */



/*

 ///POI名称     ??BMKPoiDetailResult

 @property (nonatomic, strong) NSString* name;

 ///POI地址

 @property (nonatomic, strong) NSString* address;

 ///POI电话号码

 @property (nonatomic, strong) NSString* phone;

 ///POIuid

 @property (nonatomic, strong) NSString* uid;

 ///POI标签

 @property (nonatomic, strong) NSString* tag;

 ///POI详情页url

 @property (nonatomic, strong) NSString* detailUrl;

 ///POI所属分类,如“hotel”“cater”“life”

 @property (nonatomic, strong) NSString* type;

 ///POI地理坐标

 @property (nonatomic) CLLocationCoordinate2D pt;

 ///POI价格

 @property (nonatomic) double price;

 ///POI综合评分

 @property (nonatomic) double overallRating;

 ///POI口味评分

 @property (nonatomic) double tasteRating;

 ///POI服务评分

 @property (nonatomic) double serviceRating;

 ///POI环境评分

 @property (nonatomic) double environmentRating;

 ///POI设施评分

 @property (nonatomic) double facilityRating;

 ///POI卫生评分

 @property (nonatomic) double hygieneRating;

 ///POI技术评分

 @property (nonatomic) double technologyRating;

 ///POI图片数目

 @property (nonatomic) int imageNum;

 ///POI团购数目

 @property (nonatomic) int grouponNum;

 ///POI评论数目

 @property (nonatomic) int commentNum;

 ///POI收藏数目

 @property (nonatomic) int favoriteNum;

 ///POI签到数目

 @property (nonatomic) int checkInNum;

 ///POI营业时间

 @property (nonatomic, strong) NSString* shopHours;

 */

9.原生分享组件(新浪微博分享)

需要导入社会分享组件 Social.framework

导入头文件#import <Social/Social.h>

// 1. 首先需要判断 原生的分享组件  是否支持微博分享

    

    if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeSinaWeibo])

    {

        // 2.创建分享组件,分享的类型是:新浪微博

        SLComposeViewController *slview = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeSinaWeibo];

        

        // 3.分享的内容 与图片

        [slview setInitialText:@"分享的内容"];

        

        [slview addImage:[UIImage imageNamed:@"图片"]];

        

        

        // 4.模态框展示

        [self presentViewController:slview animated:YES completion:nil];

    }


10.友盟分享-(新浪微博分享组件)

10.1通过网页登陆授权


导入友盟SDK     UMSocial_Sdk_4.2.3

导入  SystemConfiguration.framework


  1. a>appdelegate设置

导入头文件 #import "UMSocial.h"


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    

    [UMSocialData setAppKey:@"55dece9767e58ea73900083b"];

    

    return YES;

}

  1. b>触发操作,分享

appKey:友盟appID

shareText:分享的内容

shareImage :分享的图片

shareToSnsNames:使用哪些组件分享

delegate:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{


 [UMSocialSnsService presentSnsController:self appKey:@"55dece9767e58ea73900083b" shareText:@"这里是分享的内容" shareImage:[UIImage imageNamed:@"UMS_comment_tap_white"] shareToSnsNames:@[UMShareToDouban,UMShareToEmail,UMShareToSina,UMShareToSms,UMShareToTwitter] delegate:nil];


}


10.2 通过SSO分享新浪微博

使用SSO新浪分享的前提是,必须有安装新浪微博客户端

  1. a>appdelegate设置

导入

   #import "UMSocialSinaHandler.h"


didFinishLaunchingWithOptions

// SSO 回调地址可以为空,使用此方法,必须处理回调

    // 还需 配置scheme sina.appkey

[UMSocialSinaHandler openSSOWithRedirectURL:nil];

 还需要提供回调页的处理方法

// 处理回调

-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{

    

    return [UMSocialSnsService handleOpenURL:url];

}


-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{

    return [UMSocialSnsService handleOpenURL:url];

}

  1. b>分享组件不变化

[UMSocialSnsService presentSnsController:self appKey:@"55dece9767e58ea73900083b" shareText:@"这里是分享的内容" shareImage:[UIImage imageNamed:@"UMS_comment_tap_white"] shareToSnsNames:@[UMShareToDouban,UMShareToEmail,UMShareToSina,UMShareToSms,UMShareToTwitter] delegate:nil];




11.地图定位不了,代理方法用不了的解决


  1. a>地理定位的授权


Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.

解决办法:

    1. 1.设置授权

[self.mgr requestAlwaysAuthorization];

    1. 2.设置info

NSLocationAlwaysUsageDescription

    1. 3.保持网络连接



个人总结。错误之处邮件联系


IOS百度地图使用基础指南+原生分享&友盟分享

标签:

原文地址:http://my.oschina.net/u/1184527/blog/508288

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!