Fork me on GitHub

项目开发--------地图与定位功能

一.定位.

    1.定位功能 : 定位是一个很常用的功能,如一些地图软件打开之后如果用户允许软件定位的话,那么打开软件后就会自动锁定到当前位置,如果用户手机移动那么当前位置也会跟随着变化。要实现这个功能需要使用Core Loaction中CLLocationManager类.

 

相关方法:(在前面的方法和属性属于较为常用和重要的)

 

 

示例代码:

 

//地理定位-----------------------------------------------
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    //创建定位管理对象
    self.loactionMag  = [[CLLocationManager alloc] init];
    
    //CLLocationManager通过代理来实现
    //开始定位
    self.loactionMag.delegate = self;
    
    //向系统申请定位权限 定位服务授权状态 返回值为枚举值
    //总是开启定位权限功能
    [_loactionMag requestAlwaysAuthorization];
    
     //当使用次应用中允许访问定位服务
//    [_loactionMag requestWhenInUseAuthorization];
    
    //开始更新位置
        [_loactionMag startUpdatingLocation];   
}

#pragma mark ---实现相应的代理方法
//位置发生变化后执行(第一次定位到某个位置直管厚也会执行)
- (void)locationManager:(CLLocationManager *)manager
     didUpdateLocations:(NSArray *)locations
{
    //打印经纬度
    CLLocation *location = locations[0];

    NSLog(@"纬度----%f,经度---+%f",location.coordinate.latitude ,location.coordinate.longitude);
    //为了省电,定位完毕关闭
    //如果不需要实时定位,使用及时使关闭定位服务
    [_loactionMag stopUpdatingLocation];
}

 

   2.地理(反)编码

    除了提供位置跟踪功能之外,在定位服务中还包含CLGeocoder类用于处理地理编码和逆地理编码(又叫反地理编码)功能。

   地理编码:根据给定的位置(通常是地名)确定地理坐标(经、纬度)。

   逆地理编码:可以根据地理坐标(经、纬度)确定位置信息(街道、门牌等)。

CLGeocoder最主要的两个方法就是

  - (void)geocodeAddressString:(NSString *)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler;  (分别用于地理编码)

  - (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler;,(分别用于反地理编码)

 

 示例代码:

 

//地理(反)编码----------------------------------------------------

#pragma mark ---地理编码  即根据地名确定地理坐标
- (IBAction)geoCode:(UIButton *)sender {
    
    //进行地理编码的代理方法
    [self.geocoder geocodeAddressString:self.adddressField.text completionHandler:^(NSArray *placemarks, NSError *error) {
        if (error) {
            self.detailAddressLabel.text = @"查找地点不存在";
            
        } else{
           
            //打印出CLPlacemark中的内容
//            CLPlacemark *pl = placemarks[0];
//            NSDictionary *dic = pl.addressDictionary;
//            NSLog(@"%@",dic[@"city"]);
            //CLPlacemark 这个数组中存放的是CLPlacemark对象(位置对象,属性 ,name)
            
            CLPlacemark *place = placemarks[0];
            
            //设置地理纬度位置
            self.latitude.text  = [NSString stringWithFormat:@"%lf",place.location.coordinate.latitude];
            //设置地理经度位置
             self.longtitude.text  = [NSString stringWithFormat:@"%lf",place.location.coordinate.longitude];

            //设置地址详情
           self.detailAddressLabel.text = place.name;      
        }
    }];  
}


#pragma mark ---地理反编码   即根据坐标取得地名
- (IBAction)reverseGeocode:(UIButton *)sender {
    
      //反地理编码
    //创建一个<#(CLLocation *)#>对象
    //输入的纬度
    CLLocationDegrees latitude = [self.latitudeTextField.text doubleValue];
    //输入的经度
    CLLocationDegrees longtitude = [self.longtitudeTextField.text doubleValue];
    //获取输入的经纬度地理位置
    CLLocation *loc  = [[CLLocation alloc] initWithLatitude:latitude longitude:longtitude];
    //用代理方法进行地理反编码
    [self.geocoder reverseGeocodeLocation:loc completionHandler:^(NSArray *placemarks, NSError *error) {
        if (error) {
            
            self.reverseDetailAddressLable.text = @"未获取到指定位置";
        }else{
          //取出数组中第一个对象
            CLPlacemark *placem = placemarks[0];
            //设置详细地址
            self.reverseDetailAddressLable.text = placem.name;
        }
    }];

 

效果图:(由于模拟器原因定位不是很精确)

 

二.地图

    在iOS中进行地图开发主要有两种方式,一种是直接利用MapKit框架进行地图开发,利用这种方式可以对地图进行精准的控制;另一种方式是直接调用苹果官方自带的地图应用,主要用于一些简单的地图应用(例如:进行导航覆盖物填充等),无法进行精确的控制。

      在很多带有地图的应用中默认打开地图都会显示用户当前位置,同时将当前位置标记出来放到屏幕中点方便用户对周围情况进行查看。如果在iOS6或者iOS7中实现这个功能只需要添加地图控件、设置用户跟踪模式、在-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation代理方法中设置地图中心区域及显示范围

    作用:主要用于用户当前位置定位


 

示例代码:

 

- (void)viewDidLoad {
    [super viewDidLoad];
   //1.跟踪用户位置
    self.mapView.userTrackingMode = MKUserTrackingModeFollow;
    
    //2.设置地图显示类型
//    self.mapView.mapType = MKMapTypeSatellite;
       self.mapView.mapType = MKMapTypeStandard;
    
    //3.设置地图显示 由代理来完成在地图位置的更新
    self.mapView.delegate = self;
   
}

#pragma mark --实现MKMapViewDelegate

//实时更新在地图上的位置
//用户位置发生改变时触发(第一次定位到用户位置也会触发这个方法)
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
   userLocation.title = @"海淀区";
    userLocation.subtitle = @"金五星五层";
    
    //设置地图的显示范围
    //设置区域跨度(经纬度跨度)  跨度越小越清楚  越大越不清楚
    
    CLLocationCoordinate2D center = userLocation.location.coordinate;
    
    MKCoordinateSpan span = MKCoordinateSpanMake(0.5, 0.5);
    
    MKCoordinateRegion region = MKCoordinateRegionMake(center, span);
    //设置地图显示区域,用于控制当前屏幕显示地图的范围
    [self.mapView setRegion:region animated:YES];

}

 

效果图:

 

 

三.大头针

    在iOS开发中经常会标记某个位置,需要使用地图标注,也就是大家俗称的“大头针”。只要一个NSObject类实现MKAnnotation协议就可以作为一个大头针,通常会重写协议中coordinate(标记位置)、title(标题)、subtitle(子标题)三个属性,然后在程序中创建大头针对象并调用addAnnotation:方法添加大头针即可(之所以iOS没有定义一个基类实现这个协议供开发者使用,多数原因应该是MKAnnotation是一个模型对象,对于多数应用模型会稍有不同,例如后面的内容中会给大头针模型对象添加其他属性)。

 

示例代码:

 

CustomAnnotation.h文件
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface CustomAnnotation : NSObject  <MKAnnotation>

//声明称属性
@property (nonatomic) CLLocationCoordinate2D coordinate;

// Title and subtitle for use by selection UI.
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;

@property(nonatomic,strong)NSString *imageName;

@end

 

 

 AnnotationViewController.m文件

 

#import "AnnotationViewController.h"
#import <MapKit/MapKit.h>
#import "CustomAnnotation.h"
@interface AnnotationViewController ()<MKMapViewDelegate>

@property (strong, nonatomic) IBOutlet MKMapView *MKmapview;

- (IBAction)addAnnotation:(UIButton *)sender;

@end

@implementation AnnotationViewController
- (void)viewDidLoad { [super viewDidLoad]; /* 地理追踪定位,并在点击位置添加大头针 步骤:第一步:设置跟踪地理位置 第二步:设置代理 第三步:要实现相应的代理方法,同时要对大头针的重用情况做出判断 */ //1.设置跟踪用户位置 self.MKmapview.userTrackingMode = MKUserTrackingModeFollow; //2.设置代理 self.MKmapview.delegate = self; //添加手势 #pragma mark -- mapView添加轻拍手势 UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapMapView:)]; [self.MKmapview addGestureRecognizer:tapGR]; } //轻拍手势事件的实现 -(void)tapMapView:(UIGestureRecognizer *)tap { //1.获取用户点击在mapView中的位置 CGPoint point = [tap locationInView:self.MKmapview]; //2.将数学坐标系的点转换成经纬度坐标 CLLocationCoordinate2D coordinate = [self.MKmapview convertPoint:point toCoordinateFromView:self.MKmapview]; //创建大头针模型对象 CustomAnnotation *customAnno = [[CustomAnnotation alloc] init]; //必须要设置属性值************** customAnno.coordinate = coordinate; customAnno.title = @"你好"; // customAnno.imageName = @"3"; //将大头针添加到mapView [self.MKmapview addAnnotation:customAnno]; } #pragma mark --实现协议方法MKMapViewDelegate -(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation { //这里可以打印一些内容 } //如果想自定义大头针,需要实现协议中的一个方法 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation { //如果不是自定义的大头针 就用系统的 if (![annotation isKindOfClass:[CustomAnnotation class]]) { return nil; } //先到重用集合中去取 //取大头针视图对象 static NSString *identifier = @"custom"; // MKAnnotationView *annotstionView = [mapView dequeueReusableAnnotationViewWithIdentifier:identifier]; if (annotstionView == nil) { annotstionView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier]; //显示子标题 title subtitle annotstionView.canShowCallout = YES; //设置大头针 上面显示的描述区域的偏移量 annotstionView.calloutOffset = CGPointMake(0, -10); //设置大头针上面显示的描述区域 左右两边的辅助控件 annotstionView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeContactAdd]; annotstionView.leftCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; } //将annotion传过来的值给它 赋值(传递模型) annotstionView.annotation = annotation; //设置图片 (系统自带指针所带属性有限,所以这里图片要自己传过去) CustomAnnotation *customAnno = (CustomAnnotation *)annotation; annotstionView.image = [UIImage imageNamed:customAnno.imageName]; //返回为nil时,则使用系统自带的大头针 // return nil; return annotstionView; } //这里没有使用按钮 - (IBAction)addAnnotation:(UIButton *)sender { //1.第一个大头针 // MKAnnotationView *first = [[MKAnnotationView alloc] init]; } @end

 

效果图:

 

 

 

注意:搜索的所有结果都是在中国境内的,因为苹果在中国的地图服务商是高德地图。

 

参考博文:1.地图与定位服务     2.地图与定位功能

 注意:常用的百度地图,直接进入百度地图开发平台,对其使用有详细的说明 链接

 

posted @ 2015-10-21 19:41  DengHuiCheng  阅读(505)  评论(0编辑  收藏  举报