您的位置:首页 > 其它

cocoa touch layer下面的几个点连载之--CoreLocation

2012-05-31 18:13 204 查看
Core Location框架提供了三种用于追踪设备当前位置的服务,Core Location框架从内置的蜂窝,Wi-Fi或者GPS来获取位置
The significant-change location
service 提供了低耗电的方法来获取当前位置,当前位置改变时会发出通知
The standard location service 提供了一种可设置的方法来获取当前位置
Region monitoring 监视特定地区的跨越

如果程序必须使用位置服务
在程序的info.plist中添加UIRequiredDeviceCapabilities键,它是一个包含多个字符串的数组,然后添加location-services,gps字符串

1.The Standard Location Service 

<span style="font-size:16px;">Listing 1-1  Starting the standard location service
- (void)startStandardUpdates
{
// 创建location manager
if (nil == locationManager)
locationManager = [[CLLocationManager alloc] init];

locationManager.delegate = self;</span>
复制代码
<span style="font-size:16px;">  // 设置获取位置的精确度,越精确越耗电</span>
复制代码
<span style="font-size:16px;">    locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;

// 设置距离过滤器,超过次距离就更新一次位置
locationManager.distanceFilter = 500;

[locationManager startUpdatingLocation];
}</span>
复制代码使用location manager之前一般要检查位置服务是否可用,

<span style="font-size:16px;">+ (BOOL)locationServicesEnabled</span>
复制代码

当位置信息更新时,会给location manager发送消息
2.Significant-Change Location Service
<span style="font-size:16px;">- (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];
}</span>
复制代码可以叫醒在后台的程序

3.Region monitoring Service
使用之前调用CLLocationManager的regionMonitoringAvailable and regionMonitoringEnabled

<span style="font-size:16px;">- (BOOL)registerRegionWithCircularOverlay:(MyCircle*)overlay andIdentifier:(NSString*)identifier
{
// Do not create regions if support is unavailable or disabled.
if ( ![CLLocationManager regionMonitoringAvailable] ||
![CLLocationManager regionMonitoringEnabled] )
return NO;

// If the radius is too large, registration fails automatically,
// so clamp the radius to the max value.
CLLocationDegrees radius = overlay.radius;
if (radius > self.locationManager.maximumRegionMonitoringDistance)
radius = self.locationManager.maximumRegionMonitoringDistance;

// Create the region and start monitoring it.
CLRegion* region = [[CLRegion alloc] initCircularRegionWithCenter:overlay.coordinate
radius:radius identifier:identifier];
[self.locationManager startMonitoringForRegion:region
desiredAccuracy:kCLLocationAccuracyHundredMeters];

[region release];
return YES;
}</span>
复制代码接受位置更新消息

当位置更新时,location manager向其代理发送 locationManager:didUpdateToLocation:fromLocation:

如果无法获取新位置,则发送locationManager:didFailWithError:

<span style="font-size:16px;">// 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.
}
</span>
复制代码位置更新错误 locationManager:didFailWithError:

<span style="font-size:16px;">    if ([error code] != kCLErrorLocationUnknown) {
[self stopUpdatingLocation:NSLocalizedString(@"Error", @"Error")];</span>
复制代码
If the location service is unable to retrieve a location fix right away, it reports a kCLErrorLocationUnknownerror and keeps trying. In such a situation, you can simply ignore the error and wait for a new event.
If the user denies your application’s use of the location service, this method reports a kCLErrorDenied error. Upon receiving such an error, you should stop the location service.
If a heading could not be determined because of strong interference from nearby magnetic fields, this method returns kCLErrorHeadingFailure.

<span style="font-size:16px;">typedef enum {
kCLErrorLocationUnknown  = 0,
kCLErrorDenied,
kCLErrorNetwork,
kCLErrorHeadingFailure,
kCLErrorRegionMonitoringDenied,
kCLErrorRegionMonitoringFailure,
kCLErrorRegionMonitoringSetupDelayed,
} CLError;</span>
复制代码获取移动方向信息

<pre name="code" class="plain"><span style="font-size:16px;">- (void)startHeadingEvents {
if (!self.locationManager) {
CLLocationManager* theManager = [[[CLLocationManager alloc] init] autorelease];

// Retain the object in a property.
self.locationManager = theManager;
self.locationManager.delegate = self;
}

// Start location services to get the true heading.
locationManager.distanceFilter = 1000;
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
[locManager startUpdatingLocation];

// 开始更新移动方向
if ([CLLocationManager headingAvailable]) {
locManager.headingFilter = 5;
[locManager startUpdatingHeading];
}
}  </span>
复制代码
<span style="font-size:16px;">- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {
if (newHeading.headingAccuracy < 0)
return;

// Use the true heading if it is valid.
CLLocationDirection  theHeading = ((newHeading.trueHeading > 0) ?
newHeading.trueHeading : newHeading.magneticHeading);

self.currentHeading = theHeading;
[self updateHeadingDisplays];
}  </span>
复制代码Geocoding Location Data

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

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

<span style="font-size:16px;">@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</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息