地图(定位、POI、地理编码……)

  iOS中的地图,有两种:

            1、苹果自带的地图SDK,(MKMapKit)但是它在中国使用时,内部还是使用的是高德地图。(高德为苹果在中国的地图合作方)

            2、第三方地图SDK  (例如:高德的地图SDK,( MAMapKit)、百度地图SDK(BMapKit))。


  

使用方法:
第一种,苹果自带的地图SDK:

 使用苹果自带的地图MKMapKit,需要导入框架:MapKit.frameworksCoreLocation.framework


         定位 

     

         目前iOS定位方式有三种:基站   WIFI  A-GPS

     

         基站:省电、定位不精准(大概位置)

         WIFI:和基站差不多,比基站更费电、定位不精准(大概位置)

         A-GPS:苹果改良了直接使用GPS,先使用基站和WIFI获得大概位置,然后苹果自动推荐当前区域的离你位置最近的GPS卫星,这样就不用再搜索卫星了,直接就可以使用了。费电、定位精准。

     

     

         打开定位,在iOS8以前自动弹出对话框。在iOS8之后,必须在info.plist文件中添加一行  NSLocationAlwaysUsageDescription 或者 

NSLocationWhenInUseUsageDescription


注意:一定要写对,不然不会弹出提示。

区别:

WhenInUse是应用在前台的时候可以搜到更新的位置信息,Always是除了应用在前台,应用在后台(suspend或terminated)都可以获取到更新的位置数据 ,根据需要,按需去申请权限


图:



代码:

<span style="color:#333333;">#import "AZViewController.h"
#import <MapKit/MapKit.h>
@interface AZViewController ()<MKMapViewDelegate,CLLocationManagerDelegate>
{
    MKMapView *_mapView;
    CLLocationManager *_manager;
}
@end

@implementation AZViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

	/**
            iOS中的地图,有两种:
            1、苹果自带的地图SDK,(MKMapKit)但是它在中国使用的时高德地图。
            2、2、第三方地图SDK  (例如:高德的地图SDK,( MAMapKit)、百度地图SDK(BMapKit))。
           使用方法:
     
           1、 使用苹果自带的地图MKMapKit,需要导入框架:MapKit.frameworks、CoreLocation.framework
        */
    [self useMkMapKit];
}
-(void)useMkMapKit
{
    _mapView=[[MKMapView alloc] initWithFrame:self.view.bounds];
    
    //  地图类型,默认为基本
    //  MKMapTypeSatellite 卫星
    //  MKMapTypeStandard  基本
    //  MKMapTypeHybrid   混合
    _mapView.mapType=MKMapTypeStandard;
    [self.view addSubview:_mapView];
    
    UILongPressGestureRecognizer *longPress=[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:) ];
    [_mapView addGestureRecognizer:longPress];
    
    /**
             定位 
     
         目前iOS定位方式有三种: 基站   WIFI  A-GPS
     
         基站:省电、定位不精准(大概位置)
         WIFI:和基站差不多,比基站更费电、定位不精准(大概位置)
         A-GPS:苹果改良了直接使用GPS,先使用基站和WIFI获得大概位置,然后苹果自动推荐当前区域的离你位置最近的GPS卫星,这样就不用再搜索卫星了,直接就可以使用了。费电、定位精准。
     
     
         打开定位,在iOS8以前自动弹出对话框。在iOS8之后,必须在info.plist文件中添加一行  NSLocationAlwaysUsageDescription
     
        */
    
    //获取定位管理对象
    _manager=[[CLLocationManager alloc] init];
    
//    </span><span style="color:#ff0000;">//ios 8 必须加上
//    [_manager requestAlwaysAuthorization];</span><span style="color:#333333;">
    
    
    //精准度
    /*
            kCLLocationAccuracyBestForNavigation   导航精准(导航使用)
            kCLLocationAccuracyBest 普通精准
            kCLLocationAccuracyNearestTenMeters  误差十米
            kCLLocationAccuracyHundredMeters  误差百米
            kCLLocationAccuracyKilometer  误差千米
            kCLLocationAccuracyThreeKilometers  误差三千米
         */
    _manager.desiredAccuracy=kCLLocationAccuracyBest;
    
    //定位距离过滤器,超过10米,才重新定位一次
    _manager.distanceFilter=10;
    
    //设置代理
    _manager.delegate=self;
    
    //开始定位
    [_manager startUpdatingLocation];
    //开始方向定位
    [_manager startUpdatingHeading];
    
    
    
    
    //显示当前用户的位置
    _mapView.showsUserLocation=YES;
}
//长按添加大头针
-(void)longPress:(UILongPressGestureRecognizer *)longPress
{
    if (longPress.state!=UIGestureRecognizerStateBegan) {
        return;
    }
    //坐标
    CGPoint point=[longPress locationInView:_mapView];
    //转成经纬度
    CLLocationCoordinate2D coordinate=[_mapView convertPoint:point toCoordinateFromView:_mapView];
    //地图中心经纬度
    //_mapView.centerCoordinate=coordinate;
    
    //缩放比例
    MKCoordinateSpan span=MKCoordinateSpanMake(0.5, 0.5);
    //要显示的区域
    MKCoordinateRegion regin=MKCoordinateRegionMake(coordinate, span);
    //地图显示一个区域
    [_mapView setRegion:regin animated:YES];
    
    /**
            添加大头针
            1:苹果自带框架下有一个大头针数据类,它可以显示标题,副标题。
            2: 自定义大头针。
        */
    
    // 第一种大头针(系统自带)

    //添加一个标签/大头针  (数据类)
    MKPointAnnotation *anno=[[MKPointAnnotation alloc] init];
    //标题
    anno.title=@"KFC";
    //副标题
    anno.subtitle=@"地址:海淀黄庄";
    //显示位置
    anno.coordinate=coordinate;
    //添加到地图上
    [_mapView addAnnotations:@[anno]];
    

    //第二种,自定义大头针,使用代理
    _mapView.delegate=self;
}
#pragma mark -- 自定义大头针
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    if([annotation isKindOfClass:[_mapView.userLocation class]])
    {
        return nil;
    }
    static NSString *idn=@"ID";
    MKPinAnnotationView *annoView=(MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:idn];
    if (!annoView) {
        annoView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:idn];
    }
    //显示详情面板
    annoView.canShowCallout=YES;
    //颜色
    annoView.pinColor=MKPinAnnotationColorPurple;
    //拖拽
    annoView.draggable=YES;
    
    //动画效果
    annoView.animatesDrop=YES;
    
    //添加左视图
    UIView *leftview=[[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
    leftview.backgroundColor=[UIColor redColor];
    annoView.leftCalloutAccessoryView=leftview;
    
    //添加右视图
    UIButton *btn=[UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    annoView.rightCalloutAccessoryView=btn;
    /**
            添加响应事件
         */
    return annoView;
}
#pragma mark -- 实现定位协议
//定位成功
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
     //拿到定位的位置
    CLLocation *location=[locations lastObject];
    
    //缩放比例
    MKCoordinateSpan span=MKCoordinateSpanMake(0.1, 0.1);
    MKCoordinateRegion region=MKCoordinateRegionMake(location.coordinate, span);
    [_mapView setRegion:region animated:YES];
    
    //停止定位
    [manager stopUpdatingLocation];
    
    
}
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"定位失败");
}
//方向定位成功
-(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading

{
    NSLog(@"%f",newHeading.trueHeading);
}
-(BOOL)prefersStatusBarHidden
{
    return YES;
}
@end
</span>

第二种,使用第三方地图SDK。(这里使用高德SDK,百度SDK和高德的使用方式都差不多,可到百度地图开发者平台上去查看文档)

更多使用方法,请参考高德开发者平台 http://lbs.amap.com


代码:

#import "AZViewController.h"
#import "AZTest.h"
#import <MAMapKit/MAMapKit.h>
#import <AMapSearchKit/AMapSearchAPI.h>


@interface AZViewController ()<MAMapViewDelegate,AMapSearchDelegate>
{
    MAMapView *_mapview;
    AMapSearchAPI *_search;
}
@end

@implementation AZViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    [MAMapServices sharedServices].apiKey=@"372fd6b384ecb49675eaa48440d86a08";
    _mapview =[[MAMapView alloc] initWithFrame:self.view.bounds];
    
    //地图类型 多了夜景模式 MAMapTypeStandardNight
    _mapview.mapType=MAMapTypeStandard;
   
    //是否显示罗盘
    _mapview.showsCompass=YES;
    //是否显示交通情况(实时的)
    _mapview.showTraffic=NO;
    
    //设置代理
    _mapview.delegate=self;
    
# if 0
    //画线
    [self makeLine];
    
    //花园
    [self makeYuan];
    
#endif

#if 0
    //POI搜索
    [self searchPOI:@"俏江南"];
#endif
    
#if 0
    //正向地理编码
    [self getCode:@"王府井"];
#endif

#if 0
    //逆向地理编码
    [self getNameByLatitude:39.990459 andLongTitude:116.481476];
#endif

#if 0
    //导航
    [self navSearch];
#endif
    
#if 1
    //定位
    [self locationPos];
#endif
    
    [self.view addSubview:_mapview];
}
#pragma mark -- 定位
-(void)locationPos
{
    _mapview.showsUserLocation=YES;
    //地图跟着位置移动
    [_mapview setUserTrackingMode: MAUserTrackingModeFollow animated:YES];
}
-(void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation
updatingLocation:(BOOL)updatingLocation
{
    if(updatingLocation)
    {
        //取出当前位置的坐标
        NSLog(@"latitude : %f,longitude: %f",userLocation.coordinate.latitude,userLocation.coordinate.longitude);
    }
}
#pragma mark -- 导航
-(void)navSearch
{
    //初始化检索对象
    _search = [[AMapSearchAPI alloc] initWithSearchKey:@"372fd6b384ecb49675eaa48440d86a08" Delegate:self];
    
    //构造AMapNavigationSearchRequest对象,配置查询参数
    AMapNavigationSearchRequest *naviRequest= [[AMapNavigationSearchRequest alloc] init];
    naviRequest.searchType = AMapSearchType_NaviDrive;
    naviRequest.requireExtension = YES;
    
    //起点经纬度
    naviRequest.origin = [AMapGeoPoint locationWithLatitude:39.994949 longitude:116.447265 ];
    //目的地经纬度
    naviRequest.destination = [AMapGeoPoint locationWithLatitude:39.990459 longitude:116.481476];
    
    
    //发起路径搜索
    [_search AMapNavigationSearch: naviRequest];
}
//实现路径搜索的回调函数
- (void)onNavigationSearchDone:(AMapNavigationSearchRequest *)request response:(AMapNavigationSearchResponse *)response
{
    if(response.route == nil)
    {
        return;
    }
    //拿到第一个方案
    AMapRoute *route=response.route;
    //第一个方案的路线
    AMapPath *path=route.paths[0];
    NSMutableArray *coordinateArray=[[NSMutableArray alloc] initWithCapacity:path.steps.count];
    //遍历这个方案中的路段
    for(AMapStep *step in path.steps)
    {
        NSArray *pointArray=[step.polyline componentsSeparatedByString:@";"];
        for (NSString *str in pointArray) {
            [coordinateArray addObject:str];
        }
    }
    CLLocationCoordinate2D coordinate[coordinateArray.count];
    //遍历坐标字符串
    for (int i = 0; i < coordinateArray.count; i++) {
        //经纬度字符串 116,14
        NSString* pointStr = coordinateArray[i];
        NSArray* pointArray = [pointStr componentsSeparatedByString:@","];
        //取得经纬度
        coordinate[i].longitude = [pointArray[0] floatValue];
        coordinate[i].latitude = [pointArray[1] floatValue];
    }
    
    MAPolyline* polyline = [MAPolyline polylineWithCoordinates:coordinate count:coordinateArray.count];
    [_mapview addOverlay:polyline];

   
}
#pragma mark -- 逆向地理编码 (根据经纬度获取地名)
-(void)getNameByLatitude:(float)latitude andLongTitude:(float)longtitud
{
    //初始化检索对象
    _search = [[AMapSearchAPI alloc] initWithSearchKey:@"372fd6b384ecb49675eaa48440d86a08" Delegate:self];
    
    //构造AMapReGeocodeSearchRequest对象,location为必选项,radius为可选项
    AMapReGeocodeSearchRequest *regeoRequest = [[AMapReGeocodeSearchRequest alloc] init];
    regeoRequest.searchType = AMapSearchType_ReGeocode;
    regeoRequest.location = [AMapGeoPoint locationWithLatitude:latitude longitude:longtitud];
    regeoRequest.radius = 10000;
    regeoRequest.requireExtension = YES;
    
    //发起逆地理编码
    [_search AMapReGoecodeSearch: regeoRequest];
}
//实现逆地理编码的回调函数
- (void)onReGeocodeSearchDone:(AMapReGeocodeSearchRequest *)request response:(AMapReGeocodeSearchResponse *)response
{
    if(response.regeocode != nil)
    {
        AMapReGeocode *regeocode=response.regeocode;
     
        NSLog(@"%@",regeocode.formattedAddress);
       
    }
}
#pragma mark -- 正向地理编码(根据地名获取经纬度)
-(void)getCode:(NSString *)name
{
    //初始化检索对象
    _search = [[AMapSearchAPI alloc] initWithSearchKey:@"372fd6b384ecb49675eaa48440d86a08" Delegate:self];
    
    //构造AMapGeocodeSearchRequest对象,address为必选项,city为可选项
    AMapGeocodeSearchRequest *geoRequest = [[AMapGeocodeSearchRequest alloc] init];
    geoRequest.searchType = AMapSearchType_Geocode;
    geoRequest.address = name;
    geoRequest.city = @[@"beijing"];
    
    //发起正向地理编码
    [_search AMapGeocodeSearch: geoRequest];
}
//实现正向地理编码的回调函数
- (void)onGeocodeSearchDone:(AMapGeocodeSearchRequest *)request response:(AMapGeocodeSearchResponse *)response
{
    if(response.geocodes.count == 0)
    {
        return;
    }

    for ( AMapGeocode *deoCode in response.geocodes)
    {
        MAPointAnnotation *pointAnnotation = [[MAPointAnnotation alloc] init];
        pointAnnotation.coordinate = CLLocationCoordinate2DMake(deoCode.location.latitude, deoCode.location.longitude);
        pointAnnotation.title = deoCode.district;
        [_mapview addAnnotations:@[pointAnnotation]];
    }
}
#pragma mark -- POI搜索 (也称兴趣点搜索)
-(void)searchPOI:(NSString *)keyWords
{
    //初始化检索对象
    _search = [[AMapSearchAPI alloc] initWithSearchKey:@"372fd6b384ecb49675eaa48440d86a08" Delegate:self];
    
    //创建一个请求
    //构造AMapPlaceSearchRequest对象,配置关键字搜索参数
    AMapPlaceSearchRequest *poiRequest = [[AMapPlaceSearchRequest alloc] init];
    poiRequest.searchType = AMapSearchType_PlaceKeyword;
    poiRequest.keywords = keyWords;
    //搜索哪个城市,数组表示可以搜索多个城市
    poiRequest.city = @[@"beijing"];
    poiRequest.requireExtension = YES;
    
    //发起POI搜索
    [_search AMapPlaceSearch: poiRequest];
}
//POI回调
-(void)onPlaceSearchDone:(AMapPlaceSearchRequest *)request response:(AMapPlaceSearchResponse *)response
{
    //遍历数组
    for (AMapPOI *poi in response.pois) {
        MAPointAnnotation *pointAnnotation = [[MAPointAnnotation alloc] init];
        pointAnnotation.coordinate = CLLocationCoordinate2DMake(poi.location.latitude, poi.location.longitude);
        pointAnnotation.title = poi.name;
        pointAnnotation.subtitle = poi.address;
        [_mapview addAnnotations:@[pointAnnotation]];
    }
}
-(MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id<MAAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MAPointAnnotation class]])
    {
        static NSString *pointReuseIndetifier = @"pointReuseIndetifier";
        MAPinAnnotationView*annotationView = (MAPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:pointReuseIndetifier];
        if (annotationView == nil)
        {
            annotationView = [[MAPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pointReuseIndetifier];
        }
        annotationView.canShowCallout= YES;       //设置气泡可以弹出,默认为NO
        annotationView.animatesDrop = YES;        //设置标注动画显示,默认为NO
        annotationView.draggable = YES;        //设置标注可以拖动,默认为NO
        annotationView.pinColor = MAPinAnnotationColorPurple;
        return annotationView;
    }
    return nil;
}


#pragma mark -- 画线
-(void)makeLine
{
    //构造折线数据对象
    CLLocationCoordinate2D commonPolylineCoords[4];
    commonPolylineCoords[0].latitude = 39.832136;
    commonPolylineCoords[0].longitude = 116.34095;
    
    commonPolylineCoords[1].latitude = 39.832136;
    commonPolylineCoords[1].longitude = 116.42095;
    
    commonPolylineCoords[2].latitude = 39.902136;
    commonPolylineCoords[2].longitude = 116.42095;
    
    commonPolylineCoords[3].latitude = 39.902136;
    commonPolylineCoords[3].longitude = 116.44095;
    
    //构造折线对象
    MAPolyline *commonPolyline = [MAPolyline polylineWithCoordinates:commonPolylineCoords count:4];
    
    //在地图上添加折线对象
    [_mapview addOverlay: commonPolyline];

}
#pragma mark -- 画圆
-(void)makeYuan
{
    //构造圆
    MACircle *circle = [MACircle circleWithCenterCoordinate:CLLocationCoordinate2DMake(39.952136, 116.50095) radius:5000];
    
    //在地图上添加圆
    [_mapview addOverlay: circle];
}
#pragma mark -- 手动创建覆盖物,这里才是真正的创建了覆盖物(折线,画园)
- (MAOverlayView *)mapView:(MAMapView *)mapView viewForOverlay:(id <MAOverlay>)overlay
{
    //判断是折线
    if ([overlay isKindOfClass:[MAPolyline class]])
    {
        //折线类
        MAPolylineView *polylineView = [[MAPolylineView alloc] initWithPolyline:overlay];
        //线宽
        polylineView.lineWidth = 10.f;
        //颜色
        polylineView.strokeColor = [UIColor colorWithRed:0 green:0 blue:1 alpha:0.6];
        //连接类型
        polylineView.lineJoinType = kMALineJoinRound;
        //端点类型
        polylineView.lineCapType = kMALineCapRound;
        
        return polylineView;
    }
    else if ([overlay isKindOfClass:[MACircle class]])
        {
            MACircleView *circleView = [[MACircleView alloc] initWithCircle:overlay];
            
            circleView.lineWidth = 5.f;
            circleView.strokeColor = [UIColor colorWithRed:0.6 green:0.6 blue:0.6 alpha:0.8];
            circleView.fillColor = [UIColor colorWithRed:1.0 green:0.8 blue:0.0 alpha:0.8];
            circleView.lineDash = YES;
            
            return circleView;
        }
    return nil;
}
#pragma mark -- 隐藏状态栏
-(BOOL)prefersStatusBarHidden
{
    return YES;
}
@end


图:

折线、画圆                                                 POI                                                                                                                   

地图(定位、POI、地理编码……)_第1张图片      地图(定位、POI、地理编码……)_第2张图片      


  导航                                                           






你可能感兴趣的:(地图(定位、POI、地理编码……))