Core Location和MapKit的一些简单使用

 

Core Location

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

 

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

 

 

  1. @property (readonly) CLLocationAccuracy horizontalAccuracy; // in meters   
  2. @property (readonly) CLLocationAccuracy verticalAccuracy;  
  3.   
  4. kCLLocationAccuracyBestForNavigation;  
  5. kCLLocationAccuracyBest;  
  6. kCLLocationAccuracyNearestTenMeters;  
  7. kCLLocationAccuracyHundredMeters;  
  8. kCLLocationAccuracyKilometer;  
  9. kCLLocationAccuracyThreeKilometers;  

 

 

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

 

 

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

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

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

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

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

 

3. Core Location Manager的一些设置

  1. @property CLLocationAccuracy desiredAccuracy; // always set this as low as possible   
  2. @property CLLocationDistance distanceFilter;   
  3.   
  4. - (void)startUpdatingLocation;  
  5. - (void)stopUpdatingLocation;  
  6.   
  7. - (void)startMonitoringSignificantLocationChanges;  
  8. - (void)stopMonitoringSignificantLocationChanges;  

 

 

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

  • The significant-change location 

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

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

 

 

  1. Listing 1  Starting the standard location service  
  2. - (void)startStandardUpdates  
  3. {  
  4.     // 创建location manager  
  5.     if (nil == locationManager)  
  6.         locationManager = [[CLLocationManager alloc] init];  
  7.    
  8.     locationManager.delegate = self;  
  9.   
  10.   // 设置获取位置的精确度,越精确越耗电  
  11.     locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;  
  12.    
  13.     // 设置距离过滤器,超过次距离就更新一次位置  
  14.     locationManager.distanceFilter = 500;  
  15.    
  16.     [locationManager startUpdatingLocation];  
  17. }  

  1. Listing 2 Significant-Change Location Service  
  2.   
  3. - (void)startSignificantChangeUpdates  
  4. {  
  5.     // Create the location manager if this object does not  
  6.     // already have one.  
  7.     if (nil == locationManager)  
  8.         locationManager = [[CLLocationManager alloc] init];  
  9.    
  10.     locationManager.delegate = self;  
  11.     [locationManager startMonitoringSignificantLocationChanges];  
  12. }  

4. 检查硬件

 

 

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

 

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

 @property (copy) NSString *purpose


5. 获取位置更新

 

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

  1. - (void)locationManager:(CLLocationManager *)manager  
  2.        didFailWithError:(NSError *)error;  
  3.   
  4. typedef enum {  
  5.    kCLErrorLocationUnknown  = 0,  
  6.    kCLErrorDenied,                           // 如果用户拒绝开启位置服务,那么应该停止location manager  
  7.    kCLErrorNetwork,  
  8.    kCLErrorHeadingFailure,  
  9.    kCLErrorRegionMonitoringDenied,  
  10.    kCLErrorRegionMonitoringFailure,  
  11.    kCLErrorRegionMonitoringSetupDelayed,  
  12. } CLError;  


6. Geocoding Location Data

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

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

 

 

  1. @implementation MyGeocoderViewController (CustomGeocodingAdditions)    
  2. - (void)geocodeLocation:(CLLocation*)location forAnnotation:(MapLocation*)annotation    
  3. {    
  4.     MKReverseGeocoder* theGeocoder = [[MKReverseGeocoder alloc] initWithCoordinate:location.coordinate];    
  5.      
  6.     theGeocoder.delegate = self;    
  7.     [theGeocoder start];    
  8. }    
  9.      
  10. // Delegate methods    
  11. - (void)reverseGeocoder:(MKReverseGeocoder*)geocoder didFindPlacemark:(MKPlacemark*)place    
  12. {    
  13.     MapLocation*    theAnnotation = [map annotationForCoordinate:place.coordinate];    
  14.     if (!theAnnotation)    
  15.         return;    
  16.      
  17.    // Associate the placemark with the annotation.    
  18.     theAnnotation.placemark = place;    
  19.      
  20.     // Add a More Info button to the annotation's view.    
  21.     MKPinAnnotationView*  view = (MKPinAnnotationView*)[map viewForAnnotation:annotation];    
  22.     if (view && (view.rightCalloutAccessoryView == nil))    
  23.     {    
  24.         view.canShowCallout = YES;    
  25.         view.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];    
  26.     }    
  27. }    
  28.      
  29. - (void)reverseGeocoder:(MKReverseGeocoder*)geocoder didFailWithError:(NSError*)error    
  30. {    
  31.     NSLog(@"Could not retrieve the specified place information.\n");    
  32. }    
  33. @end    
  34.      
  35. @implementation MKMapView (GeocoderAdditions)    
  36.      
  37. - (MapLocation*)annotationForCoordinate:(CLLocationCoordinate2D)coord    
  38. {    
  39.     // Iterate through the map view's list of coordinates    
  40.     // and return the first one whose coordinate matches    
  41.     // the specified value exactly.    
  42.     id<MKAnnotation> theObj = nil;    
  43.      
  44.     for (id obj in [self annotations])    
  45.     {    
  46.         if (([obj isKindOfClass:[MapLocation class]]))    
  47.         {    
  48.             MapLocation* anObj = (MapLocation*)obj;    
  49.      
  50.             if ((anObj.coordinate.latitude == coord.latitude) &&    
  51.                 (anObj.coordinate.longitude == coord.longitude))    
  52.             {    
  53.                 theObj = anObj;    
  54.                 break;    
  55.             }    
  56.         }    
  57.     }    
  58.     
  59.     return theObj;    
  60. }    
  61. @end  


 

 

 

MapKit

1. MKMapView 显示地图

 

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

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

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

 

  1. @property (readonly) NSArray *annotations; // contains id <MKAnnotation> objects  
  2. <pre name="code" class="plain">MKAnnotation protocol  
  3. @protocol MKAnnotation <NSObject>  
  4. @property (readonly) CLLocationCoordinate2D coordinate;  
  5. @optional  
  6. @property (readonly) NSString *title;  
  7. @property (readonly) NSString *subtitle;  
  8. @end  
  9. typedef {  
  10.     CLLocationDegrees latitude;  
  11.     CLLocationDegrees longitude;  
  12. } CLLocationCoordinate2D;</pre><br>  
  13. <br>  
  14. <pre></pre>  
  15. <p></p>  
  16. <pre></pre>  
  17. <p></p>  
  18. <p><span style="font-size:18px">5. 管理map view的annotations的方法</span></p>  
  19. <p><span style="font-size:18px"></span></p>  
  20. <pre name="code" class="plain">- (void)addAnnotation:(id <MKAnnotation>)annotation;  
  21. - (void)addAnnotations:(NSArray *)annotations;  
  22. - (void)removeAnnotation:(id <MKAnnotation>)annotation;  
  23. - (void)removeAnnotations:(NSArray *)annotations;</pre><br>  
  24. 6. MKMapView使用跟TableView类似的方法来重用annotation view  
  25. <p></p>  
  26. <p><span style="font-size:18px">7. Annotations通过MKAnnotationView的子类显示在地图上,默认为MKPinAnnotationView<br>  
  27. </span></p>  
  28. <p><span style="font-size:18px">8. 如果MKAnnotationView的canShowCallout设置为YES,那么点击会显示,同时会调用</span></p>  
  29. <p><span style="font-size:18px"></span></p>  
  30. <pre name="code" class="plain">- (void)mapView:(MKMapView *)sender didSelectAnnotationView:(MKAnnotationView *)aView;  
  31. //This is a great place to set up the MKAnnotationView‘s callout accessory views lazily.  
  32. </pre>  
  33. <p></p>  
  34. <p><span style="font-size:18px">9. MKAnnotationViews的创建方法跟tableviewcell在tableview中的创建类似</span></p>  
  35. <p><span style="font-size:18px"></span></p>  
  36. <pre name="code" class="plain">- (MKAnnotationView *)mapView:(MKMapView *)sender  
  37.             viewForAnnotation:(id <MKAnnotation>)annotation  
  38. {  
  39.     MKAnnotationView *aView = [sender dequeueReusableAnnotationViewWithIdentifier:IDENT];  
  40.     if (!aView) {  
  41.         aView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation  
  42.                                                 reuseIdentifier:IDENT];  
  43.         // set canShowCallout to YES and build aView’s callout accessory views here   
  44.              }  
  45.     aView.annotation = annotation; // yes, this happens twice if no dequeue  
  46.     // maybe load up accessory views here (if not too expensive)?  
  47. <span style="color:#FF0000;">    // or reset them and wait until mapView:didSelectAnnotationView: to load actual data</span>  
  48.     return aView;  
  49. }  
  50. </pre>  
  51. <p></p>  
  52. <p><span style="font-size:18px">10. MKAnnotationView的一些属性</span></p>  
  53. <p><span style="font-size:18px"></span></p>  
  54. <pre name="code" class="plain">@property id <MKAnnotation> annotation; // the annotation; treat as if readonly   
  55. @property UIImage *image; // instead of the pin, for example  
  56. @property UIView *leftCalloutAccessoryView; // maybe a UIImageView  
  57. @property UIView *rightCalloutAccessoryView; // maybe a “disclosure” UIButton   
  58. @property BOOL enabled; // NO means it ignores touch events, no delegate method, no callout   
  59. @property CGPoint centerOffset; // where the “head of the pin” is relative to the image   
  60. @property BOOL draggable; // only works if the annotation implements setCoordinate:</pre><br>  
  61. <span style="font-size:18px">11. 如果你设置一个callout accessory view为一个UIControl</span>  
  62. <p></p>  
  63. <p><span style="font-size:18px"></span></p>  
  64. <pre name="code" class="plain">e.g. aView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];   
  65. The following MKMapViewDelegate method will get called when the accessory view is touched ...  
  66.   
  67. - (void)mapView:(MKMapView *)sender   
  68.         annotationView:(MKAnnotationView *)aView  
  69.         calloutAccessoryControlTapped:(UIControl *)control;</pre><br>  
  70. <span style="font-size:18px">12. 使用一下代理方法来加载accessory views</span>  
  71. <p></p>  
  72. <p><span style="font-size:18px"></span></p>  
  73. <pre name="code" class="plain">-(void)mapView:(MKMapView *)sender didSelectAnnotationView:(MKAnnotationView *)aView   
  74. {  
  75.    if ([aView.leftCalloutAccessoryView isKindOfClass:[UIImageView class]]) {  
  76.           UIImageView *imageView = (UIImageView *)aView.leftCalloutAccessoryView;   
  77.           imageView.image = ...; // if you do this in a GCD queue, be careful, views are reused!  
  78.    }  
  79. }</pre>  
  80. <p></p>  
  81. <p><span style="font-size:18px">13. 地图类型</span></p>  
  82. <p><span style="font-size:18px"></span></p>  
  83. <pre name="code" class="plain">@property MKMapType mapType;  
  84. <pre name="code" class="plain">enum {    
  85.     MKMapTypeStandard = 0,    
  86.     MKMapTypeSatellite,    
  87.     MKMapTypeHybrid    
  88. };    
  89. typedef NSUInteger MKMapType;  </pre><br>  
  90. <pre></pre>  
  91. <p></p>  
  92. <pre></pre>  
  93. <p></p>  
  94. <p><span style="font-size:18px">14. 显示用户当前地址</span></p>  
  95. <p><span style="font-size:18px"></span></p>  
  96. <pre name="code" class="plain">@property BOOL showsUserLocation;  
  97. @property (readonly) BOOL isUserLocationVisible;  
  98. @property (readonly) MKUserLocation *userLocation;  
  99. MKUserLocation is an object which conforms to MKAnnotation which holds the user’s location.</pre><br>  
  100. <span style="font-size:18px">15.限制用户对地图的操作</span>  
  101. <p></p>  
  102. <p><span style="font-size:18px"></span></p>  
  103. <pre name="code" class="plain">@property BOOL zoomEnabled;  
  104. @property BOOL scrollEnabled;</pre><br>  
  105. <span style="font-size:18px">16. 控制地图的显示区域</span>  
  106. <p></p>  
  107. <p><span style="font-size:18px"></span></p>  
  108. <pre name="code" class="plain">@property MKCoordinateRegion region;  
  109. typedef struct {  
  110.     CLLocationCoordinate2D center;  
  111.     MKCoordinateSpan span;  
  112. } MKCoordinateRegion;  
  113.   
  114. typedef struct {  
  115.     CLLocationDegrees latitudeDelta;  
  116.     CLLocationDegrees longitudeDelta;  
  117. }  
  118. - (void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated; // animate</pre><span style="font-size:18px">注意:</span><br>  
  119. <span style="font-size:18px">你赋给region属性的值通常不是最终保存的值,在设置显示区域的时候同时也设置了缩放等级。map view不能显示任意的缩放等级,因此map view会选择一个能够尽可能显示你指定区域大小的缩放等级,然后根据此时显示的区域来保存。</span><br>  
  120. <br>  
  121. <pre name="code" class="plain">@property CLLocationCoordinate2D centerCoordinate;  
  122. - (void)setCenterCoordinate:(CLLocationCoordinate2D)center animated:(BOOL)animated;</pre><br>  
  123. <span style="font-size:18px">17. 地图载入通知</span>  
  124. <p></p>  
  125. <p><span style="font-size:18px"></span></p>  
  126. <pre name="code" class="plain">Remember that the maps are downloaded from Google earth.  
  127. - (void)mapViewWillStartLoadingMap:(MKMapView *)sender;  
  128. - (void)mapViewDidFinishLoadingMap:(MKMapView *)sender;  
  129. - (void)mapViewDidFailLoadingMap:(MKMapView *)sender withError:(NSError *)error;</pre>  
  130. <p></p>  
  131. <p><span style="font-size:18px">18. <br>  
  132. </span></p>  
  133. <p><span style="font-size:18px"><br>  
  134. </span></p>  
  135. <p><span style="font-size:18px"><br>  
  136. </span></p>  
  137. <p><span style="font-size:18px"><br>  
  138. </span></p>  
  139. <p><span style="font-size:18px"><br>  
  140. </span></p>  
  141. <p><span style="font-size:18px"><br>  
  142. </span></p>  
  143. <p><span style="font-size:18px"><br>  
  144. </span></p>  
  145. <p><br>  
  146. </p>  
  147.   
  148. </pre>  
 
本文转载至 http://blog.csdn.net/nerohoop/article/details/7529562
posted @ 2013-08-22 14:43  天牛  阅读(618)  评论(0编辑  收藏  举报