mapkit实现一

这一节我将用看到那个google的地图,在实现上也相当简便。嵌入地图时需要MKMapView这个类,

它有很多方法和属性,不过如果只是想得到基本的定位功能的话,只需实例化一个对像然后加到当前的

view上就可以了。

<一>先介绍一下,它的几个常用的属性。

 region 用来设置地图的那一部份被显示,它是一个结构体,定义如下:

  typedef struct{

          CLLocationCoordinate2D center;//表示显示的中心

          MKCoordinateSpan span;        //表示比例

}MKCoordinateRegion;

对于MKCoordinateSpan其定义如下:

typedef struct{

CLLocationDegrees latitudeDelta;//这类型在前一节中讲过了,是double型的

CLLocationDegrees longitudeDlta;

}MKCoordinateSpan;

再看一下maptype属性,它用于设置地图的类型,如下所示:

      MapType属性值                 描述

    MKMapTypeStandard           表示标准的街道级地图

    MKMapTypeSatellite          表示卫星图

    MKMapTypeHybird             表示上面两者的混合

其余的就不再一一介绍了,去看看相关的文档即可,在这里已经可以把地图弄出来了。

<二>下面我们把上一节中的代码改一下:

    .h头文件

#import <UIKit/UIKit.h>

#import <CoreLocation/CoreLocation.h>

#import <MapKit/MapKit.h>

@interface CoreLocationViewController : UIViewController

<CLLocationManagerDelegate,MKMapViewDelegate>{

        MKMapView *map;

        CLLocationManager *locManager;

        CLLocationCoordinate2D loc;

}

@property (nonatomic, retain) MKMapView *map;

@property (nonatomic, retain) CLLocationManager *locManager;

- (void)setCurrentLocation:(CLLocation *)location;

@end

    .m源文件

#import "CoreLocationViewController.h"

@implementation CoreLocationViewController

@synthesize map;

@synthesize locManager;

- (void)viewDidLoad {

        map = [[MKMapView alloc]initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 411.0f)];

        map.showsUserLocation = YES;

        [self.view addSubview:map];

        locManager = [[CLLocationManager alloc] init];

        locManager.delegate = self;

        locManager.desiredAccuracy = kCLLocationAccuracyBest;

        locManager.distanceFilter = 100;

        [locManager startUpdatingLocation];

        [super viewDidLoad];

}

/*

- (IBAction) segmentChange:(id)sender {

        if (segmentControl.selectedSegmentIndex == 0) {

                map.mapType = MKMapTypeStandard;

        }

        if (segmentControl.selectedSegmentIndex == 1) {

                map.mapType = MKMapTypeSatellite;

        }

        if (segmentControl.selectedSegmentIndex == 2) {

                map.mapType = MKMapTypeHybrid;

        }

}*/

- (void)dealloc {

        [map release];

        [locManager release];

        [super dealloc];

}

#pragma mark -

#pragma mark Core Location Delegate Methods

- (void)locationManager:(CLLocationManager *)manager

        didUpdateToLocation:(CLLocation *)newLocation

                   fromLocation:(CLLocation *)oldLocation {

        NSLog(@"---------------");

        loc = [newLocation coordinate];

        MKCoordinateRegion region;

        MKCoordinateSpan span;

        span.latitudeDelta=0.1; //zoom level

        span.longitudeDelta=0.1; //zoom level

        NSLog(@"%f",loc.latitude);

        NSLog(@"%f",loc.longitude);

        region.span=span;

        region.center=loc;

        // map.showsUserLocation=NO;

         map.mapType = MKMapTypeStandard;

        [map setRegion:region animated:YES];

        [map regionThatFits:region];

}

- (void)locationManager:(CLLocationManager *)manager

           didFailWithError:(NSError *)error{

        NSString *errorMessage;

        if ([error code] == kCLErrorDenied){

                errorMessage = @"被拒绝访问";

        }

        if ([error code] == kCLErrorLocationUnknown) {

                errorMessage = @"";

        }

        UIAlertView *alert = [[UIAlertView alloc]

                                                  initWithTitle:nil

                                                  message:errorMessage

                                                  delegate:self

                                                  cancelButtonTitle:@"纭畾"

                                                  otherButtonTitles:nil];

        [alert show];

        [alert release];

}

- (void)setCurrentLocation:(CLLocation *)location {

        MKCoordinateRegion region ;

        region.center = location.coordinate;

        region.span.longitudeDelta = 0.15f;

        region.span.latitudeDelta = 0.15f;

        [map setRegion:region animated:YES];

}

@end

效果如下图所示

 

我们在GOOGLE地图上是会看到有一个标注显示出来的,就留着,我们下一小节再来完成。

1、概述
插入MapView,设置Delegate(一般为Controller),Annotations记录兴趣位置点(AnnotationView用来显示兴趣位置点),annotation是可选的,选中的annotation会显示callout,用来显示信息。
2、设置地图显示类型:
mapView.mapType = MKMapTypeStandard;
mapView.mapType = MKMapTypeSatellite;
mapView.mapType = MKMapTypeHybrid; 
3、显示用户位置
设置为可以显示用户位置:
mapView.showsUserLocation = YES; 
判断用户当前位置是否可见(只读属性):
userLocationVisible 
得到用户位置坐标:当userLocationVisible为YES时
CLLocationCoordinate2D coords = mapView.userLocation.location.coordinate; 
4、坐标范围
MKCoordinateRegion用来设置坐标显示范围。
包括两部分:Center(CLLocationCoordinate2D struct,包括latitude和longitude),坐标中心
和Span(MKCoordinateSpan struct,包括latitudeDelta和longitudeDelta),缩放级别
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(center,2000, 2000); 
以上代码创建一个以center为中心,上下各1000米,左右各1000米得区域,但其是一个矩形,不符合MapView的横纵比例
MKCoordinateRegion adjustedRegion = [mapView regionThatFits:viewRegion]; 
以上代码创建出来一个符合MapView横纵比例的区域
[mapView setRegion:adjustedRegion animated:YES]; 
以上代码为:最终显示该区域
5、Delegate
使用MapView须符合MKMapViewDelegate协议
5.1、地图加载Delegate
当需要从Google服务器取得新地图时
mapViewWillStartLoadingMap: 
当成功地取得地图后
mapViewDidFinishLoadingMap: 
当取得地图失败后(建议至少要实现此方法)
mapViewDidFailLoadingMap:withError: 

5.2、范围变化Delegate
当手势开始(拖拽,放大,缩小,双击)
mapView:regionWillChangeAnimated: 
当手势结束(拖拽,放大,缩小,双击)
mapView:regionDidChangeAnimated: 
判断坐标是否在MapView显示范围内:
CLLocationDegrees leftDegrees = mapView.region.center.longitude –(mapView.region.span.longitudeDelta / 2.0);
CLLocationDegrees rightDegrees = mapView.region.center.longitude +(mapView.region.span.longitudeDelta / 2.0);
CLLocationDegrees bottomDegrees = mapView.region.center.latitude –(mapView.region.span.latitudeDelta / 2.0);
CLLocationDegrees topDegrees = self.region.center.latitude +(mapView.region.span.latitudeDelta / 2.0);
if (leftDegrees > rightDegrees) { // Int'l Date Line in View
leftDegrees = -180.0 - leftDegrees;
if (coords.longitude > 0) // coords to West of Date Line
coords.longitude = -180.0 - coords.longitude;
}
If (leftDegrees <= coords.longitude && coords.longitude <= rightDegrees && bottomDegrees <= coords.latitude && coords.latitude <= topDegrees) {
   // 坐标在范围内


6、Annotation
Annotation包含两部分:Annotation Object和Annotation View
Annotation Object必须符合协议MKAnnotation,包括两个方法:title和subtitle,分别用于显示注释的标题和子标题。还有coordinate属性,返回CLLocationCoordinate2D,表示Annotation的位置
然后,需使用mapView:viewForAnnotation: 方法来返回MKAnnotationView或者MKAnnotationView的子类用来显示Annotation(注意:这里显示的不是选中Annotation后的弹出框) 
你可以子类化MKAnnotationView,然后再drawRect:方法里面进行自己的绘制动作(这个方法很蠢)
你完全可以实例化一个MKAnnotationView,然后更改它的image属性,这样很简单。

7、添加移除Annotation
添加一个Annotation
[mapView addAnnotation:annotation]; 
添加一个Annotation数组
[mapView addAnnotations:[NSArray arrayWithObjects:annotation1, annotation2, nil]]; 
移除一个Annotation
removeAnnotation: 
移除一个Annotation数组
removeAnnotations: 
移除所有Annotation
[mapView removeAnnotations:mapView.annotations]; 

8、选中Annotation
一次只能有一个Annotation被选中,选中后会出现CallOut(浮动框)
简单的CallOut显示Title和SubTitle,但你也可以自定义一个UIView作为CallOut(与自定义的TableViewCell一样)
可通过代码选中Annotation:
selectAnnotation:animated: 
或者取消选择:
deselectAnnotation:animated: 

9、显示Annotation
通过mapView:viewForAnnotation: 方法显示Annotation,每在MapView中加入一个Annotation,就会调用此方法
示例(与tableView:cellForRowAtIndexPath: 很相似)

- (MKAnnotationView *) mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>) annotation {
static NSString *placemarkIdentifier = @"my annotation identifier";
if ([annotation isKindOfClass:[MyAnnotation class]]) {
     MKAnnotationView *annotationView = [theMapView dequeueReusableAnnotationViewWithIdentifier:placemarkIdentifier];
if (annotationView == nil) {
         annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:placemarkIdentifier];
annotationView.image = [UIImage imageNamed:@"blood_orange.png"];
}
else
annotationView.annotation = annotation;
return annotationView;
}
return nil;


10、取得真实地址
示例:
初始化MKReverseGeocoder

MKReverseGeocoder *geocoder = [[MKReverseGeocoder alloc] initWithCoordinate:coordinates];
geocoder.delegate = self;
[geocoder start]; 
如果无法处理坐标,则调用reverseGeocoder:didFailWithError: 方法

- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error {
NSLog(@"Error resolving coordinates: %@", [error localizedDescription]);
geocoder.delegate = nil;
[geocoder autorelease];

如果成功,则调用reverseGeocoder:didFindPlacemark: 并把信息存储在MKPlacemark 中
didFindPlacemark:(MKPlacemark *)placemark {
NSString *streetAddress = placemark.thoroughfare;
NSString *city = placemark.locality;
NSString *state = placemark.administrativeArea;
NSString *zip = placemark.postalCode;
// Do something with information
geocoder.delegate = nil;
[geocoder autorelease];
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值