iOS 地图 MKWebView(在中国是使用高德地图)
2016-07-01 01:40
453 查看
一、定位服务介绍
iOS中有三个定位服务组件:
(1)Wifi定位,通过查询一个Wifi路由器的地理位置的信息。比较省电,iPod touch和iPad也可以采用。
(2)蜂窝基站定位,通过移动运用商基站定位。也适合有3G版本的iPod touch和iPad
(3)GPS卫星定位,通过3-4颗GPS定位位置定位,最为准确,但是耗电量大,不能遮挡。
二、项目引用库介绍
(1)CoreLocation.framework 是开发定位服务应用程序的框架
(2)MapKit.framework 是开发地图应用的框架
三、位置模拟
模拟器定位有6个选项:
(1)None
(2)Custom Location
(3)Apple
(4)City Bicycle Ride
(5)City Run
(6)Freeway Drive
单机"Custom Location"选项,会弹出如下对话框,要求设置待模拟的经纬度
设置后,会触发 “-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations;” 函数,打印如下:
locations = (
"<+26.06400300, +119.3107300> +/- 5.00m (speed -1.00 mps / course -1.00) @ 7/1/16, 4:05:32 PM China Standard Time"
)
注意:如果设置的不是 “Custom Location”,其他的选项我试了一遍,都会报错
触发 “-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error” 函数,打印如下
didFailWithError,error = Error Domain = kCLErrorDomainCode = 0 "(null)"
四、项目实战
(1)ViewController.h
(2)ViewController.m
(3)CustomAnnotation.h
(4)CustomAnnotation.m
五、运行截图
iOS中有三个定位服务组件:
(1)Wifi定位,通过查询一个Wifi路由器的地理位置的信息。比较省电,iPod touch和iPad也可以采用。
(2)蜂窝基站定位,通过移动运用商基站定位。也适合有3G版本的iPod touch和iPad
(3)GPS卫星定位,通过3-4颗GPS定位位置定位,最为准确,但是耗电量大,不能遮挡。
二、项目引用库介绍
(1)CoreLocation.framework 是开发定位服务应用程序的框架
(2)MapKit.framework 是开发地图应用的框架
三、位置模拟
模拟器定位有6个选项:
(1)None
(2)Custom Location
(3)Apple
(4)City Bicycle Ride
(5)City Run
(6)Freeway Drive
单机"Custom Location"选项,会弹出如下对话框,要求设置待模拟的经纬度
设置后,会触发 “-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations;” 函数,打印如下:
locations = (
"<+26.06400300, +119.3107300> +/- 5.00m (speed -1.00 mps / course -1.00) @ 7/1/16, 4:05:32 PM China Standard Time"
)
注意:如果设置的不是 “Custom Location”,其他的选项我试了一遍,都会报错
触发 “-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error” 函数,打印如下
didFailWithError,error = Error Domain = kCLErrorDomainCode = 0 "(null)"
四、项目实战
(1)ViewController.h
// // ViewController.h // MapDemo // // Created by 555chy on 6/30/16. // Copyright © 2016 555chy. All rights reserved. // #import <UIKit/UIKit.h> //CoreLocation.framework #import <CoreLocation/CoreLocation.h> //MapKit.framework #import <MapKit/MapKit.h> //标注@protocol<MKAnnotation> #import "CustomAnnotation.h" @interface ViewController : UIViewController<CLLocationManagerDelegate, MKMapViewDelegate> @end
(2)ViewController.m
// // ViewController.m // MapDemo // // Created by 555chy on 6/30/16. // Copyright © 2016 555chy. All rights reserved. // #import "ViewController.h" @interface ViewController () @property MKMapView *mapView; @property CLLocationManager *locationManager; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. [self initLocationManager]; [self initMapView]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } #pragma mark - CLLocationManagerDelegate 获取当前位置 -(void)initLocationManager { self.locationManager = [[CLLocationManager alloc] init]; self.locationManager.delegate = self; /* extern const CLLocationAccuracy kCLLocationAccuracyBestForNavigation __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0); extern const CLLocationAccuracy kCLLocationAccuracyBest; extern const CLLocationAccuracy kCLLocationAccuracyNearestTenMeters; extern const CLLocationAccuracy kCLLocationAccuracyHundredMeters; extern const CLLocationAccuracy kCLLocationAccuracyKilometer; extern const CLLocationAccuracy kCLLocationAccuracyThreeKilometers; desired 渴望的、想得到的 accuracy 精确性、准确性 */ self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; /* * distanceFilter * Discussion: 讨论、谈论、详述、论述 * Specifies the minimum update distance in meters. Client will not be notified of movements of less * than the stated value, unless the accuracy has improved. Pass in kCLDistanceFilterNone to be * notified of all movements. By default, kCLDistanceFilterNone is used. */ //locationManager.distanceFilter = kCLDistanceFilterNone; self.locationManager.distanceFilter = 1000.0f; } /* This method is deprecated. If locationManager:didUpdateLocations: is implemented, this method will not be called. 当位置变化超过distanceFilter时,会调用该方法(该方法已被废弃,将不会触发该方法) */ -(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { NSLog(@"didUpdateToLocation, newLocation = %@, oldLocation = %@", newLocation, oldLocation); } /* chronological 按时间的前后循序排列的、编年的 locations is an array of CLLocation objects in chronological order. 当位置变化超过distanceFilter时,会调用该方法 */ -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations { NSLog(@"didUpdateLocations, locations = %@", locations); } //如果地图查询错误,则会调用下面的协议函数 -(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { NSLog(@"didFailWithError, error = %@", error); } /* 没有该函数时,运行MKMapView报错 Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first. 除了实现该函数,还要在Info.plist中添加 NSLocationAlwaysUsageDescription String 任意的描述语 NSLocationWhenInUseUsageDescription String 任意的描述语 Discussion: Invoked when the authorization status changes for this application. */ -(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { /* typedef NS_ENUM(int, CLAuthorizationStatus) { // User has not yet made a choice with regards to this application kCLAuthorizationStatusNotDetermined = 0, // This application is not authorized to use location services. Due // to active restrictions on location services, the user cannot change // this status, and may not have personally denied authorization kCLAuthorizationStatusRestricted, // User has explicitly denied authorization for this application, or // location services are disabled in Settings. kCLAuthorizationStatusDenied, // User has granted authorization to use their location at any time, // including monitoring for regions, visits, or significant location changes. kCLAuthorizationStatusAuthorizedAlways NS_ENUM_AVAILABLE(NA, 8_0), // User has granted authorization to use their location only when your app // is visible to them (it will be made visible to them if you continue to // receive location updates while in the background). Authorization to use // launch APIs has not been granted. kCLAuthorizationStatusAuthorizedWhenInUse NS_ENUM_AVAILABLE(NA, 8_0), // This value is deprecated, but was equivalent to the new -Always value. kCLAuthorizationStatusAuthorized NS_ENUM_DEPRECATED(10_6, NA, 2_0, 8_0, "Use kCLAuthorizationStatusAuthorizedAlways") __WATCHOS_PROHIBITED = kCLAuthorizationStatusAuthorizedAlways }; */ switch (status) { case kCLAuthorizationStatusAuthorizedAlways: NSLog(@"didChangeAuthorizationStatus, status = %d(%@)", status, @"kCLAuthorizationStatusAuthorizedAlways"); [self.locationManager startUpdatingLocation]; break; case kCLAuthorizationStatusAuthorizedWhenInUse: NSLog(@"didChangeAuthorizationStatus, status = %d(%@)", status, @"kCLAuthorizationStatusAuthorizedWhenInUse"); [self.locationManager startUpdatingLocation]; break; case kCLAuthorizationStatusDenied: NSLog(@"didChangeAuthorizationStatus, status = %d(%@)", status, @"kCLAuthorizationStatusDenied"); break; case kCLAuthorizationStatusNotDetermined: NSLog(@"didChangeAuthorizationStatus, status = %d(%@)", status, @"kCLAuthorizationStatusNotDetermined"); if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) { //应用在前台的时候可以搜到更新的位置信息 [self.locationManager requestWhenInUseAuthorization]; //应用在前台和后台(suspend或terminated)都可以获取到更新的位置数据信息 //[self.locationManager requestAlwaysAuthorization]; [self.locationManager startUpdatingLocation]; } break; case kCLAuthorizationStatusRestricted: NSLog(@"didChangeAuthorizationStatus, status = %d(%@)", status, @"kCLAuthorizationStatusRestricted"); break; default: break; } } #pragma mark - initMapView 初始化地图控件 -(void)initMapView { self.mapView = [[MKMapView alloc] initWithFrame:self.view.bounds]; self.mapView.zoomEnabled = true; self.mapView.scrollEnabled = true; self.mapView.showsBuildings = true; //显示罗盘 self.mapView.showsCompass = true; self.mapView.showsScale = true; self.mapView.showsTraffic = true; self.mapView.showsUserLocation = true; [self.mapView setDelegate:self]; [self.view addSubview:self.mapView]; /* 2d坐标 我这里用的是 中国福建省福州市工人文化宫的坐标 北纬N26.03‘39“ 东经E119.17‘57“ */ CLLocationCoordinate2D coordinate; //纬度 coordinate.latitude = 26.064003; //经度 coordinate.longitude = 119.310730; //设置地图显示范围 MKCoordinateSpan coordinateSpan; //(0, 180] coordinateSpan.latitudeDelta = 0.01; //(0, 360] coordinateSpan.longitudeDelta = 0.01; //设置地图中心 MKCoordinateRegion coordinateRegion; coordinateRegion.center = coordinate; coordinateRegion.span = coordinateSpan; //MKCoordinateRegionMake(<#CLLocationCoordinate2D centerCoordinate#>, <#MKCoordinateSpan span#>) /* hybrid 杂种的、混合的 satellite 卫星 flyover 立交桥、高架公路 typedef NS_ENUM(NSUInteger, MKMapType) { MKMapTypeStandard = 0, MKMapTypeSatellite, MKMapTypeHybrid, MKMapTypeSatelliteFlyover NS_ENUM_AVAILABLE(10_11, 9_0), MKMapTypeHybridFlyover NS_ENUM_AVAILABLE(10_11, 9_0), } NS_ENUM_AVAILABLE(10_9, 3_0) __WATCHOS_PROHIBITED; */ [self.mapView setMapType:MKMapTypeStandard]; [self.mapView setRegion:coordinateRegion animated:YES]; //在中心点创建标记 [self createAnnotationWithCoordinate:coordinate]; //获取地图中心的地理位置描述 [self initGeocoderWithCoordinate:coordinate]; } #pragma mark - MKAnnotation 在相应的坐标点创建标记 -(void)createAnnotationWithCoordinate:(CLLocationCoordinate2D) coordinate { CustomAnnotation *annotation = [[CustomAnnotation alloc] initWithCoordinate:coordinate]; [self.mapView addAnnotation:annotation]; } #pragma mark - CLGeocoder 将经纬坐标编码对象转化为地理信息的描述对象 -(void)initGeocoderWithCoordinate:(CLLocationCoordinate2D) coordinate { //MKReverseGeocoder is now deprecated. Use CLGeocoder in CoreLocation instead. CLGeocoder *geocoder = [[CLGeocoder alloc] init]; //[NSDate date] 是获取当前时间 CLLocation *location = [[CLLocation alloc] initWithCoordinate:coordinate altitude:kCLDistanceFilterNone horizontalAccuracy:kCLLocationAccuracyBest verticalAccuracy:kCLLocationAccuracyBest timestamp:[NSDate date]]; [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) { //NSLog(@"reverseGeocodeLocation completionHandler, placemarks = %@, error = %@ ", placemarks, error); if(error == nil && placemarks.count > 0) { for(int i=0;i<placemarks.count;i++) { CLPlacemark *placemark = [placemarks objectAtIndex:i]; /* * addressDictionary * * Discussion: * This dictionary can be formatted as an address using ABCreateStringWithAddressDictionary, * defined in the AddressBookUI framework. @property (nonatomic, readonly, copy, nullable) NSDictionary *addressDictionary; // address dictionary properties @property (nonatomic, readonly, copy, nullable) NSString *name; // eg. Apple Inc. @property (nonatomic, readonly, copy, nullable) NSString *thoroughfare; // street name, eg. Infinite Loop @property (nonatomic, readonly, copy, nullable) NSString *subThoroughfare; // eg. 1 @property (nonatomic, readonly, copy, nullable) NSString *locality; // city, eg. Cupertino @property (nonatomic, readonly, copy, nullable) NSString *subLocality; // neighborhood, common name, eg. Mission District @property (nonatomic, readonly, copy, nullable) NSString *administrativeArea; // state, eg. CA @property (nonatomic, readonly, copy, nullable) NSString *subAdministrativeArea; // county, eg. Santa Clara @property (nonatomic, readonly, copy, nullable) NSString *postalCode; // zip code, eg. 95014 @property (nonatomic, readonly, copy, nullable) NSString *ISOcountryCode; // eg. US @property (nonatomic, readonly, copy, nullable) NSString *country; // eg. United States @property (nonatomic, readonly, copy, nullable) NSString *inlandWater; // eg. Lake Tahoe @property (nonatomic, readonly, copy, nullable) NSString *ocean; // eg. Pacific Ocean @property (nonatomic, readonly, copy, nullable) NSArray<NSString *> *areasOfInterest; // eg. Golden Gate Park thorough 彻底的、全面的、充分的、详尽的 thorough 通行、大道、大街 */ NSLog(@"reverseGeocodeLocation placemark, locality = %@,%@, thoroughfare = %@,%@, name = %@", placemark.locality, placemark.subLocality, placemark.thoroughfare, placemark.subThoroughfare, placemark.name); } } }]; } @end
(3)CustomAnnotation.h
// // CustomAnnotation.h // MapDemo // // Created by 555chy on 7/1/16. // Copyright © 2016 555chy. All rights reserved. // #import <Foundation/Foundation.h> #import <MapKit/MapKit.h> //大头针标注 @interface CustomAnnotation : NSObject<MKAnnotation> @property CLLocationCoordinate2D coordinate; @property NSString *title; @property NSString *subtitle; -(id)initWithCoordinate:(CLLocationCoordinate2D)coordinate; @end
(4)CustomAnnotation.m
// // CustomAnnotation.m // MapDemo // // Created by 555chy on 7/1/16. // Copyright © 2016 555chy. All rights reserved. // #import "CustomAnnotation.h" @implementation CustomAnnotation -(id)initWithCoordinate:(CLLocationCoordinate2D)coordinate { if(self = [super init]) { self.coordinate = coordinate; self.title = @"标题"; self.subtitle = @"子标题"; } return self; } @end
五、运行截图
相关文章推荐
- 自定义数据类型 --- 类全解(swift2.3)
- Unity实现剧情对话
- Unity Shaders表面着色器
- Qt5.3.0 for android windows平台下搭建及demo(虫子的博客)
- unity优化—资源优化
- Swift 容器类型总结
- Android4.4中不能发送SD卡就绪广播
- 基于android的远程视频监控系统
- Android中的Service(使用StartService 方式启动)
- sharesdk appid
- Application对象做网站计数器
- 导出数据在代码中加载-骨骼动画在cocos中加载
- object-c的代码例子
- iOS动态获取UIWebView高度
- 浏览器中唤起native app || 跳转到应用商城下载
- Android模拟器无法启动,报错:Cannot set up guest memory ‘android_arm’ Invalid argument的解决方法
- Swift 2.2 Warnings and It’s Solutions – Xcode 7.3
- Bugtags - App 测试 · 从未如此简单
- iOS 通过URL获取图片,并保存到本地
- Android开发中的机型适配和国际化适配的实现;