您的位置:首页 > 移动开发 > IOS开发

iOS开发之Map

2015-05-09 19:13 218 查看
二、iOS地图

iOS应用程序中使用Map Kit API开发地图应用程序。

其核心是MKMapView类使用。

多数情况下地图会与定位服务结合使用。

1、添加MapKit类库

MapKit.framework

MapMeViewController.h

#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#import "MapLocation.h"

@interface ViewController : UIViewController<CLLocationManagerDelegate, MKReverseGeocoderDelegate, MKMapViewDelegate> {

}

@property (retain, nonatomic) IBOutlet MKMapView *mapView;
@property (retain, nonatomic) IBOutlet UIActivityIndicatorView *activity;
- (IBAction)findMe:(id)sender;
@end


2、CLLocationManagerDelegate是定位服务委托。

MKMapViewDelegate是地图视图委托,主要方法:

-mapView:viewForAnnotation:

-mapViewDidFailLoadingMap:withError:

MKReverseGeocoderDelegate是给地理坐标获得标志点信息的委托,用于地理信息编码(即:从坐标获得地点获得信息),主要委托方法:

– reverseGeocoder:didFindPlacemark:

– reverseGeocoder:didFailWithError:

m文件中的视图加载和卸载

- (void)viewDidLoad {
[super viewDidLoad];
mapView.mapType = MKMapTypeStandard;
//mapView.mapType = MKMapTypeSatellite;
//mapView.mapType = MKMapTypeHybrid;
mapView.delegate = self;
}


3、mapView.mapType = MKMapTypeStandard;是指定地图的类型,iOS提供了三种风格的地图:

MKMapTypeStandard标准地图模式

MKMapTypeSatellite卫星地图模式

MKMapTypeHybrid具有街道等信息的卫星地图模式

mapView.delegate = self;是将委托对象指定为自身。

按钮事件

- (IBAction)findMe:(id)sender {
CLLocationManager *lm = [[CLLocationManager alloc] init];
lm.delegate = self;
lm.desiredAccuracy = kCLLocationAccuracyBest;
[lm startUpdatingLocation];

activity.hidden = NO;
[activity startAnimating];
}


4、点击按钮时候通过定位服务获取当前位置信息。

通过lm.delegate = self;是将委托对象指定为自身。

因此,点击事件发生时候将会回调CLLocationManagerDelegate委托的

-locationManager:didUpdateToLocation:fromLocation:方法。

回调位置更新方法

#pragma mark CLLocationManagerDelegate Methods
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {

MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 2000, 2000);
//[mapView setRegion:viewRegion animated:YES];
MKCoordinateRegion adjustedRegion = [mapView regionThatFits:viewRegion];
[mapView setRegion:adjustedRegion animated:YES];

manager.delegate = nil;
[manager stopUpdatingLocation];

MKReverseGeocoder *geocoder = [[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate];
geocoder.delegate = self;
[geocoder start];
}


5、MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 2000, 2000); 该函数能够创建一个MKCoordinateRegion结构体,第一个参数是一个CLLocationCoordinate2D结构指定了目标区域的中心点,第二个是目标区域南北的跨度单位是米,第三个是目标区域东西的跨度单位是米。后两个参数的调整会影响地图缩放。

[[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate]; 创建地理编码对象geocoder,通过该对象可以把坐标转换成为地理信息的描述。

geocoder.delegate = self;指定编码的处理是自身对象。

[geocoder start];开始编码处理。

MKReverseGeocoderDelegate

是地理编码委托对象,该委托的方法:

成功时候调用-reverseGeocoder:didFindPlacemark:

失败时候调用-reverseGeocoder:didFailWithError:

成功编码回调方法

- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark {

MapLocation *annotation = [[MapLocation alloc] init];
annotation.streetAddress = placemark.thoroughfare;
annotation.city = placemark.locality;
annotation.state = placemark.administrativeArea;
annotation.zip = placemark.postalCode;
annotation.coordinate = geocoder.coordinate;
[mapView addAnnotation:annotation];

[annotation release];
geocoder.delegate = nil;
[geocoder autorelease];

[activity stopAnimating];
activity.hidden = YES;
}


6、成功编码后需要在该方法中创建标注对象(MapLocation)。MapLocation 是我们自定义的实现MKAnnotation协议标注对象。 该方法的placemark是MKPlacemark获得很多地理信息,详细见下表。

[mapView addAnnotation:annotation]; 为地图添加标注,该方法将会触发mapView:viewForAnnotation:方法回调。

MKPlacemark类属性

addressDictionary 地址信息的dictionary

thoroughfare 指定街道级别信息

subThoroughfare 指定街道级别的附加信息

locality 指定城市信息

subLocality 指定城市信息附加信息

administrativeArea 行政区域

subAdministrativeArea 行政区域附加信息

country 国家信息

countryCode 国家代号

postalCode 邮政编码

失败编码回调方法

- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:@"地理解码错误息"
message:@"地理代码不能识别"
delegate:nil
cancelButtonTitle:@"Ok"
otherButtonTitles:nil];
[alert show];
[alert release];

geocoder.delegate = nil;
[geocoder autorelease];

[activity stopAnimating];
}


7、MKMapViewDelegate

是地图视图委托对象,本例子我们使用的方法:

mapView:viewForAnnotation:为地图设置标注时候回调方法。

-mapViewDidFailLoadingMap:withError:地图加载错误时候回调方法。

地图标注回调方法

pragma mark Map View Delegate Methods
- (MKAnnotationView *) mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>) annotation {

MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"PIN_ANNOTATION"];
if(annotationView == nil) {
annotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:@"PIN_ANNOTATION"] autorelease];
}
annotationView.canShowCallout = YES;
annotationView.pinColor = MKPinAnnotationColorRed;
annotationView.animatesDrop = YES;
annotationView.highlighted = YES;
annotationView.draggable = YES;
return annotationView;
}


8、与表格视图单元格处理类似,地图标注对象由于会很多,因此需要重复利用,通过

dequeueReusableAnnotationViewWithIdentifier方法可以查找可重复利用的标注对象,以达到节省内存的目的。

annotationView.canShowCallout = YES;指定标注上的插图,点击图钉有气泡显示。

annotationView.pinColor 设置图钉的颜色。

annotationView.animatesDrop动画效果。

地图加载失败回调方法

- (void)mapViewDidFailLoadingMap:(MKMapView *)theMapView withError:(NSError *)error {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:@"地图加载错误"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:@"Ok"
otherButtonTitles:nil];
[alert show];
[alert release];
}


9、自定义地图标注对象 用到得地方较多

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface MapLocation : NSObject <MKAnnotation, NSCoding> {
NSString *streetAddress;
NSString *city;
NSString *state;
NSString *zip;

CLLocationCoordinate2D coordinate;
}
@property (nonatomic, copy) NSString *streetAddress;
@property (nonatomic, copy) NSString *city;
@property (nonatomic, copy) NSString *state;
@property (nonatomic, copy) NSString *zip;
@property (nonatomic, readwrite) CLLocationCoordinate2D coordinate;
@end


9、作为地图标注对象实现MKAnnotation协议是必须的,只有实现该协议才能使该类成为标注类。实现NSCoding协议是可选的,实现该协议可以使标注对象能够复制。 里面的属性有哪些要看你自己的需要。

MapLocation.m

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

NSMutableString *ret = [NSMutableString string];
if (streetAddress)
[ret appendString:streetAddress];
if (streetAddress && (city || state || zip))
[ret appendString:@" • "];
if (city)
[ret appendString:city];
if (city && state)
[ret appendString:@", "];
if (state)
[ret appendString:state];
if (zip)
[ret appendFormat:@", %@", zip];

return ret;
}


10、title 和subtitle 是MKAnnotation协议要求实现的方法。

#pragma mark -
- (void)dealloc {
[streetAddress release];
[city release];
[state release];
[zip release];
[super dealloc];
}
#pragma mark -
#pragma mark NSCoding Methods
- (void) encodeWithCoder: (NSCoder *)encoder {
[encoder encodeObject: [self streetAddress] forKey: @"streetAddress"];
[encoder encodeObject: [self city] forKey: @"city"];
[encoder encodeObject: [self state] forKey: @"state"];
[encoder encodeObject: [self zip] forKey: @"zip"];
}
- (id) initWithCoder: (NSCoder *)decoder  {
if (self = [super init]) {
[self setStreetAddress: [decoder decodeObjectForKey: @"streetAddress"]];
[self setCity: [decoder decodeObjectForKey: @"city"]];
[self setState: [decoder decodeObjectForKey: @"state"]];
[self setZip: [decoder decodeObjectForKey: @"zip"]];
}
return self;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: