iOS 地图 MKWebView(在中国是使用高德地图)

来源:互联网 发布:javascript 构造函数 编辑:程序博客网 时间:2024/05/22 05:17

一、定位服务介绍

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

五、运行截图




0 0
原创粉丝点击