Apple系列的移动设备定位位置有两种方式,一是使用ArcGIS API for iOS中MapView中的GPS对象来获取当前位置;二是通过iPhone SDK中的CLLocationManager来获取。前者在获取当前位置的时候会受到设备的限制,如iPod Touch、iPad wifi版都是没有GPS模块的,因此,在使用mapView中的GPS对象时会失效,无法进行定位;后者在获取定位信息的时候,移动设备会首先使用 GPS,如果GPS无效则使用wifi或者蜂窝网络进行定位,这样,即便iPod Touch、iPad wifi版在联网情况下同样可以进行定位。
我们首先认识一下mapView的GPS对象。
1. – (void)viewDidLoad {
2. [super viewDidLoad];
3. //启动GPS
4. [self.mapView.gps start];
5. //检测GPS设备是否启动;
6. if (!self.mapView.gps.enabled) {
7. NSLog(@”The GPS is not enabled”);
8. }
9. else {
10. NSLog(@”The GPS is enabled”);
11. }
12. }
鉴于前文分析的使用mapView中GPS对象的局限性,下面来介绍CLLocationManager的地图定位。
1、 按照【ArcGIS API for iOS开发之旅】mapView中介绍的步骤创建好一个基本的地图应用程序,命名为GeoLocatorDemo
2、 将CoreLocation.framework加入到工程引用中
3、 打开GeoLocatorDemoViewController.h文件,定义CLLocationManager对象,并定义为属性;添加CLLocationManagerDelegate代理,代码如下:
1. @interface GeoLocatorDemoViewController : UIViewController<CLLocationManagerDelegate,AGSMapViewDelegate> {
2. AGSMapView *mapView;
3. AGSGraphicsLayer *graphicsLayer;
4. AGSTiledMapServiceLayer *tiledLayer;
5. CLLocationManager *locationManager;
6. }
7. @property (nonatomic, retain) IBOutlet AGSMapView *mapView;
8. @property (nonatomic, retain) AGSGraphicsLayer *graphicsLayer;
9. @property (nonatomic, retain) AGSTiledMapServiceLayer *tiledLayer;
10. @property (nonatomic, retain) CLLocationManager *locationManager;
4、 打开GeoLocatorDemoViewController.m文件,在viewDidLoad函数中初始化locationManager,代码如下:
1. – (void)viewDidLoad {
2. [super viewDidLoad];
3. self.mapView.mapViewDelegate = self;
4. self.tiledLayer = [[AGSTiledMapServiceLayer alloc]
5. initWithURL:[NSURL URLWithString:kTiledMapServiceURL ]];
6. [self.mapView addMapLayer:tiledLayer withName:@"Tiled Layer"];
7. self.graphicsLayer = [AGSGraphicsLayer graphicsLayer];
8. [self.mapView addMapLayer:self.graphicsLayer withName:@"graphicsLayer"];
9. self.locationManager = [[[CLLocationManager alloc] init] autorelease];
10. self.locationManager.delegate = self; // send loc updates to myself
11. self.locationManager.distanceFilter = 1000; // 1 kilometer
12. self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
13. }
5、 实现AGSMapViewDelegate中的mapViewDidLoad函数,在该函数中启动位置的监控,代码如下:
[self.locationManager startUpdatingLocation];
6、 实现CLLocationManagerDelegate中的-(void)locationManager: (CLLocationManager *)manager didUpdateToLocation: (CLLocation *)newLocation fromLocation: (CLLocation *)oldLocation方法,用于获取地理位置信息。在该方法中首先获取位置信息,之后将获取的经纬度信息转换成Web 墨卡托坐标信息,用来在地图上定位;最后漫游到指定级别
1. – (void)locationManager:(CLLocationManager *)manager
2. didUpdateToLocation:(CLLocation *)newLocation
3. fromLocation:(CLLocation *)oldLocation
4. {
5. NSLog(@”Location: %@”, [newLocation description]);
6. [self.locationManager stopUpdatingLocation];
7. CGPoint pnt;
8. //获取位置信息
9. pnt.x = newLocation.coordinate.longitude;
10. pnt.y = newLocation.coordinate.latitude;
11. //坐标转换
12. CGPoint mecPoint = [self lonLat2Mercator:pnt];
13. AGSPoint *mappoint =[[AGSPoint alloc] initWithX:mecPoint.x y:mecPoint.y spatialReference:nil ];
14. [self.graphicsLayer removeAllGraphics];
15. AGSPictureMarkerSymbol *pt;
16. pt = [AGSPictureMarkerSymbol pictureMarkerSymbolWithImageNamed:@"pushpin.png"];
17. // this offset is to line the symbol up with the map was actually clicked
18. pt.xoffset = 8;
19. pt.yoffset = -18;
20. AGSGraphic *pushpin = [[AGSGraphic alloc] initWithGeometry:mappoint symbol:pt attributes:nil infoTemplate:nil];
21. // add pushpin to graphics layer
22. [self.graphicsLayer addGraphic:pushpin];
23. [pushpin release];
24. [self.graphicsLayer dataChanged];
25. //漫游到指定级别
26. [self.mapView centerAtPoint:mappoint animated:YES];
27. int levelToZoomTo = 12;
28. AGSLOD* lod = [self.tiledLayer.mapServiceInfo.tileInfo.lods objectAtIndex:levelToZoomTo];
29. float zoomFactor = lod.resolution/self.mapView.resolution;
30. AGSMutableEnvelope *newEnv =
31. [AGSMutableEnvelope envelopeWithXmin:self.mapView.envelope.xmin ymin:self.mapView.envelope.ymin
32. xmax:self.mapView.envelope.xmax ymax:self.mapView.envelope.ymax spatialReference:self.mapView.spatialReference];
33. [newEnv expandByFactor:zoomFactor];
34. [self.mapView zoomToEnvelope:newEnv animated:YES];
35. }