首页 > 代码库 > iOS定位服务与地图开发(4)---显示地图

iOS定位服务与地图开发(4)---显示地图

iOS 6之前,苹果使用的是谷歌地图,iOS 6之后,苹果使用了自己的地图(国内好像用的是高德地图),但是API编程接口与iOS 5相比没有太大变化。

iOS 应用程序中使用Map Kit API开发地图应用程序,使用MKMapView类作为地图显示视图,其委托协议是MKMapViewDelegate。

1、显示地图:

.h文件中代码

#import <MapKit/MapKit.h>

@interface YXCViewController <MKMapViewDelegate>@end

.m文件类实现代码

@implementation YXCViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // 设置地图的类型
    self.mapView.mapType = MKMapTypeStandard;
    // 设置代理
    self.mapView.delegate = self;
}

#pragma  mark - MKMapViewDelegate代理方法
// 失败回调
- (void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error
{
    NSLog(@"error : %@",error.localizedDescription);
}

@end

地图类型有3种:

MKMapTypeStandard:标准地图。

MKMapTypeSatellite:卫星地图类型。

MKMapTypeHybrid:混合地图类型。

2、添加标注:

如果要在地图视图上添加标注点,需要2个步骤:1)触发添加动作;2)实现地图委托方法mapView:viewForAnnotation:,完成添加标注。

1)触发添加动作:

- (IBAction)geocodeQuery:(id)sender {
    
    // 从界面文本框获取查询地址字符串
    if (_txtQueryKey.text == nil || [_txtQueryKey.text length] == 0) {
        return ;
    }
    
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    
    [geocoder geocodeAddressString:_txtQueryKey.text completionHandler:^(NSArray *placemarks, NSError *error) {
        
        NSLog(@"查询记录数:%i",[placemarks count]);
        
        if ([placemarks count] > 0) {
            // 移除目前地图上所有标注点【否则单击查询按钮,你会发现地图上的标注点越来越多】
            [self.mapView removeAnnotations:_mapView.annotations];
        }
        
        for (int i = 0; i < [placemarks count]; i++) {
            
            CLPlacemark *placemark = placemarks[i];
            // 关闭键盘
            [_txtQueryKey resignFirstResponder];
            
            // 调整地图位置和缩放比例
            MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(placemark.location.coordinate, 1000, 1000);
            [_mapView setRegion:viewRegion animated:YES];
            
            // 实例化自定义的实现了MKAnnotation协议的地图标注点类
            MapLocation *annoation = [[MapLocation alloc] init];
            annoation.streetAddress = placemark.thoroughfare;
            annoation.city = placemark.locality;
            annoation.state = placemark.administrativeArea;
            annoation.zip = placemark.postalCode;
            annoation.coordinate = placemark.location.coordinate;
            
            // 把标注点对象添加到地图上
            // 该方法一定会调用代理方法mapView: viewForAnnotation:
            [_mapView addAnnotation:annoation];
        }
    }];
}

MKCoordinateRegionMakeWithDistance()函数封装了一个表示地图区域的结构体:

typedef struct {

    CLLocationCoordinate2D center;   // 中心点

    MKCoordinateSpan span;  // 跨度

}MKCoordinateRegion ;

2)实现代理方法,完成添加标注

// 委托方法,在地图视图添加标注的时候回调
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    // 获得地图标注对象
    MKPinAnnotationView *annoationView = (MKPinAnnotationView *)[_mapView dequeueReusableAnnotationViewWithIdentifier:@"PIN_ANNOATION"];
    if (annoationView == nil) {
        annoationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"PIN_ANNOATION"];
    }
    // 设置大头针标注视图的颜色为紫色
    annoationView.pinColor= MKPinAnnotationColorPurple;
    // 设置标注视图时候是否动画显示在地图上
    annoationView.animatesDrop = YES;
    // 在标注上可以显示一些附加信息,为YES情况下单击“大头针”时会出现一个气泡
    // 气泡中文字信息封装在MapLocation对象中
    annoationView.canShowCallout = YES;
    
    return annoationView;
}

自定义标注类MapLocation实现:

首先需要引入<Mapkit/MapKit.h>头文件,因为MKAnnotation协议是包含在该框架中。

- (NSString *)title :标注点上的主标题

- (NSString *)subTitle:标注点上副标题

.h头文件中代码:

#import <MapKit/MapKit.h>

@interface MapLocation : NSObject<MKAnnotation>

// 地理坐标
@property (nonatomic , readwrite) CLLocationCoordinate2D coordinate;
// 街道信息属性
@property (nonatomic , copy) NSString *streetAddress;
// 城市信息属性
@property (nonatomic , copy) NSString *city;
// 州、省、市信息
@property (nonatomic , copy) NSString *state;
// 邮编
@property (nonatomic , copy) NSString *zip;

@end

.m中代码:

 

@implementation MapLocation

- (NSString *)title
{
    return @"您的位置!";
}

- (NSString *)subtitle
{
    NSMutableString *ret = [[NSMutableString alloc] init];
    if (_state)
        [ ret appendString:_state];
    if (_city) {
        [ret appendString:_city];
    }
    
    if (_city && _state) {
        [ret appendString:@","];
    }
    if (_streetAddress && (_city || _state || _zip)) {
        [ret appendString:@"?"];
    }
    if (_streetAddress) {
        [ret appendString:_streetAddress];
    }
    
    if (_zip) {
        [ret appendFormat:@",%@",_zip];
    }
    
    return ret;
    
}

 效果图:

3、跟踪用户位置变化:

MapKit提供了跟踪用户位置和方向变化的API,可以不用自己编写定位服务代码。开启地图视图的showsUserLocation属性,并设置方法setUserTrackingMode:就可以了,参考代码如下:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // 设置地图的类型
    self.mapView.mapType = MKMapTypeStandard;
    // 设置代理
    self.mapView.delegate = self;
    
    // 允许跟踪显示用户的位置信息
    self.mapView.showsUserLocation = YES;
    // 设置用户跟踪模式(有3种)
    [self.mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
}
// 实现地图视图的委托方法
// 该方法是在定位服务更新完成用户位置时回调
// 在该方法中重新调整地图的中心点为当前用户的中心点
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
    self.mapView.centerCoordinate = userLocation.location.coordinate;
}