美文网首页谷歌地图Wi-Fi参考ios基础
iOS GoogleMaps SDK 的详细使用教程 【谷歌地图

iOS GoogleMaps SDK 的详细使用教程 【谷歌地图

作者: SHMI | 来源:发表于2017-08-10 15:03 被阅读699次

    最近由于公司项目做的是国外的项目,使用到了GoogleMaps SDK ,期间磕磕碰碰各种查资料看官方文档总算完成了地图方面的功能,现在和大家分享一下Google地图功能的实现,自己也记录下以后用到可以在看看,同时祝大家项目顺利。

    很感谢其他作者的分享,少走了点弯路。

    集成步骤及GoogleMaps的常用方法地址

    GoogleMaps SDK for iOS 详细集成地址:   www.jianshu.com/p/dc7d267d63d0

    GoogleMaps 常用方法介绍:                         www.jianshu.com/p/ec6d154e3928

    iOS--谷歌地图相关功能的实现          : www.jianshu.com/p/2a1bf192e496

    以上3个链接附有GoogleMaps的集成方式以及代理方法详细介绍。

    获取定位信息

    首先要通过CLLocation拿到定位信息,并且用户授权访问位置信息等,这里不详细介绍,直接上代码。

    //获取现在的定位位置

    - (void)getNowLocation{

    if ([CLLocationManager locationServicesEnabled]){//判断是否打开定位

    self.locationManager = [[CLLocationManager alloc] init];

    self.locationManager.delegate = self;

    [self.locationManager requestWhenInUseAuthorization];//请求前台定位权限

    [self.locationManager requestAlwaysAuthorization];//请求后台定位权限

    [self.locationManager setDistanceFilter:10];

    [self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];

    [self.locationManager startUpdatingLocation];

    }else{

    //不能定位用户的位置

    //1.提醒用户检查当前的网络状况

    //2.提醒用户打开定位开关

    [MBProgressHUD showError:@"Switch on the position switch,please"];

    }

    }


    初始化地图等信息

    - (void)creatGoogleMaps{

    //初始化google地图

    _polyline = [[GMSPolyline alloc] init];

    _linepath = [GMSMutablePath path];

    _lastMark = [[GMSMarker alloc] init];

    self.mapView = [[GMSMapView alloc] initWithFrame:CGRectZero];

    self.mapView.indoorEnabled = NO;

    //根据自己需要设置地图缩放最大最小比例

    [self.mapView setMinZoom:3 maxZoom:19];

    self.mapView.buildingsEnabled = NO;

    self.mapView.settings.rotateGestures = NO;

    self.mapView.settings.tiltGestures = NO;

    self.mapView.myLocationEnabled = YES;

    self.mapView.delegate = self;

    [self.view addSubview:self.mapView];

    [self.mapView makeConstraints:^(MASConstraintMaker *make) {

    make.edges.equalTo(self.view);

    }];

    //地图中心标记

    [self createCenterViw];

    //初始化弹出框

    self.homeMenuView = [HomeMenuView instanceView];

    self.cyclingMenuView = [CyclingNowView instanceView];

    }

    简单的地图中心标记

    //中间定位图标显示

    - (void)createCenterViw{

    UIImageView *centerImageView=[[UIImageView alloc]init];

    [centerImageView setImage:[UIImage imageNamed:@"ziji"]];

    [self.view addSubview:centerImageView];

    [centerImageView makeConstraints:^(MASConstraintMaker *make) {

    make.centerX.equalTo(self.view);

    make.centerY.equalTo(self.view).offset(-20.5);

    }];

    }

    定位代理方法实现

    因为googlemaps在国内定位坐标不准确,期间也做了国内和国外火星坐标的处理,后面因为好像不在国内使用,就注释了,方便以后可能会用。

    #pragma mark -  CLLocationManagerDelegate


    //拿到授权发起定位请求

    -(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{

    if (status == kCLAuthorizationStatusAuthorizedWhenInUse) {

    [self.locationManager startUpdatingLocation];

    NSLog(@"locationmanager ===== %f",self.locationManager.location.coordinate.longitude);

    }

    }

    //位置更新时调用

    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray*)locations{

    //    通过location  或得到当前位置的经纬度

    CLLocation *currentLocation = locations.firstObject;

    CLLocationCoordinate2D curCoordinate2D=currentLocation.coordinate;

    [[NSUserDefaults standardUserDefaults] setDouble:curCoordinate2D.latitude forKey:@"latitude"];

    [[NSUserDefaults standardUserDefaults] setDouble:curCoordinate2D.longitude forKey:@"longitude"];

    self.mapView.camera = [[GMSCameraPosition alloc] initWithTarget:curCoordinate2D zoom:17 bearing:0 viewingAngle:0];

    self.marker.position = CLLocationCoordinate2DMake(curCoordinate2D.latitude, curCoordinate2D.longitude);

    /* 中国火星坐标判断

    BOOL ischina = [[ZCChinaLocation shared] isInsideChina:(CLLocationCoordinate2D){curCoordinate2D.latitude,curCoordinate2D.longitude}];

    if (!ischina) {

    [[NSUserDefaults standardUserDefaults] setDouble:curCoordinate2D.latitude forKey:@"latitude"];

    [[NSUserDefaults standardUserDefaults] setDouble:curCoordinate2D.longitude forKey:@"longitude"];

    self.mapView.camera = [[GMSCameraPosition alloc] initWithTarget:curCoordinate2D zoom:17 bearing:0 viewingAngle:0];

    self.marker.position = CLLocationCoordinate2DMake(curCoordinate2D.latitude, curCoordinate2D.longitude);

    }

    else{

    CLLocationCoordinate2D curCoordinate = [TQLocationConverter transformFromWGSToGCJ:curCoordinate2D];

    [[NSUserDefaults standardUserDefaults] setDouble:curCoordinate.latitude forKey:@"latitude"];

    [[NSUserDefaults standardUserDefaults] setDouble:curCoordinate.longitude forKey:@"longitude"];

    self.mapView.camera = [[GMSCameraPosition alloc] initWithTarget:curCoordinate zoom:17 bearing:0 viewingAngle:0];

    self.marker.position = CLLocationCoordinate2DMake(curCoordinate.latitude, curCoordinate.longitude);

    }

    */

    double latitude = [[NSUserDefaults standardUserDefaults]doubleForKey:@"latitude"];

    double longitude = [[NSUserDefaults standardUserDefaults]doubleForKey:@"longitude"];

    NSLog(@"我拿到经度了==%f  我拿到纬度了==%f",longitude,latitude);

    //像服务端发送获取当前位置周边车辆请求

    [self getBikeAndBaseStationInfoWithLocationLongitude:longitude andLatitude:latitude];

    //取最新的一个定位值

    self.newloc = [[locations lastObject] coordinate];

    [self.locationManager stopUpdatingLocation];

    }


    google地图代理方法实现

    //镜头移动完成后调用

    - (void)mapView:(GMSMapView *)mapView didChangeCameraPosition:(GMSCameraPosition *)position{

    //反向地理编码

    //      [self getBikeAndBaseStationInfoWithLocationLongitude:position.target.longitude andLatitude:position.target.latitude];

    [[GMSGeocoder geocoder]reverseGeocodeCoordinate:position.target completionHandler:^(GMSReverseGeocodeResponse * response, NSError * error) {

    if (response.results) {

    GMSAddress *address = response.results[0];

    NSLog(@"%@",address.thoroughfare);

    }

    }];

    }

    //点击大头针的弹出视窗时调用

    -(void)mapView:(GMSMapView *)mapView didTapInfoWindowOfMarker:(GMSMarker *)marker{

    NSLog(@"点击大头针的弹出视窗时调用");

    }

    //拖拽大头针时调用

    -(void)mapView:(GMSMapView *)mapView didDragMarker:(GMSMarker *)marker{

    NSLog(@"拖拽大头针时调用");

    }

    //大头针拖拽完成时调用

    -(void)mapView:(GMSMapView *)mapView didEndDraggingMarker:(GMSMarker *)marker{

    NSLog(@"大头针拖拽完成时调用");

    }

    //点击大头针时调用

    - (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker{

    NSLog(@"点击大头针... mark.userData:%@",marker.userData);

    //给点击的mark赋值,方便加入坐标数组

    self.lastMark = marker;

    //获取路径点数组

    SMBikeInfoModel *model = marker.userData;

    [self showMenuView];

    [self showStationDetailMenuView:model];

    [self calculateRoutesFrom:self.newloc to:marker.position];

    return YES;

    }


    *计算轨迹线路径、行驶距离及时间

    #pragma mark - 画轨迹线

    //注:需要画轨迹线,所以必须向googlemap官网请求api,获取到路径规划的数组点

    //计算路线 由开始到结束路线请求

    - (void)calculateRoutesFrom:(CLLocationCoordinate2D)startLoc to:(CLLocationCoordinate2D)endLoc{

    //开始地址

    NSString *startAddress = [NSString stringWithFormat:@"%f,%f",startLoc.latitude,startLoc.longitude];

    //结束地址

    NSString *endAddress = [NSString stringWithFormat:@"%f,%f",endLoc.latitude,endLoc.longitude];

    SMNetworking *network = [SMNetworking sharedTool];

    NSString *urlString = [NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/directions/json?origin=%@&destination=%@&mode=walking&key=%@",startAddress,endAddress,GoogleDirectionsKey];

    [network GET:urlString parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {

    NSDictionary *dict = (NSDictionary *)responseObject;

    NSArray *routesarray = dict[@"routes"];

    NSLog(@"%@",routesarray);

    //无路线方案、防崩溃

    if (routesarray.count==0) {

    [MBProgressHUD showError:@"NO Routes"];

    return ;

    }

    NSDictionary *legsDic = [routesarray objectAtIndex:0];

    NSArray *legsArray = [NSArray array];

    legsArray = legsDic[@"legs"];

    NSDictionary *addressDic = [legsArray objectAtIndex:0];

    //起点终点

    NSString *startAddressStr = addressDic[@"start_address"];

    NSString *endAddressStr = addressDic[@"end_address"];

    NSLog(@"起点:%@    终点:%@",startAddressStr,endAddressStr);

    //距离

    NSDictionary *distanceDic = addressDic[@"distance"];

    NSString *distanceStr = distanceDic[@"text"];

    //花费时间

    NSDictionary *durationDic = addressDic[@"duration"];

    NSString *durationStr = durationDic[@"text"];

    NSString *dis = [distanceStr stringByReplacingOccurrencesOfString:@"" withString:@"km"];

    NSString *minStr = [durationStr stringByReplacingOccurrencesOfString:@"" withString:@"min"];

    NSString *hoursStr = [minStr stringByReplacingOccurrencesOfString:@"小时" withString:@"hour"];

    self.homeMenuView.distance.text = dis;

    self.homeMenuView.time.text = minStr;

    NSDictionary *tempDic = legsDic[@"overview_polyline"];

    NSString *points = tempDic[@"points"];

    self.routesArray = [self decodePolyLine:[points mutableCopy]];

    NSLog(@"points:%@",points);

    //画轨迹线

    [self showMenuView];

    [self.linepath removeAllCoordinates];//移除以前的路径轨迹

    [self update_rpute_view];//画线

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

    NSLog(@"%@",error);

    //        [MBProgressHUD showError:@"路线请求超时"];

    }];

    }


    *画线

    - (void)update_rpute_view{

    //线条颜色

    self.polyline.strokeColor = SETCOLOR(71, 215, 205);

    //线条宽度

    self.polyline.strokeWidth = 6.0f;

    for (int i = 0; i < self.routesArray.count; i++) {

    CLLocation *location = [self.routesArray objectAtIndex:i];

    CLLocationDegrees latitude = location.coordinate.latitude;

    CLLocationDegrees longitude = location.coordinate.longitude;

    CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude);

    [self.linepath addCoordinate:coordinate];

    }

    self.polyline.path = self.linepath;

    self.polyline.map = self.mapView;

    NSLog(@"count:%lu --- path:%@",(unsigned long)self.polyline.path.count,self.polyline.path.encodedPath);

    //展示当前路线

    GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] initWithPath:self.linepath];

    GMSCameraUpdate *update = [GMSCameraUpdate fitBounds:bounds];

    [self.mapView moveCamera:update];

    }





    *得到路径数组

    - (NSMutableArray *)decodePolyLine:(NSMutableString *)encoded{

    NSInteger len = [encoded length];

    NSInteger index = 0;

    NSMutableArray *array = [NSMutableArray array];

    NSInteger lat = 0;

    NSInteger lng = 0;

    while (index < len) {

    NSInteger b;

    NSInteger shift = 0;

    NSInteger result = 0;

    do {

    b = [encoded characterAtIndex:index++] - 63;

    result |= (b & 0x1f) << shift;

    shift += 5;

    } while (b >= 0x20);

    NSInteger dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));

    lat += dlat;

    shift = 0;

    result = 0;

    do {

    b = [encoded characterAtIndex:index++] - 63;

    result |= (b & 0x1f) << shift;

    shift += 5;

    } while (b >= 0x20);

    NSInteger dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));

    lng += dlng;

    NSNumber *latitude = [[NSNumber alloc]initWithFloat:lat * 1e-5 ];

    NSNumber *lontitude = [[NSNumber alloc]initWithFloat:lng * 1e-5];

    printf("[%f",[latitude doubleValue]);

    printf(" %f]",[lontitude doubleValue]);

    CLLocation *loction = [[CLLocation alloc]initWithLatitude:[latitude floatValue] longitude:[lontitude floatValue]];

    [array addObject:loction];

    }

    //加上最后一组轨迹(即加入一组为点击的mark坐标)

    CLLocation *lastLoc = [[CLLocation alloc]initWithLatitude:self.lastMark.position.latitude longitude:self.lastMark.position.longitude];

    [array addObject:lastLoc];

    return array;

    }

    Tips:在国内使用的话需要翻墙,由于网络等原因,可能导致地图显示不出来,链接不上GoogleMaps,路线显示不出来或延迟显示。

    以上便是整个功能的实现了,第一次在简书上发表文章。希望大家多多支持,以后也会多写写文章的。



    相关文章

      网友评论

        本文标题:iOS GoogleMaps SDK 的详细使用教程 【谷歌地图

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