这两天抽时间学习了一下IOS下谷歌地图的API 现在很多APP中都会使用谷歌的地图。 个人觉得开发起来还是非常的便利的。废话不多说啦,赶快进入今天的正题。如下所示 这是MOMO的手机,这个项目我是在iPhone上调试的,这正是我的手机,模拟器上我没有试过,模拟器肯定是能打开谷歌地图的,但是好像不能定位地点。大家仔细看我下面的代码描述,其实很简单 真的很简单。本来今天晚上不像写这篇博文的,只是今天的北京雨下的太大了,困住了我回家的路,既然困在了公司那么当然要学习一下啦哈哈哈哈哈哈哈哈哈~~~
OK下面是代码片段。
创建一个工程,如下图所示,先将CoreLocation.framework 和 MapKit.framework 引入工程中,前者是负责定位的,后者是负责地图的。
AppDelegate.h 入口类,没什么好说的我就不解释了。
#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
#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
#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 注意看这个类噢。
#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 所以地图界面中就是一个白屏。那么我将解决的办法贴出来。
//定位成功后将进入此方法
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
myMapView.showsUserLocation =YES;
}
用这个方法来接受当前地图经纬度信息
- (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 不是收费吗
现在可以直接用的。