iOS 接入谷歌地图

前言

项目为国外服务,所以需要接入谷歌地图。第一次接入,简单总结下。

谷歌地图接入

同百度,高德地图,先去 谷歌开发者中心注册,拿到key,绑定应用的bundleId.

第一步:

通过pod 集成
pod 'GoogleMaps'

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
添加下面的key到plist中,添加定位相关私有信息配置。
<key>LSApplicationQueriesSchemes</key>
<array>
<string>googlechromes</string>
<string>comgooglemaps</string>
</array>
//引入框架
@import GoogleMaps;
AppDelegate 里完成对SDK的注册,完成认证。(key如果异常,地图会加载不出来)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GMSServices provideAPIKey:YOUR_API_KEY];
}

第二步:显示地图。

引入框架,#import <GoogleMaps/GoogleMaps.h>

谷歌地图的视图通过类GMSMapView来展示。
GMSMapView初始化方式:

1
+ (instancetype)mapWithFrame:(CGRect)frame camera:(GMSCameraPosition *)camera;

可以看到camera不能为空,camera可以理解为一个初始定位点,后面我们获得用户的位置之后,可以重新设置用户的位置为定位点。

地图的一些主要属性:

是否启用指南针

1
mapView.settings.compassButton = YES;

仅当启用了My Location 按钮时,My Location 按钮才会出现在屏幕的右下角。 当用户点击该按钮时,如果当前已知用户的位置,摄像头会以动画方式聚焦于用户的当前位置。

1
mapView.settings.myLocationButton = YES;

是否禁用平移和缩放手势

1
2
mapView.settings.scrollGestures = NO;
mapView.settings.zoomGestures = NO;

然后就是大头针,(谷歌地图成其为标记GMSMarker对象),要添加标记,请创建一个包含 position 和 title 的 GMSMarker 对象,并设置其 map,您可以通过将 marker.appearAnimation 属性设置为 kGMSMarkerAnimationPop,从而以动画呈现方式将新标记添加到地图中。

添加标记:

1
2
3
4
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(10, 10);
GMSMarker *marker = [GMSMarker markerWithPosition:position];
marker.title = @"Hello World";
marker.map = mapView;

删除标记(通过将 GMSMarkemap 属性设置为nil,您可以将标记从地图中移除。 或者,您也可以通过调用 GMSMapViewclear 方法移除目前地图上的所有叠层(包括标记)。)

1
marker.map = nil;

清除所有标记,叠层

1
[mapView clear]

标记(大头针的一些属性)
//更改大头针的图片

1
2
marker.icon = [GMSMarker markerImageWithColor:[UIColor blackColor]];
marker.icon = [UIImage imageNamed:@"house"];

自定义大头针,使用iconView属性,iconView 不会响应用户交互,因为它只是一张视图快照

1
marker.iconView = [[UIImageView alloc] initWithImage:house];

添加信息窗口(也就是弹出气泡)

您可以在用户点按标记时,通过信息窗口向其显示信息。 一次只能显示一个信息窗口。 如果用户点按另一个标记,将隐藏当前窗口,并打开新的信息窗口。

信息窗口的内容由 title 和 snippet属性定义。 如果 titlesnippet 属性均为空白或 nil,点击该标记将不会显示信息窗口。

1
2
3
4
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(51.5, -0.127);
GMSMarker *london = [GMSMarker markerWithPosition:position];
london.title = @"London";
london.map = mapView;

使用 `snippet 属性,您可以添加其他文本,该文本将以较小的字体显示在标题下面。 超出信息窗口宽度的字符串将自动换成多行。 特别长的消息可能会被截断

将信息窗口设置为自动刷新

如果您希望信息窗口的新属性或内容在更改后立即显示,而不用等待信息窗口先隐藏更改然后再将其显示,请将标记的tracksInfoWindowChanges设为 YEStrue

1
marker.tracksInfoWindowChanges = YES;

更改信息窗口的位置

息窗口绘制时朝向设备屏幕的相反方向,在其关联标记的上方居中显示。 您可以通过设置 infoWindowAnchor 属性来更改信息窗口相对于标记的位置。 此属性可接受 CGPoint,它定义为(x,y) 偏移,其中 x 和 y 的范围都介于0.01.0之间。默认偏移为(0.5, 0.0),即顶部中心。

1
2
3
4
5
6
7
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(51.5, -0.127);
GMSMarker *london = [GMSMarker markerWithPosition:position];
london.title = @"London";
london.snippet = @"Population: 8,174,100";
london.infoWindowAnchor = CGPointMake(0.5, 0.5);
london.icon = [UIImage imageNamed:@"house"];
london.map = mapView;

至于如何定位,获取用户的位置,使用系统的CLLocationManager

1
2
3
4
5
6
7
8
9
10
11
-(CLLocationManager *)locationManager{
if (!_locationManager) {
_locationManager = [[CLLocationManager alloc]init];
_locationManager.delegate = self;
[_locationManager requestAlwaysAuthorization];//授权方式,如果在后台也需要定位,那就选择 requestAlwaysAuthorization。
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;//最精确的定位
_locationManager.distanceFilter = kCLDistanceFilterNone; // 默认是kCLDistanceFilterNone,也可以设置其他值,表示用户移动的距离小于该范围内就不会接收到通知
}
return _locationManager;
}

遵守协议后,实现下面的代理方法:

1
2
3
4
5
6
7
8
9
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
CLLocation *curLocation = [locations lastObject];
// 通过location 或得到当前位置的经纬度
CLLocationCoordinate2D curCoordinate2D = curLocation.coordinate;
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:curCoordinate2D.latitude longitude:curCoordinate2D.longitude zoom:6];
self.mapView.camera = camera;//这句话很重要很重要,将我们获取到的经纬度转成影像并赋值给地图的camera属性
[self.locationManager stopUpdatingLocation];//定位成功后停止定位
}

最后看一下<GMSMapViewDelegate> 几个常用协议参考,可以类比一下百度或者高德地图,基本大同小异。

//地图即将移动

1
- (void)mapView:(GMSMapView *)mapView willMove:(BOOL)gesture;

在特定坐标点击手势后调用,但仅在未点击标记时调用。

1
- (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate;

在点击标记后调用。

1
- (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker;

在点击标记的信息窗口后调用。

1
- (void)mapView:(GMSMapView *)mapView didTapInfoWindowOfMarker:(GMSMarker *)marker;

end

电脑,手机都需要翻墙。负责地图会加载不出来。