iOS的SDK中提供与地图有关的两大框架 Map Kit 和 core location;其中Map Kit 位于iPhone架构层的Cocoa Touch层, 主要提供了四个功能:显示地图,cllocation和地址之间的转换,支持在地图上做标记,把一个位置解析成地址。core location 位于架构层的core Services,提供获取当前位置的功能。本文通过一个小例子解析对地图有关知识的学习和理解。
Map Kit:(主要负责地图的显示)
首先,创建一个single View Application 工程,在工程中引入MapKit.framework和CoreLocation.framework并在viewController.h或者viewController.m文件里包含<MapKit/MapKit.h>、<CoreLocation/CoreLocation.h>头文件。
(1)Map Kit 有关地图显示主要的类、数据结构及常用方法
MKMapView:
-
mapType:有 MKMapTypeStandard(标准) ,MKMapTypeSatellite(卫星),MKMapTypeHybrid(混合)
-
zoomEnabled:是否允许缩放
-
CLLocationCoordinate2D:
经度 与纬度的合称组成一个坐标系统,又称为地理坐标系统(它是一种利用三度空间的球面来定义地球上的空间的球面坐标系 统,能够标示地球上的任何一个位置)北纬为正数,南纬为负数、东经正数,西经为负数。
-
MKCoordinateRegion
typedef struct { CLLocationCoordinate2D center; //位置的中心点坐标 MKCoordinateSpan span; //水平和垂直显示地图的大小,也定义了地图的zoom级别 } MKCoordinateRegion;
-
常用方法
MKCoordinateRegion MKCoordinateRegionMakeWithDistance(CLLocationCoordinate2D centerCoordinate, latitudinalMeters, CLLocationDistance longitudinalMeters);
功能:根据指定的地理坐标和距离创建MKCoordinateRegion对象。参数1:新的坐标区域的中心点。参数2:纬度(从北向南 的距离、单位米)。参数3:经度(从东到西的距离,单位米)。
显示某一坐标的地图程序如下:
- (void)viewDidLoad
{
[super viewDidLoad];
self.mapView = [[MKMapView alloc]initWithFrame:self.view.bounds];
// 设置地图的显示类型
self.mapView.mapType = MKMapTypeHybrid;
// 设置地图是否允许缩放
self.mapView.zoomEnabled = YES;
CLLocationCoordinate2D coordinate = {34.7568711,113.663221};
MKCoordinateSpan span = {100,100};
MKCoordinateRegion region = {coordinate,span};
[self.mapView setRegion:region];
[self.view addSubview:self.mapView];
}
(2)在Map上标记注解,具体做法步骤如下:
创建注解类(需要声明实现MKAnnotation协议)
实例化注解类对象
将实列化的注解对象添加到MKMapView对象
类似于UITableViewCell的方法创建MKAnnotationView对象,这个对象用于最终在地图上展示。
a)使用系统默认的annotation,代码如下:
MKPointAnnotation *pinAnnotation = [[MKPointAnnotation alloc] init];
pinAnnotation.coordinate = coordinate;
pinAnnotation.title = @"郑州";
pinAnnotation.subtitle = @"河南青云信息技术";
self.mapView addAnnotation:pinAnnotation;
这样就会出现一个红色的大头针形状的annotation ;
要改变大头针形的annotation的属性就要调用方法
- (MKAnnotationView*)mapView:(MKMapView *)mapView viewForAnnotation: (id<MKAnnotation>)annotation
一下代码是改变大头针形状的annotation的一些属性:(大头针的颜色变为紫色,)
- (MKAnnotationView*)mapView:(MKMapView *)mapView
viewForAnnotation:(id<MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
{
return nil;
}
static NSString *indentifier = @"pinView";
MKPinAnnotationView *pinView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:indentifier];
if (nil == pinView)
{
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:indentifier];
}
pinView.pinColor = MKPinAnnotationColorPurple;
pinView.animatesDrop = YES;
pinView.canShowCallout = YES;
return pinView;
}
b)在系统提供的callout基础上自定义自己的图片的annotation
首先,先创建一个继承自MKAnnotationView的类,然后根据自己的素材设置属性;示例代码如下:
- (MKAnnotationView*)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
{
return nil;
}
QYAnnotationView *pinView =(QYAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:ind entifier];
if (nil == pinView)
{
pinView = [[QYAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:indentifier];
}
pinView.image = [UIImage imageNamed:@"icon_nav_start"];
UIImageView *leftImageView = [[UIImageView alloc]
initWithFrame:CGRectMake(0, 0, 40, 40)];
leftImageView.image = [UIImage imageNamed:@"icon"];
pinView.leftCalloutAccessoryView = leftImageView;
UIButton *button = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[button addTarget:self action:@selector(onButton:)forControlEvents:UIControlEventTouchUpInside];
pinView.rightCalloutAccessoryView = button;
return pinView;
}
(3)位置反编码:
位置反编码就是给一个CLLocationCoordinate2D结构的数据coordinator,调用方法得到地址的详细信息的方法(iOS5.0之后用CLGeocoder)
- (void)reverseGeocodeLocation:(CLLocation *)location
completionHandler:(CLGeocodeCompletionHandler)completionHandler;
Core Location(主要用于获取当前位置)
IOS SDK提供的Core Location能比较好的提供获取位置信息的功能,获取位置信息涉及如下几个类,CLLocationManager(位置管理器), CLLocation, CLLocationManagerdelegate(协议、提供委托方法),CLLocationCoodinate2D(存储坐标位置)另外CLLocationManager还有几个属性;desiredAccuracy:位置的精度属性
取值有如下几种:
kCLLocationAccuracyBest 精确度最佳
kCLLocationAccuracynearestTenMeters 精确度10m以内
kCLLocationAccuracyHundredMeters 精确度100m以内
kCLLocationAccuracyKilometer 精确度1000m以内
kCLLocationAccuracyThreeKilometers 精确度3000m以内
distanceFilter:横向移动多少距离后更新位置信息
delegate:响应CLLocationManagerdelegate的对象
以下是获取当前位置的一个示例:
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.distanceFilter = 500;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
首先遵守CLLocationManagerDelegate,然后@property一个locationManager属性;
调用delegate 方法:
-
-(void)locationManager:(CLLocationManager )manager didUpdateToLocation:(CLLocation )newLocation fromLocation:(CLLocation *)oldLocation
-
-(void)locationManager:(CLLocationManager )manager didFailWithError:(NSError )error
在第一个delegate方法里面进行所需的操作,第二个delegate方法