美文网首页iOS开发攻城狮的集散地
iOS开发 - 关于谷歌地图的使用总结

iOS开发 - 关于谷歌地图的使用总结

作者: Jackie_123 | 来源:发表于2018-07-23 16:25 被阅读3次

    前段时间遇到项目上需要运用谷歌地图开发,完成之后个人感觉非常的麻烦,主要是相关资料较少,并且谷歌地图的SDK不是特别好啃,并且我相信之后还会有不少人会遇到和我同样的问题,所以今天我在这里做一个比较详细的记录,希望能够帮到有相关需求的人.

    1. 对于iOS开发者,Google地图提供两个开发入口:一个地图的(Maps SDK for iOS),一个是定位的(Places SDK for iOS),你可以去下载google的官方Demo

    对于Demo的下载,我的做法是直接打开命令行工具,按照官方文档给的提示,进行操作,下面是我下载定位的Demo

    下载定位Demo

    他这个Demo的下载方式挺有意思的,下载完成之后如果你想要找到这个程序放的位置,只需要在工程打开后自己找个文件show in finder就行了.(想要查看google的官方文档肯定是需要翻墙的哦) ,下载下来这个Demo之后,如果你想要运行改工程你必须去配置相关服务的key,不然运行会报错,并且如果想要在手机上运行也需要你的手机翻墙才行,这里推荐一个手机的免费的翻墙工具(Screen VPN),免费的,AppStore搜索即可下载,每天有200M免费流量,对于测试完全够了,这个软件的翻墙需要在4G下才行,我用公司的WiFi翻不了.

    1. 你需要根据手里的google的开发者账号,去平台申请第1步说的key,看下图:
    创建需要的服务.png
    获取凭据.png

    首先需要去开放者平台创建服务,然后创建凭据拿到相应的key.在启动了服务并且拿到了key之后,把key填在第1步获取的Demo中的相应的位置就行了.

    1. 简单的介绍一下google地图的基本功能:
      3.1 基本组成部分:

    Map(地图): 基本的地图创建, 组件, 类别等;
    Panorama(全景): 固定/可旋转的街景;
    Overlays(覆盖物): 地图视图的自定义(地图大头针, 弹出信息框等);
    Camera(摄像头): 当前地图的可视范围(设置摄像头中心点坐标、镜头缩放比例、方向、视角等);
    Services(服务): 地理编码/逆地理编码;

    GoogleMap SDK结构概览.png

    3.2 常用类介绍:

    GMSMapView: 最主要的地图类
    GMSCameraPosition: 地图摄像头,可以理解为当前地图的可视范围,可以获取到摄像头中心点坐标、镜头缩放比例、方向、视角等参数
    GMSMarker: 地图大头针
    GMSGeocoder: 反向地理编码类
    GMSAddress: 反向地理编码返回的类,包含坐标及地理位置描述等信息
    CLLocationManager: 就是CoreLocation框架下的地理位置管理类
    GMSAutocompleteFetcher: 搜索自动补全抓取器,通过该类的代理方法实现搜索自动补全

    3.3 常用方法介绍:(GMSMapViewDelegate:)

    mapView:willMove: 镜头即将移动时调用
    mapView:didChangeCameraPosition: 镜头移动完成后调用
    mapView:didTapAtCoordinate: 点击地图时调用
    mapView:didLongPressAtCoordinate: 长按地图时调用
    mapView:didTapMarker: 点击大头针时调用
    mapView:didTapInfoWindowOfMarker: 点击大头针的弹出视窗时调用
    mapView:didLongPressInfoWindowOfMarker: 长按大头针视窗时调用
    mapView:markerInfoWindow: 自定义大头针弹出视窗,返回UIView
    mapView:didCloseInfoWindowOfMarker: 自定义大头针弹出视窗关闭时调用
    mapView:didDragMarker: 拖拽大头针时调用
    didTapMyLocationButtonForMapView: 点击定位大头针, 返回BOOL值

    那么通过上面三点,我相信你应该对google地图有了一个基本的了解,那么下面我再通过代码的方式去看看google地图怎么实现.

    我自己的项目中有一个自定义弹窗的需求,google地图有一个比较不友好的问题就是:

    如果你需要自定义弹窗是用的SDK提供的代理方法那么在你弹窗的view上面的按钮的点击事件没有作用,解决的办法是自己写一套弹窗的逻辑,通过google,找到了一个第三方叫做SMCalloutView, 在这里也感谢作者的开源,非常棒.

    下面是我实现之后的效果展示

    自己写弹窗

    下面,我贴一下我的代码给大家起一个头:

    @property(nonatomic, strong) GMSMapView *mapView;
    
    /** 用户当前所在位置 */
    
    @property(nonatomic, assign) CLLocationCoordinate2D curCoordinate2D;
    
    - (void)createUI{
    
        GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.868
    
                                                                longitude:151.2086
    
                                                                     zoom:16];
    
        GMSMapView*mapView = [GMSMapViewmapWithFrame:CGRectZerocamera:camera];
    
        mapView.myLocationEnabled = YES;
    
        [self.viewaddSubview:mapView];
    
        self.mapView= mapView;
    
    }
    
    - (void)viewDidLayoutSubviews{
    
        [super viewDidLayoutSubviews];
    
        self.mapView.frame = self.view.bounds;
    
    }
    
    #pragma mark - CLLocationManagerDelegate
    
    - (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:14];
    
        self.mapView.camera= camera;
    
        self.curCoordinate2D= curCoordinate2D;
    
        if (self.curCoordinate2D.latitude) {
    
            [self.locationManager stopUpdatingLocation];
    
        }
    
    }
    

    上面呢,大家就可以拿到当前用户所在的地理位置了,那么接下来我再给大家贴一段关于SMCalloutView是怎么使用的,下面代码中的JNBubbleChange继承的SMCalloutView,用xib拖拽的一个弹出框.

    @property (strong, nonatomic) JNBubbleChange *calloutView;
    
    @property(strong, nonatomic) UIView *emptyCalloutView;
    
    - (UIView*)emptyCalloutView
    
    {
    
       if (!_emptyCalloutView) {
    
           _emptyCalloutView = [[UIView alloc] init];
    
           _calloutView.backgroundColor = [UIColor clearColor];
    
       }
    
       return _emptyCalloutView;
    
    }
    
    - (JNBubbleChange*)calloutView
    
    {
    
       if (!_calloutView) {
    
           _calloutView = [[JNBubbleChange alloc] initWithFrame:CGRectMake(0,0, (JNScreenW-JNW(60)),JNH(160))];
    
       }
    
       return _calloutView;
    
    }
    
    #pragma mark - GMSMapViewDelegate
    
    - (nullableUIView*)mapView:(GMSMapView*)mapView markerInfoWindow:(GMSMarker*)marker{
    
       CLLocationCoordinate2D anchor = marker.position;
    
       CGPoint point = [mapView.projection pointForCoordinate:anchor];
    
       self.calloutView.calloutOffset = CGPointMake(0, -CalloutYOffset);
    
       self.calloutView.hidden = NO;
    
       CGRectcalloutRect = CGRectZero;
    
       calloutRect.origin = point;
    
       calloutRect.size = CGSizeZero;
    
       //确定一个对象是否是当前类的成员
    
       if([marker isMemberOfClass:[JNCusGmsMaker class]]){
    
           JNCusGmsMaker *jMarker = (JNCusGmsMaker*) marker;
    
           self.calloutView.dict = jMarker.shopDict;
    
           self.calloutView.daoB.dict = jMarker.shopDict;
    
           self.calloutView.detailB.dict = jMarker.shopDict;
    
       }
    
       [self.calloutView.daoB addTarget:self action:@selector(clickDaoB:) forControlEvents:UIControlEventTouchUpInside];
    
       [self.calloutView.detailB addTarget:self action:@selector(clickDetailB:) forControlEvents:UIControlEventTouchUpInside];
    
       [self.calloutView presentCalloutFromRect:calloutRect inView:mapView constrainedToView:mapView animated:YES];
    
       return self.emptyCalloutView;
    
    }
    

    上面的这一段代码就是点击标注的时候弹窗的显示框,其中的JNCusGmsMaker是继承的GMSMarker,里面加了一个字典属性,目的很简单就是让对应的maker去相应的保存服务器中获取的值,最后返回一个空的UIView给系统即可.

    1. 再给大家贴一下关于如何用google地图导航到相应的地点
      首先,google提供的SDK中没有关于导航的,那么我的做法是拿到目的地的坐标后跳转到googleMap的客户端去导航,方法如下:
    #pragma mark - 标注按钮点击事件
    
    -(void)clickDaoB:(JNBaseVarBtn*)sender{
    
        if(!kDictIsEmpty(sender.dict)){
    
            NSURL *url = JNUrl(@"comgooglemaps://");
    
            if ([[UIApplication sharedApplication] canOpenURL:url]) {
    
                CGFloat lati = [sender.dict[@"latitude" ] floatValue];
    
                CGFloat loti = [sender.dict[@"longitude"] floatValue];;
    
                NSString *desS = [NSString stringWithFormat:@"comgooglemaps://?x-source=%@&x-success=%@&saddr=&daddr=%f,%f&directionsmode=driving",@"你的App名称",JNAppScheme,lati,loti];
    
                NSString *urlString = [desS stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    
                [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
    
            }else{
    
                [M showAlert:@"请先安装谷歌地图客户端"];
    
            }
    
        }
    
    }
    

    5.关于google地图的反地理位置编码
    对于google地图的反地理位置编码,我的做法是在拿到用户的经纬度时,去根据经纬度拿到其位置,再给大家贴一小段代码

    //反地理编码
    
    -(void)reversiGeocode:(CLLocationCoordinate2D)target{
    
        [JNHudTool mb_showHUDWithInfo:nil userEnaled:YES someView:self.JNBaseTableview];
    
        [self.searchAddressArrayM removeAllObjects];
    
        [[GMSGeocoder geocoder] reverseGeocodeCoordinate:target completionHandler:^(GMSReverseGeocodeResponse * response, NSError * error) {
    
            if(response.results) {
    
                for(inti =0; i < response.results.count; i ++ ) {
    
                    GMSAddress*temp = response.results[i];
    
                    if(!kStringIsEmpty(temp.thoroughfare)) {
    
                        [self.searchAddressArrayMaddObject:temp];
    
                    }
    
                }
    
                NSLog(@"查看反地理编码的结果res:%@",response.results);
    
                [self.JNBaseTableviewreloadData];
    
                [JNHudTool mb_dismissHUDWithTime:2 someView:self.JNBaseTableview];
    
            }
    
        }];
    
    }
    

    其他的关于输入某个地点进行搜索的话,可以直接用google提供的一个控制器,叫做(GMSAutocompleteViewController),这个大家可以自己去下第1步中的Demo简单看下就可以了

    以上就是我最近遇到的关于google地图的问题和解决方法,希望对之后也遇到此问题的朋友有一些帮助.下面的链接是我在解决的过程中用到的资料,也是非常的感谢作者:

    https://juejin.im/post/59de263551882578bf1847b9

    相关文章

      网友评论

        本文标题:iOS开发 - 关于谷歌地图的使用总结

        本文链接:https://www.haomeiwen.com/subject/nhyjmftx.html