打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
IOS定位核心与地图 - wangwangheng - 博客园
Core Location以及Map框架包通常能给我们的应用程序添加定位和地图相关的服务。Core Location框架包通常是使用硬件设备来进行定位服务的,Map框架包通常能够使你的应用程序做一些地图展示与交互的相关功能。地图的定位服务一般需要依赖设备的硬件组成部分。如果有定位的硬件设备,那么肯定是可以利用地图框架包来进行地图的一些相关的操作。
为了能够在项目中使用到位置服务以及地图展示的相关功能,你必须要导入Core Location Map这两个框架包。如果你不知道怎么做,那么请参照如下步骤。
1.点击你的项目工程图标文件。
2.然后选择target选项,如图1所示。
3.然后选择Build Phase模块栏。
4.然后点开Link Binary With Libraries栏目,在点击 号按钮。
1 添加相关的框架包
5.添加MapKit.framework和CoreLocation.framework这两个库
6.在使用地图和定位的地方,导入:
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
MKMapView是UIView的子类,所以可以像一个普通的View一样添加到ViewController的View当中。
以下是相关的代码
ViewController.h
#import<UIKit/UIKit.h>
#import<CoreLocation/CoreLocation.h>
#import<MapKit/MapKit.h>
#import'MyAnnotation.h'
@interfaceViewController : UIViewController <MKMapViewDelegate,CLLocationManagerDelegate>
// MapView
@property (nonatomic,strong) MKMapView *myMapView;// 地图控件
// LocationManager
@property (nonatomic,strong) CLLocationManager *myLocationManager;// 位置管理器
@property (nonatomic,strong) CLGeocoder *myGeoCoder ;// 地理位置和真实地址转换
@end
ViewController.m
#import'ViewController.h'
#import'MKMapView ZoomLevel.h'
@interfaceViewController ()
@end
@implementation ViewController
@synthesize myMapView;
@synthesize myLocationManager;
@synthesize myGeoCoder;
- (void)viewDidLoad
{
    [superviewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// 设置根View的背景颜色
    self.view.backgroundColor = [UIColor colorWithRed:0x33 / 255.0f green:0x66 / 255.0f blue:0x99 / 255.0f alpha:0xFF / 255.0f];
// 初始化MapView并且设置MapView显示的边界
    self.myMapView = [[MKMapView alloc]initWithFrame:self.view.bounds];
// self.myMapView.mapType = MKMapTypeSatellite;
// self.myMapView.mapType = MKMapTypeHybrid;
    self.myMapView.mapType = MKMapTypeStandard;
    self.myMapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    self.myMapView.delegate= self;
    CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(40.034122, 116.289574);
    MyAnnotation *annotation = [[MyAnnotation alloc]initWithCoordinate:coordinate title:@'我的位置' subTitle:@'这里就是寡人的位置,嘿嘿!'];
    annotation.pinColor = MKPinAnnotationColorPurple;
    [self.myMapView addAnnotation:annotation];
    [self.myMapView setShowsUserLocation:YES];
    [self.myMapView setCenterCoordinate:coordinate zoomLevel:15 animated:YES];
    [self.view addSubview:myMapView];
if([CLLocationManager locationServicesEnabled]){
        self.myLocationManager = [[CLLocationManager alloc]init];
        self.myLocationManager.delegate= self;
// // 提示用户是否允许当前应用使用地理位置,已过时,在Info.plist中使用NSLocationUsageDescription键值替换
// self.myLocationManager.purpose = @'提示用户是否允许当前应用使用位置,已过时';
        [self.myLocationManager startUpdatingLocation];
    }else{
        NSLog(@'>>>>>>>>>> 位置服务不可用 <<<<<<<<<<<<');
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@'提示' message:@'您的位置服务当前不可用,请打开位置服务后重试' delegate:nil cancelButtonTitle:@'确定' otherButtonTitles:nil, nil];
        [alertView show];
    }
    CLLocation *location = [[CLLocation alloc]initWithLatitude:40.034122 longitude:116.289574];
    self.myGeoCoder = [[CLGeocoder alloc]init];
    [self.myGeoCoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks,NSError *error){
if(error == nil && [placemarks count] > 0){
            CLPlacemark *pm = [placemarks objectAtIndex:0];
            NSLog(@'国家:%@' ,pm.country);
            NSLog(@'邮编:%@',pm.postalCode);
            NSLog(@'Locality:%@',pm.locality);
        }elseif(error == nil && [placemarks count] == 0){
            NSLog(@'没有地址返回');
        }elseif(error != nil){
            NSLog(@'出错了:%@',error);
        }
    }];
    [self.myGeoCoder geocodeAddressString:@'中国北京市海淀区花园东路10号高德大厦' completionHandler:^(NSArray *placemarks,NSError *error){
if(nil == error && [placemarks count] > 0){
            NSLog(@'placemarks count:%i',[placemarks count]);
            CLPlacemark *pm = [placemarks objectAtIndex:0];
            NSLog(@'longitude=%f',pm.location.coordinate.longitude);
            NSLog(@'latitude=%f',pm.location.coordinate.latitude);
        }elseif([placemarks count] == 0 && error == nil){
            NSLog(@'找不到给定地址的经纬度');
        }elseif(nil != nil){
            NSLog(@'发生了错误:%@',error);
        }
    }];
}
- (void)didReceiveMemoryWarning
{
    [superdidReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)viewDidUnload
{
    [superviewDidUnload];
    self.myMapView = nil;
    [self.myLocationManager stopUpdatingLocation];
    self.myLocationManager = nil;
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
returnYES;
}
/*******************************************************************************************/
/*******************************************************************************************/
/*************************** MapView的Delegate的方法,全部都是Option的 *************************/
/*******************************************************************************************/
/*******************************************************************************************/
/*******************************************************************************************/
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
    NSLog(@'mapView:regionWillChangeAnimated:方法被调用');
}
// 用户的地理位置发生改变的时候调用
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
    NSLog(@'mapView:regionDidChangeAnimated:方法被调用');
}
// 当地图界面将要加载的时候将会调用这个方法
- (void)mapViewWillStartLoadingMap:(MKMapView *)mapView{
    NSLog(@'mapViewWillStartLoadingMap:方法被调用');
}
// 当地图界面加载完成的时候将要调用这个方法
- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView{
    NSLog(@'mapViewDidFinishLoadingMap:方法被调用');
}
// 当地图界面加载失败的时候调用这个方法
- (void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error{
    NSLog(@'mapViewDidFailLoadingMap:withError:方法被调用,error is:%@' , [error description]);
}
// 添加到地图的Annotation
// mapView:viewForAnnotation: provides the view for each annotation.
// This method may be called for all or some of the added annotations.
// For MapKit provided annotations (eg. MKUserLocation) return nil to use the MapKit provided annotation view.
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    MKAnnotationView *view = nil;
if([annotation isKindOfClass:[MyAnnotation class]] == NO){
returnview;
    }
if([mapView isEqual:self.myMapView] == NO){
returnview;
    }
    MyAnnotation *senderAnnotation = (MyAnnotation*)annotation;
    NSString *pinReusableIdentifier = [MyAnnotation reusableIdentifierForPinColor:senderAnnotation.pinColor];
    MKPinAnnotationView *annotationView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:pinReusableIdentifier];
if(annotationView == nil){
        annotationView = [[MKPinAnnotationView alloc]initWithAnnotation:senderAnnotation reuseIdentifier:pinReusableIdentifier];
        [annotationView setCanShowCallout:YES];
    }
    annotationView.pinColor = senderAnnotation.pinColor;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentPath = [paths objectAtIndex:0];
    NSString *cachePath = [documentPath stringByAppendingString:@'/images'];
    NSString *cacheFile = [cachePath stringByAppendingString:@'icon.image'];
if([[NSFileManager defaultManager]fileExistsAtPath:cacheFile]){
        UIImage *image = [UIImage imageWithContentsOfFile:cacheFile];
if(image != nil){
            annotationView.image = image;
            NSLog(@'通过本地设置图片');
        }else{
            [self setAnnotionImageByUrl:annotationView cacheFile:cacheFile];
        }
    }else{
        [self setAnnotionImageByUrl:annotationView cacheFile:cacheFile];
    }
    view = annotationView;
returnview;
}
-(void) setAnnotionImageByUrl:(MKPinAnnotationView *)annotationView cacheFile:(NSString *) cacheFile{
    NSLog(@'通过网络设置文件');
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        NSURL *url = [NSURL URLWithString:@'http://www.baidu.com/img/duanwulogo_94a0060bda0885d1c2320ca0d7d7c342.gif'];
        NSData *data = [NSData dataWithContentsOfURL:url];
if(data != nil){
            [data writeToFile:cacheFile atomically:YES];
            UIImage *image = [UIImage imageWithData:data];
            dispatch_queue_t mainQueue = dispatch_get_main_queue();
            dispatch_async(mainQueue, ^{
if(image != nil){
                    annotationView.image = image;
                }
            });
        }
    });
}
/**
// mapView:didAddAnnotationViews: is called after the annotation views have been added and positioned in the map.
// The delegate can implement this method to animate the adding of the annotations views.
// Use the current positions of the annotation views as the destinations of the animation.
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views;
// mapView:annotationView:calloutAccessoryControlTapped: is called when the user taps on left & right callout accessory UIControls.
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control;
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view NS_AVAILABLE(NA, 4_0);
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view NS_AVAILABLE(NA, 4_0);
- (void)mapViewWillStartLocatingUser:(MKMapView *)mapView NS_AVAILABLE(NA, 4_0);
- (void)mapViewDidStopLocatingUser:(MKMapView *)mapView NS_AVAILABLE(NA, 4_0);
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation NS_AVAILABLE(NA, 4_0);
- (void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error NS_AVAILABLE(NA, 4_0);
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view didChangeDragState:(MKAnnotationViewDragState)newState
fromOldState:(MKAnnotationViewDragState)oldState NS_AVAILABLE(NA, 4_0);
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay NS_AVAILABLE(NA, 4_0);
// Called after the provided overlay views have been added and positioned in the map.
- (void)mapView:(MKMapView *)mapView didAddOverlayViews:(NSArray *)overlayViews NS_AVAILABLE(NA, 4_0);
- (void)mapView:(MKMapView *)mapView didChangeUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated NS_AVAILABLE(NA, 5_0);
*/
/*******************************************************************************************/
/*******************************************************************************************/
/*************************** 位置相关 *************************/
/*******************************************************************************************/
/*******************************************************************************************/
/*******************************************************************************************/
-(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
{
    NSLog(@'获得位置失败');
}
@end
MKMapView ZoomLevel.h
#import<MapKit/MapKit.h>
@interfaceMKMapView (ZoomLevel)
- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
                  zoomLevel:(NSUInteger)zoomLevel
                   animated:(BOOL)animated;
@end
MKMapView ZoomLevel.m
#import'MKMapView ZoomLevel.h'
@implementation MKMapView (ZoomLevel)
#define MERCATOR_OFFSET 268435456
#define MERCATOR_RADIUS 85445659.44705395
#pragma mark -
#pragma mark Map conversion methods
- (double)longitudeToPixelSpaceX:(double)longitude
{
returnround(MERCATOR_OFFSET MERCATOR_RADIUS * longitude * M_PI / 180.0);
}
- (double)latitudeToPixelSpaceY:(double)latitude
{
returnround(MERCATOR_OFFSET - MERCATOR_RADIUS * logf((1 sinf(latitude * M_PI / 180.0)) / (1 - sinf(latitude * M_PI / 180.0))) / 2.0);
}
- (double)pixelSpaceXToLongitude:(double)pixelX
{
return((round(pixelX) - MERCATOR_OFFSET) / MERCATOR_RADIUS) * 180.0 / M_PI;
}
- (double)pixelSpaceYToLatitude:(double)pixelY
{
return(M_PI / 2.0 - 2.0 * atan(exp((round(pixelY) - MERCATOR_OFFSET) / MERCATOR_RADIUS))) * 180.0 / M_PI;
}
#pragma mark -
#pragma mark Helper methods
- (MKCoordinateSpan)coordinateSpanWithMapView:(MKMapView *)mapView
                             centerCoordinate:(CLLocationCoordinate2D)centerCoordinate
                                 andZoomLevel:(NSUInteger)zoomLevel
{
// convert center coordiate to pixel space
doublecenterPixelX = [self longitudeToPixelSpaceX:centerCoordinate.longitude];
doublecenterPixelY = [self latitudeToPixelSpaceY:centerCoordinate.latitude];
// determine the scale value from the zoom level
    NSInteger zoomExponent = 20 - zoomLevel;
doublezoomScale = pow(2, zoomExponent);
// scale the map's size in pixel space
    CGSize mapSizeInPixels = mapView.bounds.size;
doublescaledMapWidth = mapSizeInPixels.width * zoomScale;
doublescaledMapHeight = mapSizeInPixels.height * zoomScale;
// figure out the position of the top-left pixel
doubletopLeftPixelX = centerPixelX - (scaledMapWidth / 2);
doubletopLeftPixelY = centerPixelY - (scaledMapHeight / 2);
// find delta between left and right longitudes
    CLLocationDegrees minLng = [self pixelSpaceXToLongitude:topLeftPixelX];
    CLLocationDegrees maxLng = [self pixelSpaceXToLongitude:topLeftPixelX scaledMapWidth];
    CLLocationDegrees longitudeDelta = maxLng - minLng;
// find delta between top and bottom latitudes
    CLLocationDegrees minLat = [self pixelSpaceYToLatitude:topLeftPixelY];
    CLLocationDegrees maxLat = [self pixelSpaceYToLatitude:topLeftPixelY scaledMapHeight];
    CLLocationDegrees latitudeDelta = -1 * (maxLat - minLat);
// create and return the lat/lng span
    MKCoordinateSpan span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta);
returnspan;
}
#pragma mark -
#pragma mark Public methods
- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
                  zoomLevel:(NSUInteger)zoomLevel
                   animated:(BOOL)animated
{
// clamp large numbers to 28
    zoomLevel = MIN(zoomLevel, 28);
// use the zoom level to compute the region
    MKCoordinateSpan span = [self coordinateSpanWithMapView:self centerCoordinate:centerCoordinate andZoomLevel:zoomLevel];
    MKCoordinateRegion region = MKCoordinateRegionMake(centerCoordinate, span);
// set the region like normal
    [self setRegion:region animated:animated];
}
@end
MyAnnotation.h
#import<Foundation/Foundation.h>
#import<CoreLocation/CoreLocation.h>
#import<MapKit/MapKit.h>
#define REUSABLE_PIN_RED @'Red'
#define REUSABLE_PIN_GREEN @'Green'
#define REUSABLE_PIN_PURPLE @'Purple'
@interfaceMyAnnotation : NSObject <MKAnnotation>
@property (nonatomic,readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, readonly, copy) NSString *title;
@property (nonatomic, readonly, copy) NSString *subtitle;
@property (nonatomic,unsafe_unretained) MKPinAnnotationColor pinColor;
-(id) initWithCoordinate:(CLLocationCoordinate2D) coordinate
                   title:(NSString*) paramTitle
                subTitle:(NSString*) paramSubTitle;
// 得到颜色
(NSString *) reusableIdentifierForPinColor:(MKPinAnnotationColor) paramColor;
@end
MyAnnotation.m
#import'MyAnnotation.h'
@implementation MyAnnotation
@synthesize coordinate,title,subtitle,pinColor;
-(id) initWithCoordinate
:(CLLocationCoordinate2D) paramCoordinate title:(NSString *)paramTitle subTitle:(NSString *)paramSubTitle
{
    self = [superinit];
if(self != nil){
        coordinate = paramCoordinate;
        title = paramTitle;
        subtitle = paramSubTitle;
        pinColor = MKPinAnnotationColorGreen;
    }
returnself;
}
(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;
    }
returnresult;
}
@end
注意,在使用用户的位置的时候,系统会弹出是否允许应用使用位置的对话框,这个对话框中的提示文字,可以自己进行定义
在系统版本是6.0(包括6.0)以上的时候,在Info.plist文件中进行定义
<key>NSLocationUsageDescription</key>
<string>是否可以使用位置?如果需要使用本应用,是必须的!</string>
在6.0以下,这样进行定义
// // 提示用户是否允许当前应用使用地理位置,已过时,在Info.plist中使用NSLocationUsageDescription键值替换
// self.myLocationManager.purpose = @'提示用户是否允许当前应用使用位置,已过时';
posted on 2013-06-13 21:56wangwangheng阅读(...) 评论(...) 编辑收藏
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
地图与定位(LBS)-MapKit篇
如何使用iOS 7的iBeacons来提高你的应用
【iOS】苹果,百度Map定位使用与总结
iOS中百度地图API的总结
iOS游戏开发游戏功能之外的东西
iOS如何实现从一个navigation的子页面跳转到另一个navigation的子页面
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服