这两天抽时间学习了一下IOS下谷歌地图的API 现在很多APP中都会使用谷歌的地图。 个人觉得开发起来还是非常的便利的。废话不多说啦,赶快进入今天的正题。如下所示 这是MOMO的手机,这个项目我是在iPhone上调试的,这正是我的手机,模拟器上我没有试过,模拟器肯定是能打开谷歌地图的,但是好像不能定位地点。大家仔细看我下面的代码描述,其实很简单 真的很简单。本来今天晚上不像写这篇博文的,只是今天的北京雨下的太大了,困住了我回家的路,既然困在了公司那么当然要学习一下啦哈哈哈哈哈哈哈哈哈~~~
OK下面是代码片段。
创建一个工程,如下图所示,先将CoreLocation.framework 和 MapKit.framework 引入工程中,前者是负责定位的,后者是负责地图的。
AppDelegate.h 入口类,没什么好说的我就不解释了。
1 2 3 4 5 6 7 8 9 10 11 |
#import <UIKit/UIKit.h> #import "MapViewController.h" @interface AppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) UINavigationController *navController; @property (strong, nonatomic) UIViewController *viewController; @end |
AppDelegate.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#import "AppDelegate.h" @implementation AppDelegate @synthesize window = _window; @synthesize navController; @synthesize viewController; - (void)dealloc { [_window release]; [super dealloc]; } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; self.window.backgroundColor = [UIColor whiteColor]; self.viewController = [[MapViewController alloc]init]; self.navController = [[UINavigationController alloc] initWithRootViewController:self.viewController]; [self.window addSubview:navController.view]; [self.window makeKeyAndVisible]; return YES; } @end |
主要的东东都写在MapViewController中,请大家仔细看这里。
MapViewController.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#import <UIKit/UIKit.h> #import <MapKit/MKReverseGeocoder.h> #import <CoreLocation/CoreLocation.h> #import <MapKit/MapKit.h> @interface MapViewController : UIViewController<CLLocationManagerDelegate,MKMapViewDelegate> { //地图视图, 谷歌地图将加载在这个视图中喔 MKMapView *myMapView ; //地图定位管理器 CLLocationManager *_locManager ; } @end |
MapViewController.m 注意看这个类噢。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
#import "MapViewController.h" @implementation MapViewController - (void)dealloc { [_locManager release]; [super dealloc]; } - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.title = @"雨松MOMO"; myMapView = [[[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)] autorelease]; myMapView.delegate = self; //在这里先让地图视图隐藏起来, //等获取当前经纬度完成后在把整个地图显示出来 myMapView.hidden = true; [self.view addSubview:myMapView]; //创建定位管理器, _locManager = [[CLLocationManager alloc] init]; [_locManager setDelegate:self]; [_locManager setDesiredAccuracy:kCLLocationAccuracyBest]; } -(void) viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; //开始使用手机定位,这是一个回调方法, //一旦定位完成后程序将进入 //- (void)locationManager:(CLLocationManager *)manager //didUpdateToLocation:(CLLocation *)newLocation //fromLocation:(CLLocation *)oldLocation //方法中 [_locManager startUpdatingLocation]; } //定位成功后将进入此方法 - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { //得到当前定位后的经纬度,当前经纬度是有一定偏移量的, //使用另一种方法可以很好的解决这个问题 CLLocationCoordinate2D loc = [newLocation coordinate]; float lat = loc.latitude; float lon = loc.longitude; //让MapView使用定位功能。 myMapView.showsUserLocation =YES; //更新地址, [manager stopUpdatingLocation]; //设置定位后的自定义图标。 MKCircle* circle = [MKCircle circleWithCenterCoordinate:CLLocationCoordinate2DMake(myMapView.userLocation.location.coordinate.latitude, myMapView.userLocation.location.coordinate.longitude) radius:5000]; //一定要使用addAnnotation 方法把MKCircle加入进视图, // 否则下面刷新图标的方法是永远不会进入的 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation; //切记!!!! [myMapView addAnnotation:circle]; //我们需要通过当前用户的经纬度换成出它现在在地图中的地名 CLGeocoder *geocoder = [[[CLGeocoder alloc] init] autorelease]; [geocoder reverseGeocodeLocation: _locManager.location completionHandler: ^(NSArray *placemarks, NSError *error) { //得到自己当前最近的地名 CLPlacemark *placemark = [placemarks objectAtIndex:0]; NSString *locatedAt = [[placemark.addressDictionary valueForKey:@"FormattedAddressLines"] componentsJoinedByString:@", "]; //locatedAt就是当前我所在的街道名称 //上图中的中国北京市朝阳区慧中北路 [myMapView.userLocation setTitle:locatedAt]; [myMapView.userLocation setSubtitle:@"雨松MOMO在这里噢"]; //这里是设置地图的缩放,如果不设置缩放地图就非常的尴尬, //只能光秃秃的显示中国的大地图,但是我们需要更加精确到当前所在的街道, //那么就需要设置地图的缩放。 MKCoordinateRegion theRegion = { {0.0, 0.0 }, { 0.0, 0.0 } }; theRegion.center= myMapView.userLocation.location.coordinate; //缩放的精度。数值越小约精准 theRegion.span.longitudeDelta = 0.01f; theRegion.span.latitudeDelta = 0.01f; //让MapView显示缩放后的地图。 [myMapView setRegion:theRegion animated:YES]; //最后让MapView整体显示, 因为截至到这里,我们已经拿到用户的经纬度, //并且已经换算出用户当前所在街道的名称。 myMapView.hidden = false; }]; } //定位失败后将进入此方法 - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { if ( [error code] == kCLErrorDenied ) { //第一次安装含有定位功能的软件时 //程序将自定提示用户是否让当前App打开定位功能, //如果这里选择不打开定位功能, //再次调用定位的方法将会失败,并且进到这里。 //除非用户在设置页面中重新对该软件打开定位服务, //否则程序将一直进到这里。 UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"定位服务已经关闭" message:@"请您在设置页面中打开本软件的定位服务" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil]; [alert show]; [alert release]; [manager stopUpdatingHeading]; } else if ([error code] == kCLErrorHeadingFailure) { } } //在这里我们设置自定义图标来 标志当前我在地图的地方 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation; { static NSString *identifier = @"com.xys.momo"; MKAnnotationView *pin = [ mapView dequeueReusableAnnotationViewWithIdentifier:identifier ]; if ( !pin ) { pin = [ [ MKAnnotationView alloc ] initWithAnnotation:annotation reuseIdentifier:identifier ]; //随便加载了一张ICON //我的icon的大小是48X48 大家可根据仔细的喜好制定自己的icon pin.image = [ UIImage imageNamed:@"0.jpg" ]; //在图中我们可以看到图标的上方,有个气泡弹窗里面写着当前用户的位置所在地 //原因是这里需要设置了True pin.canShowCallout=YES; //上图气泡的右侧还有一个带箭头的小按钮 //这个按钮就是在这里创建的,不过MOMO目前没有写按钮的响应事件喔。 //细心的朋友可以自己加上。 UIButton *btn = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; pin.rightCalloutAccessoryView=btn; } pin.annotation = annotation; return pin; } - (void)viewDidUnload { [super viewDidUnload]; // Release any retained subviews of the main view. } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationPortrait); } @end |
最后是本文的源码下载:http://vdisk.weibo.com/s/acdN7
雨松MOMO祝大家学习愉快、工作愉快、生活愉快、互相学习与进步,加油~ 话说北京这会应该不下雨了吧??雨停了回家睡觉。 嚯嚯!
———————————-华丽的分割线——————————–
以上方法我在IOS6中使用发现了一点小问题,IOS6使用CLLocationManager定位的时候发现有时候定位到的经纬度是0.0000 所以地图界面中就是一个白屏。那么我将解决的办法贴出来。
1 2 3 4 5 6 7 8 9 10 11 |
//定位成功后将进入此方法 - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { myMapView.showsUserLocation =YES; } |
用这个方法来接受当前地图经纬度信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation { //更新地址, [_locManager stopUpdatingLocation]; //设置定位后的自定义图标。 MKCircle* circle = [MKCircle circleWithCenterCoordinate:CLLocationCoordinate2DMake(myMapView.userLocation.location.coordinate.latitude, myMapView.userLocation.location.coordinate.longitude) radius:5000]; [myMapView addAnnotation:circle]; NSLog(@"%f",myMapView.userLocation.location.coordinate.latitude); //我们需要通过当前用户的经纬度换成出它现在在地图中的地名 CLGeocoder *geocoder = [[[CLGeocoder alloc] init] autorelease]; [geocoder reverseGeocodeLocation: _locManager.location completionHandler: ^(NSArray *placemarks, NSError *error) { //得到自己当前最近的地名 CLPlacemark *placemark = [placemarks objectAtIndex:0]; NSString *locatedAt = [[placemark.addressDictionary valueForKey:@"FormattedAddressLines"] componentsJoinedByString:@", "]; //locatedAt就是当前我所在的街道名称 //上图中的中国北京市朝阳区慧中北路 [myMapView.userLocation setTitle:locatedAt]; [myMapView.userLocation setSubtitle:@"你在这里噢"]; nowLatitude = myMapView.userLocation.location.coordinate.latitude; nowLongitude = myMapView.userLocation.location.coordinate.longitude; //这里是设置地图的缩放,如果不设置缩放地图就非常的尴尬, //只能光秃秃的显示中国的大地图,但是我们需要更加精确到当前所在的街道, //那么就需要设置地图的缩放。 MKCoordinateRegion theRegion = { {0.0, 0.0 }, { 0.0, 0.0 } }; theRegion.center= myMapView.userLocation.location.coordinate; //theRegion.center.latitude = targetLatitude; //theRegion.center.longitude = argetLongitude; //缩放的精度。数值越小约精准 theRegion.span.longitudeDelta = 0.01f; theRegion.span.latitudeDelta = 0.01f; //让MapView显示缩放后的地图。 [myMapView setRegion:theRegion animated:YES]; //最后让MapView整体显示, 因为截至到这里,我们已经拿到用户的经纬度, //并且已经换算出用户当前所在街道的名称。 //myMapView.hidden = false; }]; } |
- 本文固定链接: https://www.xuanyusong.com/archives/1504
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!
源码地址没了啊,可以再提供一份吗
能出个u3d 读取百度地图sdk android的示列吗?
楼主,国内谷歌被封了,你是怎么访问到地图的?如果地图可以用,为什么我的就不能显示呢?求解决方案,谢谢
在unity上怎么调用google map 的API啊?
: CGBitmapContextCreate: unsupported parameter combination: 5 integer bits/component; 16 bits/pixel; 3-component color space; kCGImageAlphaNoneSkipLast; 512 bytes/row. 报这个错是什么原因,大侠。
问一下这个定位的只能在实体手机上测试?
好厉害,什么都懂,MOMO,我心中的大神,,,,,请回答我今天问你的问题先把,拜托晒!
请问 地图先隐藏等userlocation位置出现后再显示,中间大概有几秒钟白屏现象,你是怎么解决的?
初学中。。。
好好学习。。
请教一下,我使用你的demo定位,位置是对的,但是地址是有偏移的,是什么原因,有方法解决么?
偏移没有办法, 这个涉及到政治原因 呵呵。。
请教一下MOMO,这个程序用的是google的api吗?mapKit里面有google地图是吗?
现在已经不是谷歌地图了。。
源码下载在真机上运行,有两个图标(把地图缩放到最小),有一个在非洲位置。 MKCircle* circle = [MKCircle circleWithCenterCoordinate:CLLocationCoordinate2DMake(myMapView.userLocation.location.coordinate.latitude, myMapView.userLocation.location.coordinate.longitude) radius:5000];这里的问题。我是新手不知道什么原因,只知道注释掉就不会有上面的情况。CLLocationCoordinate2D loc = [newLocation coordinate]; float lat = loc.latitude; float lon = loc.longitude;这里没有用到…
那个是自定义地图图钉的
MOMO,IOS里面提供的Googl地图跟安卓里面的缩放级别是一样的吗?
一样的
正在学习,谢谢你的文章。写的很好,以后多向你请教
好的
如果直接用谷歌地图的api的话,怎么感觉跟之前ios5不一样了,调用的方式什么的,请问您还有一些资料么
你觉得不一样的地方在哪里?
Google Map 不是收费吗
现在可以直接用的。