在iOS应用程序中,我们可以使用Map Kit API开发地图应用,其核心是MKMapView类。本次主要实现的功能是显示地图,添加标注,跟踪用户位置变化。
(本日志的所有内容基于已成功获取坐标位置,获取方法见上篇日志)
1、显示地图
首先需要引用<MapKit/MapKit.h>,它的委托协议是 MKMapViewDelegate。
初始化MapView
mapView = [[MKMapView alloc] initWithFrame:CGRectMake(5, 120, self.view.frame.size.width - 10, 430)]; mapView.mapType = MKMapTypeStandard; mapView.delegate = self;
MKMapTypeStandard 标注地图类型
MKMapSatellite 卫星地图类型
MKMapTypeHybrid 混合地图类型
在获取到位置的placemark后,我自定义了一个函数,实现地图的显示
- (void) showInMapView: (CLPlacemark *) placemark { CLLocationCoordinate2D coordinate = placemark.location.coordinate; // 添加MapView MKCoordinateSpan span = MKCoordinateSpanMake(0.01, 0.01);<span style="white-space:pre"> </span>// 跨度(比例) MKCoordinateRegion region = MKCoordinateRegionMake(coordinate, span); // 范围、区域 [mapView setRegion:region]; [self.view addSubview: mapView]; }此处只需设置mapView的显示区域,使用如下结构体:
typedef struct{
CLLocationCoordinate2D center; // 中心点
MKCoordinateSpan Span; // 跨度
}MKCoodinateRegion;
结构体初始化使用 MKCoodinateRegionMake函数,其第一个参数指定了目标区域中心点,第二个设置目标区域的跨度
而显示跨度的结构体MKCoordinateSpan的定义为:
typedef struct{
CLLocationDegress latitudeDelta; // 区域的南北跨度
CLLocationDegress longtitudeDelta; // 区域的东西跨度
}MKCoordinateSpan;
南北跨度1度大约是111公里,东西跨度在赤道上1度大约是111公里,越靠近两极,这个距离在逐渐减小,在极点是变为0公里。
最后使用setRegion函数,为mapView设置显示区域。
2、添加标注
首先要引用它的头文件<MapKit/MKAnnotation.h>,
首先设置标注点,需使用MKPointAnnotation类,它主要有以下三个属性
- (NSString *) titile; 标注点的主标题
- (NSString *)subtitle; 标注点的副标题
- (CLLocationCoordinate2D) coordinate; // 标注点的位置信息
在设置好以上三个属性后,直接使用addAnnotation函数将标注点添加进mapView。
这部分代码还是在上面的showInMapView: 函数中,代码如下
- (void) showInMapView: (CLPlacemark *) placemark { CLLocationCoordinate2D coordinate = placemark.location.coordinate; // 添加MapView MKCoordinateSpan span = MKCoordinateSpanMake(0.01, 0.01); MKCoordinateRegion region = MKCoordinateRegionMake(coordinate, span); [mapView setRegion:region animated:YES]; [self.view addSubview: mapView]; // 添加Annotation MKPointAnnotation *annotaion = [[MKPointAnnotation alloc] init]; annotaion.coordinate = coordinate; annotaion.title = placemark.locality; annotaion.subtitle = placemark.name; [mapView addAnnotation: annotaion]; }
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation { MKPinAnnotationView *annotaionView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"PIN_ANNOTATION"]; if (annotaionView == nil) { annotaionView = [[MKPinAnnotationView alloc] initWithAnnotation: annotation reuseIdentifier:@"PIN_ANNOTATION"]; } annotaionView.pinColor = MKPinAnnotationColorRed;<span style="white-space:pre"> </span>// 标注点颜色 annotaionView.animatesDrop = YES;<span style="white-space:pre"> </span>// 动画 annotaionView.canShowCallout = YES;<span style="white-space:pre"> </span>// 插图编号 return annotaionView; }其中 (MBAnnotationView *) - dequeueReusableAnnotationViewWithIdentifier: 通过标识符返回可复用的标注视图
开启地图的showsUserLocation属性,并设置方法setUserTrackMode:即可实现跟踪用户的位置和方向变化。
mapView.showsUserLocation = YES; [mapView setUserTrackingMode:MKUserTrackingModeFollowWithHeading animated:YES];其中用户跟踪模式有以下三种:
MKUserTrackingModeNone 没有用户跟踪模式
MKUsetTrackingModeFollow 跟踪用户的位置变化
MKUserTrackingModeFollowWithHeading 跟踪用户位置和方向变化
同时还需实现地图视图的委托方法mapView:didUpdataUserLocation:
- (void) mapView:(MKMapView *) mapView didUpdateUserLocation:(MKUserLocation *)userLocation { mapView.centerCoordinate = userLocation.location.coordinate; }