读书人

IOS 学习笔记(13) map地图

发布时间: 2013-02-02 12:27:16 作者: rapoo

IOS 学习笔记(13) 地图map

定位核心与地图

Core Location以及Map框架包通常能给我们的应用程序添加定位和地图相关的服务。

Core Location框架包通常是使用硬件设备来进行定位服务的,map框架包通常能够使你的应用程序做一些地图展示与交互的相关功能。地图的定位服务一般需要依赖设备的硬件组成部分。所以必须要导入Core Location 和Map这两个框架包。

#import <Core Location/CoreLocation.h>

#import<MapKit/MapKit.h>


创建一个地图的视图


#import <UIKit/UIKit.h>

#import <CoreLocation/CoreLocation.h>

#import <MapKit/MapKit.h>


@interface ViewController :UIViewController

@property(nonatomic,strong)MKMapView *myMapView;

@end


#import "ViewController.h"

@implementation ViewController

@synthesize myMapView;

- (void)viewDidLoad

{

[superviewDidLoad];

self.view.backgroundColor = [UIColorwhiteColor];

myMapView = [[MKMapViewalloc]initWithFrame:self.view.bounds];

myMapView.mapType =MKMapTypeStandard;//普通地图(默认)

myMapView.mapType =MKMapTypeSatellite;//卫星云图

myMapView.mapType =MKMapTypeHybrid;//普通类型来显示普通地图覆盖于卫星云图之上,展现属于复合形式。

myMapView.autoresizingMask =UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

[self.viewaddSubview:myMapView];

}

-(BOOL)shouldAutorotateToOnterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{

return YES;

}

- (void)didReceiveMemoryWarning

{

[superdidReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}


@end


捕获Map视图上的一些动作事件

实现MKMapViewDelegate协议里面的相关方法

mapViewWillStartLoadingMap: 这个方法是当地图界面要加载的时候会调用。

mapView:viewForAnnotation: 这个方法是当地图上有一些动画效果展示或者加载时候会调用这个方法。

mapViewWillStartLocatingUser: 这个方法是准备进行一个位置定位的时候会调用的方法。

mapView:regionDidChangeAnimated:这个方法调用,一般是当用户的地理位置发生变化的时候会调用。



用硬件设备获取当前用户的地理位置

使用CLLocationManager这个类,参考代码如下:

@interface ViewController :UIViewController<MKMapViewDelegate,CLLocationManagerDelegate>

@property(nonatomic,strong)MKMapView *myMapView;

@property(nonatomic,strong)CLLocationManager *myLocationManager;

@end


if([CLLocationManagerlocationServicesEnabled]){

myLocationManager = [[CLLocationManageralloc]init];

myLocationManager.delegate =self;

myLocationManager.purpose =@"To provide functionality based on user's current location.";

[myLocationManagerstartUpdatingLocation];

}else{

NSLog(@"Location services are not enabled");

}

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

NSLog(@"Latitude = %f",newLocation.coordinate.latitude);

NSLog(@"Longitude = %f",newLocation.coordinate.longitude);

}

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

}

CLLocationManager的startUpdateLocation 方法通过它的代理 didUpdateToLocation:fromLocation:和locationManager:didFailWithError:方法来报告用户定位成功或失败。


在地图视图上添加锚点

创建一个类,命名为MyAnnotation,实现MKAnnotation协议。

给这个类定义一个类型为CLLocationCoordinate2D的属性,命名为coordinate。特别要注意这个参数需要标示为只读类型的。因为MKAnnotation这个协议中定义的Coordinate也是只读类型的。

定义两个NSString类型的属性,分别命名为title 和 subtitle。这两个参数用来保存锚点的标题和内容信息。

给这个类添加一个初始化方法,这个方法需要传递一个CLLocationCoordinate2D类型的参数,在这个方法中把CLLocationCoordinate2D的属性传递进来,由于这个属性是只读的,它并不能在这个类的以外进行赋值。因此这个初始化方法也就是一个桥梁,使我们能够正常的往这个子类中进行传值,同理,title和subtitle也要进行类似操作。

初始化myAnnotation这个类,然后把他添加到你的地图中,通过Annotation这个方法。

相关代码如下:

#import <UIKit/UIKit.h>

#import <Foundation/Foundation.h>

#import <MapKit/MapKit.h>


@interface MyAnnotation :NSObject<MKAnnotation>

@property(nonatomic,readonly)CLLocationCoordinate2D coordinate;

@property(nonatomic,copy,readonly)NSString *title;

@property(nonatomic,copy,readonly)NSString *subtitle;

-(id)initWithCoordinates:(CLLocationCoordinate2D)paramCoordinates title:(NSString *)paramTitle subTitle:(NSString *)paramSubTitle;

@end


#import "MyAnnotation.h"


@interface MyAnnotation ()


@end


@implementation MyAnnotation

CLLocationCoordinate2D coordinate;

@synthesize coordinate,title,subtitle;


-(id)initWithCoordinates:(CLLocationCoordinate2D)paramCoordinates title:(NSString *)paramTitle subTitle:(NSString *)paramSubTitle{

self = [superinit];

if(self != nil){

coordinate = paramCoordinates;

title = paramTitle;

subtitle = paramSubTitle;

}

return (self);

}


@end


#import <UIKit/UIKit.h>

#import "MyAnnotation.h"


@interface MapViewController :UIViewController<MKMapViewDelegate>

@property(nonatomic,strong)MKMapView *myMapView;

@end


#import "MapViewController.h"


@interface MapViewController ()


@end


@implementation MapViewController

@synthesize myMapView;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

{

self = [superinitWithNibName:nibNameOrNil bundle:nibBundleOrNil];

if (self) {

// Custom initialization

}

return self;

}


- (void)viewDidLoad

{

[superviewDidLoad];

myMapView = [[MKMapViewalloc]initWithFrame:self.view.bounds];

myMapView.delegate =self;

myMapView.mapType =MKMapTypeStandard;

myMapView.autoresizingMask =UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

[self.viewaddSubview:myMapView];

CLLocationCoordinate2D location =CLLocationCoordinate2DMake(50.82191692907181, -0.138117671012842);

MyAnnotation *annotation = [[MyAnnotationalloc]initWithCoordinates:locationtitle:@"MyTitle"subTitle:@"My Sub Title"];

[myMapViewaddAnnotation:annotation];

}


- (void)didReceiveMemoryWarning

{

[superdidReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}


@end

在地图上添加一些不同颜色的锚点

通过mapView:viewForAnnotation:这个方法来返回一个MKPinAnnotationView实例对象,来进行操作。每一个动画都是添加到一个MKMapView实例化对象的视图上,然后加以显示的。这些视图一般称为动画视图。一个动画视图是一个MKAnnotationView类型的对象。也是UIView的子类。如果一个实现类的对象是一个地图的视图,并且实现了mapView:viewForAnnotation:这个方法,那么这个实现类将会返回一个MKAnnotationView的实例,然后你可以自己添加一个动画的视图效果,从而使他们在地图上得以显示。

MKPinAnnotationView

mapView:viewForAnnotation

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

MKAnnotationView *result = nil;

if([annotation isKindOfClass:[MyAnnotationclass]] == NO){

return result;

}

if ([mapView isEqual:mapView] ==NO) {

return result;

}

MyAnnotation *senderAnnotation = (MyAnnotation *)annotation;

NSString *pinReusableIdentifier = [MyAnnotationreusableIdentifierforPinColor:senderAnnotation.pinColor];

MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapViewdequeueReusableAnnotationViewWithIdentifier:pinReusableIdentifier];

if(annotationView == nil){

annotationView = [[MKPinAnnotationViewalloc]initWithAnnotation:senderAnnotationreuseIdentifier:pinReusableIdentifier];

[annotationViewsetCanShowCallout:YES];

}

annotationView.pinColor = senderAnnotation.pinColor;

result = annotationView;

return result;

}


在地图上添加自定义的锚点

通过UIImage 引入一个你自定义的图片,然后把它绑定到 MKAnnotationView的image这个属性上去,以一个锚点的形式返回到你的地图视图上。代码如下:

#import <UIKit/UIKit.h>

#import <Foundation/Foundation.h>

#import <MapKit/MapKit.h>


#define REUSABLE_PIN_RED @"Red"

#define REUSABLE_PIN_GREEN @"Green"

#define REUSABLE_PIN_PURPLE @"Purple"

@interface MyAnnotation :NSObject<MKAnnotation>

@property(nonatomic,readonly)CLLocationCoordinate2D coordinate;

@property(nonatomic,copy,readonly)NSString *title;

@property(nonatomic,copy,readonly)NSString *subtitle;

@property(nonatomic,unsafe_unretained)MKPinAnnotationColor pinColor;

-(id)initWithCoordinates:(CLLocationCoordinate2D)paramCoordinates title:(NSString *)paramTitle subTitle:(NSString *)paramSubTitle;

+(NSString *)reusableIdentifierforPinColor:(MKPinAnnotationColor)paramColor;

@end


#import "MyAnnotation.h"


@interface MyAnnotation ()


@end


@implementation MyAnnotation

CLLocationCoordinate2D coordinate;

@synthesize coordinate,title,subtitle,pinColor;


-(id)initWithCoordinates:(CLLocationCoordinate2D)paramCoordinates title:(NSString *)paramTitle subTitle:(NSString *)paramSubTitle{

self = [superinit];

if(self != nil){

coordinate = paramCoordinates;

title = paramTitle;

subtitle = paramSubTitle;

}

return (self);

}


+(NSString *)reusableIdentifierforPinColor:(MKPinAnnotationColor)paramColor{

NSString *result = nil;

switch (paramColor) {

caseMKPinAnnotationColorRed:{

result =REUSABLE_PIN_RED;

break;

}

caseMKPinAnnotationColorGreen:{

result =REUSABLE_PIN_GREEN;

break;

}

caseMKPinAnnotationColorPurple:{

result =REUSABLE_PIN_PURPLE;

break;

}

}

return result;

}

@end


#import <UIKit/UIKit.h>

#import "MyAnnotation.h"


@interface MapViewController :UIViewController<MKMapViewDelegate>

@property(nonatomic,strong)MKMapView *myMapView;

@end


#import "MapViewController.h"


@interface MapViewController ()


@end


@implementation MapViewController

@synthesize myMapView;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

{

self = [superinitWithNibName:nibNameOrNil bundle:nibBundleOrNil];

if (self) {

// Custom initialization

}

return self;

}


- (void)viewDidLoad

{

[superviewDidLoad];

myMapView = [[MKMapViewalloc]initWithFrame:self.view.bounds];

myMapView.delegate =self;

myMapView.mapType =MKMapTypeStandard;

myMapView.autoresizingMask =UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

[self.viewaddSubview:myMapView];

CLLocationCoordinate2D location =CLLocationCoordinate2DMake(50.82191692907181, -0.138117671012842);

MyAnnotation *annotation = [[MyAnnotationalloc]initWithCoordinates:locationtitle:@"MyTitle"subTitle:@"My Sub Title"];

[myMapViewaddAnnotation:annotation];

}

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

MKAnnotationView *result = nil;

if([annotation isKindOfClass:[MyAnnotationclass]] == NO){

return result;

}

if([mapView isEqual:mapView] ==NO){

return result;

}

MyAnnotation *senderAnnotation = (MyAnnotation *)annotation;

NSString *pinReusableIdentifier = [MyAnnotationreusableIdentifierforPinColor:senderAnnotation.pinColor];

MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapViewdequeueReusableAnnotationViewWithIdentifier:pinReusableIdentifier];

if(annotationView == nil){

annotationView = [[MKPinAnnotationViewalloc]initWithAnnotation:senderAnnotationreuseIdentifier:pinReusableIdentifier];

annotationView.canShowCallout =YES;

}

annotationView.pinColor = senderAnnotation.pinColor;

UIImage *pinImage = [UIImageimageNamed:@"BluePin.png"];

if (pinImage != pinImage) {

annotationView.image = pinImage;

}

result = annotationView;

return result;

}

- (void)didReceiveMemoryWarning

{

[superdidReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}


@end

通过一组经纬度数据得到一个地点名称

通过一组经纬度数据得到一个实在的地理位置数据,我们通常称之为逆向地理编码。

创建一个CLGeocoder的实例对象,然后创建一个完整的块对象,这个对象必须要没有返回值,而且要接收两个参数。

一个NSArray类型的地点标记参数,这个参数将会用来保存你讲需要查询的地理位置。

一个NSError类型参数,这个参数将会返回一些地理位置编码信息是否正确的校验信息。

erverseGeocodeLocation:completionHandle 这个方法来进行反向地理位置编码。

#import <UIKit/UIKit.h>

#import <CoreLocation/CoreLocation.h>


@interface AddressViewController :UIViewController

@property(nonatomic,strong)CLGeocoder *myGeocoder;

@end

#import "AddressViewController.h"


@interface AddressViewController ()


@end


@implementation AddressViewController

@synthesize myGeocoder;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

{

self = [superinitWithNibName:nibNameOrNil bundle:nibBundleOrNil];

if (self) {

// Custom initialization

}

return self;

}


- (void)viewDidLoad

{

[superviewDidLoad];

CLLocation *location = [[CLLocationalloc]initWithLatitude:+38.4112810longitude:-122.8409780f];

myGeocoder = [[CLGeocoderalloc]init];

[myGeocoderreverseGeocodeLocation:location completionHandler:^(NSArray *placemarks,NSError *error) {

if (error == nil && [placemarkscount] > 0) {

CLPlacemark *placemark = [placemarks objectAtIndex:0];

NSLog(@"Country = %@",placemark.country);

NSLog(@"Postal Code = %@",placemark.postalCode);

NSLog(@"Locality = %@",placemark.locality);

}elseif (error == nil && [placemarkscount] == 0){

NSLog(@"No results were returned.");

}elseif (error != nil){

NSLog(@"An error occurred = %@",error);

}

}];

}


- (void)didReceiveMemoryWarning

{

[superdidReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}


@end

通过一个有意义的地址得到一组经纬度数据

通过一个地理名称得到一组经纬度数据

通过GLGeocoder 这个类的 geocodeAddressString:completionHandler 这个方法来实现

#import <UIKit/UIKit.h>

#import <CoreLocation/CoreLocation.h>


/*通过一个有意义的地址得到一组经纬度数据*/

@interface GetCodeViewController :UIViewController

@property(nonatomic,strong)CLGeocoder *myGeocoder;

@end


#import "GetCodeViewController.h"


@interface GetCodeViewController ()


@end


@implementation GetCodeViewController

@synthesize myGeocoder;


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

{

self = [superinitWithNibName:nibNameOrNil bundle:nibBundleOrNil];

if (self) {

// Custom initialization

}

return self;

}


- (void)viewDidLoad

{

[superviewDidLoad];

NSString *oreillyAddress =@"1005 Gravenstein Highway North,Sebastopol,CA95472,USA";

myGeocoder = [[CLGeocoderalloc]init];

[myGeocodergeocodeAddressString:oreillyAddress completionHandler:^(NSArray *placemarks,NSError *error) {

if([placemarks count] >0 && error == nil){

NSLog(@"Found %lu placemark(s).",(unsignedlong)[placemarks count]);

CLPlacemark *firstPlacemark = [placemarks objectAtIndex:0];

NSLog(@"Longitude = %f",firstPlacemark.location.coordinate.longitude);

NSLog(@"Latitude = %f",firstPlacemark.location.coordinate.latitude);

}elseif ([placemarks count] ==0 && error == nil){

NSLog(@"@Found no placemarks.");

}elseif (error != nil){

NSLog(@"An error occurred = %@",error);

}

}];

}


- (void)didReceiveMemoryWarning

{

[superdidReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}


@end


读书人网 >操作系统

热点推荐