地图和定位

iPhone SDK提供了三个类来管理位置信息:CLLocation CLLocationManager 和 CLLHeading(不常用)。除了使用GPS来获取当前的位置信息外,iPhone也可以基于WiFi基站和无线发射塔来获得位置信息。GPS的精度最高,可以精确到米级别,但是也最耗电。


------------CLLocation
CLLocation类代表一个位置信息,其中还包括了方向和速度。比如我在长安街188号以5公里/小时的速度往西走。CLLocation具有下面的属性和方法:
@property  CLLocationCoordinate2D coordinate; //以经度和纬度表示的位置信息
@property CLLocationDistance altitude;  //海拔
@property CLLocationAccuracy horizontalAccuracy; //水平精度(如:精确到米)
@property CLLocationAccuracy verticalAccuracy; //垂直精度
@property CLLocationDirection course; //方向
@property CLLocationSpeed speed; //速度
-(NSDate *)timeStamp;
//两个位置之间的距离
-(CLLocationDistance)distanceFromLocation:(CLLocation *)location;


-------------CLLocationManager
CLLocationManager类管理和提供位置服务。它的属性和方法有:
@property CLLocation *location; //位置
@property id<CLLocationManagerDelegate> delegate;
@property CLLocationDistance distanceFilter; //距离过滤,比如:500以内
@property CLlocationAccuracy verticalAccuracy; //垂直精度
-(void) startUpdatingLocation; //开始更新位置(比如:你在往某个地方走)
-(void)stopUpdatingLocation; //停止更新位置
-(void)startUpdatingHeading; //开始更新方向(比如:你改往东走)
-(void)stopUpdatingHeading; //停止更新方向
CLLocationManagerDelegate是一个委托类。你的应用程序需要使用这个委托类。当用户改变位置的时候,CLLocationManager回调的方法是:
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation;
当用户改变方向的时候,所调用的方法是:
-(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLLHeading *)newHeading;
当iPhone无法获得当前位置的信息时,所回调的方法是:
-(void)locationManager: (CLLocationManager *)manager didFailLoadWithError:(NSError *)error;


=========================================================================
下面我们来看一个位置类的基本步骤:
一、启动定位服务
CLLocationManager *locManager = [[CLLocationManager alloc] init];
locManager.delegate = self;
[locManager startUpdatingLocation];
二、获得位置信息
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation fromLocation: (CLLocation *)oldLocation
{
NSTimeInterval howRecent = [newLocation.timestamp timeIntervalSinceNow];
if(howRecent < -10) return ; //离上次更新的时间少于10秒
if(newLocation.horizontalAccuracy > 100) return; //精度> 100米
//经度和纬度
double lat = newLocation.coordinate.latitude;
double lon = newLocation.coordinate.longitude;
}
三、获得方向信息(比如往南走)
-(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
//获得方向
CLLocationDirection heading = newHeading .trueHeading;
}
四、停止定位
[locManager stopUpdatingLocation];
你可以设置你想要的精度和距离过滤:
locManager.desiredAccuracy = kLLocationAccuracyBest;
locManager.distanceFilter = 1000;


MapKit框架:
     主要提供了四个功能:显示地图、CLLocation和地址之间的转换、支持在地图上做标记(比如标记北京天安门广场)、把一个位置解析成地址(比如我在水立方,想要知道确切的地址信息)。
 MKMapView类:主要是完成下述功能:
-------显示地图,比如:显示北京市的地图;
-------提供多种显示方式,比如标准地图格式,卫星地图等;
-------支持地图的放大缩小;
-------支持在地图上做标记,比如标记天安门广场;
-------在地图上显示手机所在的当前位置。
MKMapView类的属性有:
@property MKCoordinateRegin region; //地图所显示的区域
@property CLLocationCoordinate2D centerCoordinate; //经度和纬度确定的中心位置
@property MKMapView mapType; //地图的显示类型,如:卫星地图
@property NSArray *annotations; //地图上的标记
@property MKUserLocation userLocation; //用户位置
@property id <MKMapViewDelegate>delegate; //委托类


装载地图时的回调方法有:
-(void)mapViewWillStartLocationMap:(MKMapView *) mapView; //开始装载地图
-(void)mapViewDidFinishLocationMap:(MKMapView  *)mapView; //结束装载地图
-(void)mapVewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error; //装载失败


当位置发生转变时的回调方法:
-(void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated; //将要更改
-(void)mapView: (MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated; //已经更改


MKPlacemark、MKUserLocation和MKReverseGeocoder
在地图上做标记是通过MKPlacemark类来完成的。这个类使用(符合)MKAnnotation协议。MKAnnotation包含了多个属性,如:位置(经纬度,CLLocationCoordinate2D类型)、文字标记信息(NSString类型)等。
MKPlacemark保存了位置(经纬度)和地址(字典类)之间的映射。下面是它的初始化方法:
-(void)initWithCoordinate:(CLLocationCoordinate2D *)coordinate addressDictionary:(NSDictionary *)dictionary;
MKUserLocation就是指手机的当前位置,它是MKAnnotation的一个特别案例(因为MKAnnotation可以是地图上的任何标记,而MKUserLocation只是标记了地图上手机所在的当前位置)。这个类包含了多个属性:手机的位置(类型为CLLocation)、位置文字信息(类型为NSString)等。
MKPlacemark保存了位置(经纬度)和地址之间的映射。那么,有没有工具在这两者之间做转换呢?这就是MKRecerseGeocoder.给定一个位置信息,这个类可以返回相应的地址信息。MKReverseGeocoder的初始化方法为:
-(void)initWithCoodinate:(CLLocationCoordinate2D)coordinate;
下面是MKReverseGeocoder常用的一些属性和方法:
@property id <MKReverseGeocoderDelegate>delegate; //委托
-(void)start; //开始转换
-(void)cancel; //取消转换


回调的方法有:
-(void)reverseGeocoder:(MKReverseGeocoder *) geocoded didFindPlacemark:(MKPlacemark *)placemark;  //转换成功
-(void)reverseGeocoder : (MKReverseGeocoder *)geocoded didFailWithError:(NSError *)error; //转换失败




代码例子
.h

#import <UIKit/UIKit.h>

#import <MapKit/MapKit.h>


@interface ViewController : UIViewController<CLLocationManagerDelegate,MKMapViewDelegate>{

    MKMapView* _mapView;

}



@end


.m


//


#import "ViewController.h"

#import "MyAnnotation.h"


@implementation ViewController


- (void)viewDidLoad

{

    [super viewDidLoad];

    //39.918163,116.40152

    //维经度

    CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(39.918163,116.40152);

    //缩放比例

    MKCoordinateSpan span = MKCoordinateSpanMake(0.1, 0.1);

    //确定一个区域

    MKCoordinateRegion region = MKCoordinateRegionMake(coordinate, span);


    _mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];

    _mapView.delegate = self;

    //设置显示区域 

    _mapView.region = region;

    //地图类型

    _mapView.mapType = MKMapTypeStandard;

    //显示用户位置

    _mapView.showsUserLocation = YES;

    [self.view addSubview:_mapView];

    [_mapView release];

    

if ([CLLocationManager locationServicesEnabled]==NO) {

        NSLog(@"您的设备没有定位系统");

        return;

    }



    //定位

    CLLocationManager* manager = [[CLLocationManager alloc] init];

    //精确度

    manager.desiredAccuracy = kCLLocationAccuracyBest;

    manager.distanceFilter = 100;

    manager.delegate = self;

    //开始定位

    [manager startUpdatingLocation];

    

    

    //添加大头针

    /*

    MyAnnotation* anno = [[MyAnnotation alloc] initWithTitle:@"大头针" SubTitle:@"我叫大头针" Coordinate:coordinate];

    [_mapView addAnnotation:anno];

    [anno release];

    */

    

    UILongPressGestureRecognizer* longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(addAnno:)];

    [_mapView addGestureRecognizer:longPress];

    [longPress release];

    

}


- (void)addAnno:(UILongPressGestureRecognizer*)longPress{

    if (longPress.state != UIGestureRecognizerStateBegan) {

        return;

    }

    //得到触摸屏幕坐标

    CGPoint point = [longPress locationInView:_mapView];

    //转成经纬度

    CLLocationCoordinate2D coordinate = [_mapView convertPoint:point toCoordinateFromView:_mapView];

    MyAnnotation* anno = [[MyAnnotation alloc] initWithTitle:@"大头针" SubTitle:@"我还是大头针" Coordinate:coordinate];

    [_mapView addAnnotation:anno];

    [anno release];

}


//定位

//<IOS6.0 ios2-ios6使用

//- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{


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

    CLLocation* location = [locations lastObject];

    CLLocationCoordinate2D coordinate = location.coordinate;

    MKCoordinateSpan span = MKCoordinateSpanMake(0.1, 0.1);

    MKCoordinateRegion region = MKCoordinateRegionMake(coordinate, span);

    [_mapView setRegion:region animated:YES];

}


//定位失败

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{

    NSLog(@"定位失败");

}


//自定义大头针

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

    if ([annotation isKindOfClass:[mapView.userLocation class]]) {

        return nil;

    }

    

    

    MKPinAnnotationView* pinView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:@"ID"];

    if (pinView == nil) {

        pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"ID"] autorelease];

    }

    //显示详细信息

    pinView.canShowCallout = YES;

    //颜色

    pinView.pinColor = MKPinAnnotationColorPurple;

    //掉下动画

    pinView.animatesDrop = YES;

    

    UIView* leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];

    leftView.backgroundColor = [UIColor redColor];

    pinView.leftCalloutAccessoryView = leftView;

    [leftView release];

    

    UIButton* button =[UIButton buttonWithType:UIButtonTypeDetailDisclosure];

    pinView.rightCalloutAccessoryView = button;

    

    

    return pinView;

}


@end





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值