Core Location和MapKit的一些简单使用

来源:互联网 发布:windows共享文件夹密码 编辑:程序博客网 时间:2024/05/19 05:31
来自http://blog.csdn.net/nerohoop/article/details/7529562

Core Location

1. 基本对象是CLLocation,有属性coordinate, altitude, horizontal/vertical Accuracy, timestamp, speed, course

<span style="font-size:18px;">typedef {CLLocationDegrees latitude; // a doubleCLLocationDegrees longitude; // a double } CLLocationCoordinate2D;    // 经纬度</span>

@property (readonly) CLLocationAccuracy horizontalAccuracy; // in meters @property (readonly) CLLocationAccuracy verticalAccuracy;kCLLocationAccuracyBestForNavigation;kCLLocationAccuracyBest;kCLLocationAccuracyNearestTenMeters;kCLLocationAccuracyHundredMeters;kCLLocationAccuracyKilometer;kCLLocationAccuracyThreeKilometers;


- (CLLocationDistance)distanceFromLocation:(CLLocation *)otherLocation; // in meters 两个位置之间的距离

2. 总是通过CLLocationManager来获取CLLocation(通过其代理),其一般的使用方法为:

(1)检查硬件是否支持你需要的位置更新

(2)创建一个CLLocationManager实例,并设置接收更新的代理对象

(3)根据你的需求对CLLocationManager进行配置

(4)启动CLLocationManager来监视改变。


3. Core Location Manager的一些设置

@property CLLocationAccuracy desiredAccuracy; // always set this as low as possible @property CLLocationDistance distanceFilter; - (void)startUpdatingLocation;- (void)stopUpdatingLocation;- (void)startMonitoringSignificantLocationChanges;- (void)stopMonitoringSignificantLocationChanges;

Core Location框架提供了三种用于追踪设备当前位置的服务

  • The significant-change location

    service 提供了低耗电的方法来获取当前位置,当前位置改变时会发出通知
  • The standard location service 提供了一种可设置的方法来获取当前位置

  • Region monitoring 监视特定地区的跨越

Listing 1  Starting the standard location service- (void)startStandardUpdates{    // 创建location manager    if (nil == locationManager)        locationManager = [[CLLocationManager alloc] init];     locationManager.delegate = self;  // 设置获取位置的精确度,越精确越耗电    locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;     // 设置距离过滤器,超过次距离就更新一次位置    locationManager.distanceFilter = 500;     [locationManager startUpdatingLocation];}

Listing 2 Significant-Change Location Service- (void)startSignificantChangeUpdates{    // Create the location manager if this object does not    // already have one.    if (nil == locationManager)        locationManager = [[CLLocationManager alloc] init];     locationManager.delegate = self;    [locationManager startMonitoringSignificantLocationChanges];}

4. 检查硬件

+ (BOOL)locationServicesEnabled; // has the user enabled location monitoring in Settings? + (BOOL)headingAvailable; // can this hardware provide heading info (compass)? + (BOOL)significantLocationChangeMonitoringAvailable; // only if device has cellular?+ (BOOL)regionMonitoringAvailable; // only certain iOS4 devices+ (BOOL)regionMonitoringEnabled; // by the user in Settings

当程序初次使用位置服务时,会询问用户。可以提供一个string来描述使用目的。如果用户拒绝,则上面所有方法均返回NO

 @property (copy) NSString *purpose


5. 获取位置更新

// Delegate method from the CLLocationManagerDelegate protocol.- (void)locationManager:(CLLocationManager *)manager    didUpdateToLocation:(CLLocation *)newLocation    fromLocation:(CLLocation *)oldLocation{    // If it's a relatively recent event, turn off updates to save power    NSDate* eventDate = newLocation.timestamp;    NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];    if (abs(howRecent) < 15.0)    {        NSLog(@"latitude %+.6f, longitude %+.6f\n",                newLocation.coordinate.latitude,                newLocation.coordinate.longitude);    }    // else skip the event and process the next one.}

- (void)locationManager:(CLLocationManager *)manager       didFailWithError:(NSError *)error;typedef enum {   kCLErrorLocationUnknown  = 0,   kCLErrorDenied,                           // 如果用户拒绝开启位置服务,那么应该停止location manager   kCLErrorNetwork,   kCLErrorHeadingFailure,   kCLErrorRegionMonitoringDenied,   kCLErrorRegionMonitoringFailure,   kCLErrorRegionMonitoringSetupDelayed,} CLError;

6. Geocoding Location Data

Geocoder对象使用网络服务来将经纬度转换为具体地址信息,iOS当前只支持经纬度转地址信息,不能将位置信息转换为经纬度

创建一个MKReverseGeocoder实例,设置代理,调用start方法。
代理会接受到 reverseGeocoder:didFindPlacemark:和reverseGeocoder:didFailWithError: 


@implementation MyGeocoderViewController (CustomGeocodingAdditions)  - (void)geocodeLocation:(CLLocation*)location forAnnotation:(MapLocation*)annotation  {      MKReverseGeocoder* theGeocoder = [[MKReverseGeocoder alloc] initWithCoordinate:location.coordinate];         theGeocoder.delegate = self;      [theGeocoder start];  }     // Delegate methods  - (void)reverseGeocoder:(MKReverseGeocoder*)geocoder didFindPlacemark:(MKPlacemark*)place  {      MapLocation*    theAnnotation = [map annotationForCoordinate:place.coordinate];      if (!theAnnotation)          return;        // Associate the placemark with the annotation.      theAnnotation.placemark = place;         // Add a More Info button to the annotation's view.      MKPinAnnotationView*  view = (MKPinAnnotationView*)[map viewForAnnotation:annotation];      if (view && (view.rightCalloutAccessoryView == nil))      {          view.canShowCallout = YES;          view.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];      }  }     - (void)reverseGeocoder:(MKReverseGeocoder*)geocoder didFailWithError:(NSError*)error  {      NSLog(@"Could not retrieve the specified place information.\n");  }  @end     @implementation MKMapView (GeocoderAdditions)     - (MapLocation*)annotationForCoordinate:(CLLocationCoordinate2D)coord  {      // Iterate through the map view's list of coordinates      // and return the first one whose coordinate matches      // the specified value exactly.      id<MKAnnotation> theObj = nil;         for (id obj in [self annotations])      {          if (([obj isKindOfClass:[MapLocation class]]))          {              MapLocation* anObj = (MapLocation*)obj;                 if ((anObj.coordinate.latitude == coord.latitude) &&                  (anObj.coordinate.longitude == coord.longitude))              {                  theObj = anObj;                  break;              }          }      }        return theObj;  }  @end

MapKit

1. MKMapView 显示地图

2. 地图上可以显示注释(annotation),每个annotation由coordinate,title,subtitle构成,并由MKAnnotationView来显示

3. Annotation可以有一个callout,当annotation view被点击时显示,默认情况下只是显示title和subtitle,不过你可以添加左右accessory views

4. MKMapView显示一个遵守MKAnnotation协议的数组对象


@property (readonly) NSArray *annotations; // contains id <MKAnnotation> objectsMKAnnotation protocol@protocol MKAnnotation <NSObject>@property (readonly) CLLocationCoordinate2D coordinate;@optional@property (readonly) NSString *title;@property (readonly) NSString *subtitle;@end typedef {    CLLocationDegrees latitude;    CLLocationDegrees longitude;} CLLocationCoordinate2D;//5. 管理map view的annotations的方法- (void)addAnnotation:(id <MKAnnotation>)annotation;- (void)addAnnotations:(NSArray *)annotations;- (void)removeAnnotation:(id <MKAnnotation>)annotation;- (void)removeAnnotations:(NSArray *)annotations;6. MKMapView使用跟TableView类似的方法来重用annotation view7. Annotations通过MKAnnotationView的子类显示在地图上,默认为MKPinAnnotationView8. 如果MKAnnotationView的canShowCallout设置为YES,那么点击会显示,同时会调用- (void)mapView:(MKMapView *)sender didSelectAnnotationView:(MKAnnotationView *)aView;//This is a great place to set up the MKAnnotationView‘s callout accessory views lazily.9. MKAnnotationViews的创建方法跟tableviewcell在tableview中的创建类似- (MKAnnotationView *)mapView:(MKMapView *)sender            viewForAnnotation:(id <MKAnnotation>)annotation{    MKAnnotationView *aView = [sender dequeueReusableAnnotationViewWithIdentifier:IDENT];    if (!aView) {        aView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation                                                reuseIdentifier:IDENT];        // set canShowCallout to YES and build aView’s callout accessory views here              }    aView.annotation = annotation; // yes, this happens twice if no dequeue    // maybe load up accessory views here (if not too expensive)?<span style="color: rgb(255, 0, 0);">    // or reset them and wait until mapView:didSelectAnnotationView: to load actual data</span>    return aView;}10. MKAnnotationView的一些属性@property id <MKAnnotation> annotation; // the annotation; treat as if readonly @property UIImage *image; // instead of the pin, for example@property UIView *leftCalloutAccessoryView; // maybe a UIImageView@property UIView *rightCalloutAccessoryView; // maybe a “disclosure” UIButton @property BOOL enabled; // NO means it ignores touch events, no delegate method, no callout @property CGPoint centerOffset; // where the “head of the pin” is relative to the image @property BOOL draggable; // only works if the annotation implements setCoordinate:11. 如果你设置一个callout accessory view为一个UIControle.g. aView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; The following MKMapViewDelegate method will get called when the accessory view is touched ...- (void)mapView:(MKMapView *)sender         annotationView:(MKAnnotationView *)aView        calloutAccessoryControlTapped:(UIControl *)control;12. 使用一下代理方法来加载accessory views-(void)mapView:(MKMapView *)sender didSelectAnnotationView:(MKAnnotationView *)aView {   if ([aView.leftCalloutAccessoryView isKindOfClass:[UIImageView class]]) {          UIImageView *imageView = (UIImageView *)aView.leftCalloutAccessoryView;           imageView.image = ...; // if you do this in a GCD queue, be careful, views are reused!   }}13. 地图类型@property MKMapType mapType;enum {      MKMapTypeStandard = 0,      MKMapTypeSatellite,      MKMapTypeHybrid  };  typedef NSUInteger MKMapType;14. 显示用户当前地址@property BOOL showsUserLocation;@property (readonly) BOOL isUserLocationVisible;@property (readonly) MKUserLocation *userLocation;MKUserLocation is an object which conforms to MKAnnotation which holds the user’s location.15.限制用户对地图的操作16. 控制地图的显示区域@property MKCoordinateRegion region;typedef struct {    CLLocationCoordinate2D center;    MKCoordinateSpan span;} MKCoordinateRegion;typedef struct {    CLLocationDegrees latitudeDelta;    CLLocationDegrees longitudeDelta;}- (void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated; // animate注意:你赋给region属性的值通常不是最终保存的值,在设置显示区域的时候同时//也设置了缩放等级。map view不能显示任意的缩放等级,因此map view会选择一个能够尽可能显示你指定区域大小的缩放等级,然后根据此时显示的区域来保存。@property CLLocationCoordinate2D centerCoordinate;- (void)setCenterCoordinate:(CLLocationCoordinate2D)center animated:(BOOL)animated;17. 地图载入通知Remember that the maps are downloaded from Google earth.- (void)mapViewWillStartLoadingMap:(MKMapView *)sender;- (void)mapViewDidFinishLoadingMap:(MKMapView *)sender;- (void)mapViewDidFailLoadingMap:(MKMapView *)sender withError:(NSError *)error;


0 0