Core Location和MapKit的一些简单使用
Core Location
1. 基本对象是CLLocation,有属性coordinate, altitude, horizontal/vertical Accuracy, timestamp, speed, course
- <span style="font-size:18px;">typedef {
- CLLocationDegrees latitude; // a double
- CLLocationDegrees 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> objects
- <pre name="code" class="plain">MKAnnotation protocol
- @protocol MKAnnotation <NSObject>
- @property (readonly) CLLocationCoordinate2D coordinate;
- @optional
- @property (readonly) NSString *title;
- @property (readonly) NSString *subtitle;
- @end
- typedef {
- CLLocationDegrees latitude;
- CLLocationDegrees longitude;
- } CLLocationCoordinate2D;</pre><br>
- <br>
- <pre></pre>
- <p></p>
- <pre></pre>
- <p></p>
- <p><span style="font-size:18px">5. 管理map view的annotations的方法</span></p>
- <p><span style="font-size:18px"></span></p>
- <pre name="code" class="plain">- (void)addAnnotation:(id <MKAnnotation>)annotation;
- - (void)addAnnotations:(NSArray *)annotations;
- - (void)removeAnnotation:(id <MKAnnotation>)annotation;
- - (void)removeAnnotations:(NSArray *)annotations;</pre><br>
- 6. MKMapView使用跟TableView类似的方法来重用annotation view
- <p></p>
- <p><span style="font-size:18px">7. Annotations通过MKAnnotationView的子类显示在地图上,默认为MKPinAnnotationView<br>
- </span></p>
- <p><span style="font-size:18px">8. 如果MKAnnotationView的canShowCallout设置为YES,那么点击会显示,同时会调用</span></p>
- <p><span style="font-size:18px"></span></p>
- <pre name="code" class="plain">- (void)mapView:(MKMapView *)sender didSelectAnnotationView:(MKAnnotationView *)aView;
- //This is a great place to set up the MKAnnotationView‘s callout accessory views lazily.
- </pre>
- <p></p>
- <p><span style="font-size:18px">9. MKAnnotationViews的创建方法跟tableviewcell在tableview中的创建类似</span></p>
- <p><span style="font-size:18px"></span></p>
- <pre name="code" class="plain">- (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:#FF0000;"> // or reset them and wait until mapView:didSelectAnnotationView: to load actual data</span>
- return aView;
- }
- </pre>
- <p></p>
- <p><span style="font-size:18px">10. MKAnnotationView的一些属性</span></p>
- <p><span style="font-size:18px"></span></p>
- <pre name="code" class="plain">@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:</pre><br>
- <span style="font-size:18px">11. 如果你设置一个callout accessory view为一个UIControl</span>
- <p></p>
- <p><span style="font-size:18px"></span></p>
- <pre name="code" class="plain">e.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;</pre><br>
- <span style="font-size:18px">12. 使用一下代理方法来加载accessory views</span>
- <p></p>
- <p><span style="font-size:18px"></span></p>
- <pre name="code" class="plain">-(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!
- }
- }</pre>
- <p></p>
- <p><span style="font-size:18px">13. 地图类型</span></p>
- <p><span style="font-size:18px"></span></p>
- <pre name="code" class="plain">@property MKMapType mapType;
- <pre name="code" class="plain">enum {
- MKMapTypeStandard = 0,
- MKMapTypeSatellite,
- MKMapTypeHybrid
- };
- typedef NSUInteger MKMapType; </pre><br>
- <pre></pre>
- <p></p>
- <pre></pre>
- <p></p>
- <p><span style="font-size:18px">14. 显示用户当前地址</span></p>
- <p><span style="font-size:18px"></span></p>
- <pre name="code" class="plain">@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.</pre><br>
- <span style="font-size:18px">15.限制用户对地图的操作</span>
- <p></p>
- <p><span style="font-size:18px"></span></p>
- <pre name="code" class="plain">@property BOOL zoomEnabled;
- @property BOOL scrollEnabled;</pre><br>
- <span style="font-size:18px">16. 控制地图的显示区域</span>
- <p></p>
- <p><span style="font-size:18px"></span></p>
- <pre name="code" class="plain">@property MKCoordinateRegion region;
- typedef struct {
- CLLocationCoordinate2D center;
- MKCoordinateSpan span;
- } MKCoordinateRegion;
- typedef struct {
- CLLocationDegrees latitudeDelta;
- CLLocationDegrees longitudeDelta;
- }
- - (void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated; // animate</pre><span style="font-size:18px">注意:</span><br>
- <span style="font-size:18px">你赋给region属性的值通常不是最终保存的值,在设置显示区域的时候同时也设置了缩放等级。map view不能显示任意的缩放等级,因此map view会选择一个能够尽可能显示你指定区域大小的缩放等级,然后根据此时显示的区域来保存。</span><br>
- <br>
- <pre name="code" class="plain">@property CLLocationCoordinate2D centerCoordinate;
- - (void)setCenterCoordinate:(CLLocationCoordinate2D)center animated:(BOOL)animated;</pre><br>
- <span style="font-size:18px">17. 地图载入通知</span>
- <p></p>
- <p><span style="font-size:18px"></span></p>
- <pre name="code" class="plain">Remember that the maps are downloaded from Google earth.
- - (void)mapViewWillStartLoadingMap:(MKMapView *)sender;
- - (void)mapViewDidFinishLoadingMap:(MKMapView *)sender;
- - (void)mapViewDidFailLoadingMap:(MKMapView *)sender withError:(NSError *)error;</pre>
- <p></p>
- <p><span style="font-size:18px">18. <br>
- </span></p>
- <p><span style="font-size:18px"><br>
- </span></p>
- <p><span style="font-size:18px"><br>
- </span></p>
- <p><span style="font-size:18px"><br>
- </span></p>
- <p><span style="font-size:18px"><br>
- </span></p>
- <p><span style="font-size:18px"><br>
- </span></p>
- <p><span style="font-size:18px"><br>
- </span></p>
- <p><br>
- </p>
- </pre>
Core Location和MapKit的一些简单使用的更多相关文章
- iOS 苹果自带地图定位Core Location
Core Location是iOS SDK中一个提供设备位置的框架.可以使用三种技术来获取位置:GPS.蜂窝或WiFi.在这些技术中,GPS最为精准,如果有GPS硬件,Core Location将优先 ...
- iPhone的定位技术与Core Location框架
来源:http://www.cnblogs.com/lovecode/archive/2011/12/24/2300579.html iPhone定位来源通常有:1. GPS定位 2. WiFi定位 ...
- iOS开发-Core Location和Map Kit
一.Core Location确定物理位置 利用以下3种技术: 1.GPS(最精确的) 2.蜂窝基站ID定位(cell ID Location) 3.WPS(Wi-Fi Positioning Ser ...
- 关于Core Location-ios定位
IOS中的core location提供了定位功能,能定位装置的当前坐标,同一时候能得到装置移动信息.由于对定位装置的轮询是非常耗电的,所以最好仅仅在非常必要的前提下启动. 当中,最重要的类是CLLo ...
- IOS开发之Core Location
IOS 支持三种检测当前位置的方式:手机基站.Wi-Fi.和GPS,其中GPS是经度最高的,同时也是最耗费手机电量的.一般情况下在室内是无法通过GPS获 取位置信息的,通过Wi-Fi获取位置的原理是通 ...
- ios中Core Location跟Map Kit的基本使用
地图类开发应用中,离不开地理位置跟MKMapView的使用,下面就记录下自己在使用这两个东西中学到的. 不过并不是所有苹果的设备都支持地理位置,我们在使用前应该做个判断,代码如下: BOOL loca ...
- Core Location :⽤用于地理定位
Core Location :⽤用于地理定位 在移动互联⽹网时代,移动app能解决⽤用户的很多⽣生活琐事,⽐比如 导航:去任意陌⽣生的地⽅方 周边:找餐馆.找酒店.找银⾏行.找电影院 在上述应⽤用中, ...
- 并发编程概述 委托(delegate) 事件(event) .net core 2.0 event bus 一个简单的基于内存事件总线实现 .net core 基于NPOI 的excel导出类,支持自定义导出哪些字段 基于Ace Admin 的菜单栏实现 第五节:SignalR大杂烩(与MVC融合、全局的几个配置、跨域的应用、C/S程序充当Client和Server)
并发编程概述 前言 说实话,在我软件开发的头两年几乎不考虑并发编程,请求与响应把业务逻辑尽快完成一个星期的任务能两天完成绝不拖三天(剩下时间各种浪),根本不会考虑性能问题(能接受范围内).但随着工 ...
- Core Location Framework学习
在Apple开发中,尤其是移动设备开发,经常会使用Core Location Framework,这个框架可以使得iOS设备获取当前的地理位置.本文就具体到Core Location 框架中,查看其声 ...
随机推荐
- mysql海量数据处理步骤
本文转自https://segmentfault.com/a/1190000006158186 当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化: 单表优化 除非单表数据 ...
- golang中map并发读写问题及解决方法
一.map并发读写问题 如果map由多协程同时读和写就会出现 fatal error:concurrent map read and map write的错误 如下代码很容易就出现map并发读写问题 ...
- FATAL ERROR: Could not find ./bin/my_print_defaults 解决方法
FATAL ERROR: Could not find ./bin/my_print_defaults If you compiled from source, you need to run 'ma ...
- 消息中间件系列之Java API操作ActiveMQ
一.依赖 <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activem ...
- C++:在堆上创建对象,还是在栈上?
这篇文章来自于一次讨论:http://www.devbean.net/2013/01/qt-study-road-2-model-view/#comment-17532.关于究竟是在堆上还是在栈上创建 ...
- 【F12】网络面板
使用网络面板了解请求和下载的资源文件并优化网页加载性能 (1)网络面板基础 测量资源加载时间 使用 Network 面板测量您的网站网络性能. Network 面板记录页面上每个网络操作的相关信息,包 ...
- Spring 4 官方文档学习(十一)Web MVC 框架之URI Builder
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-uri-building ...
- c网络编程-多播
/* 编译通过环境,Windows XP sp2,Windows 2003 server SDK,VC++6.0 sp5. */ /********************************** ...
- (转)S5pv210 HDMI 接口在 Linux 3.0.8 驱动框架解析 (By liukun321 咕唧咕唧)
作者:liukun321 咕唧咕唧 日期:2014.1.18 转载请标明作者.出处:http://blog.csdn.net/liukun321/article/details/18452663 本文 ...
- 详解ASP.NET Core Docker部署
前言 在前面文章中,介绍了 ASP.NET Core在 macOS,Linux 上基于Nginx和Jexus的发布和部署,本篇文章主要是如何在Docker容器中运行ASP.NET Core应用程序. ...