iOS中关于GoogleMaps的使用以及注意事项--随笔

前言:由于最近公司的新项目需要用到谷歌地图功能,所以顺便将自己碰到的问题以及注意事项随笔下来,为自己以及同道中人留点参考,不足之处后续再进行修改更新吧,闲话少说,开始吧。。。

1.下载GoogleMaps SDK,由于目前Google不FQ是访问不了的,所以想下载sdk需要先将电脑FQ,开vpn。不过,当初我下载的时候,由于电脑并没有FQ,所以我找资源就是在code4app中搜索前辈高人做过的一些关于实现了定位功能的googlemaps的demo,从他们的demo中将framework Copy出来。

2.集成GoogleMaps SDK,将获取到的GoogleMaps.framework拉到你的项目中,记得勾选第一项“copy items if needed”,不用多说吧。然后同样的,在GoogleMaps.framework的Resources中,将GoogleMaps.bundle拉到项目中。做完这些,就需要添加一些库文件了,可参考网上的资料:http://www.jianshu.com/p/dc7d267d63d0,此网址链接中有后续的所有操作,感谢此简书的作者!

3当看完网址上的内容时,当然你的定位功能已经实现了,不过,对于项目来说,还远远不够,比如画轨迹线,地图缩放等等。下面将自己写的代码粘贴如下:

初始化:

-(void)initMap{

    self.mapView = [[GMSMapView alloc] initWithFrame:self.rootView.bounds];

    self.mapView.delegate = self;

    self.mapView.indoorEnabled = NO;

    self.mapView.settings.rotateGestures = NO;

    self.mapView.settings.tiltGestures = NO;

    self.mapView.settings.myLocationButton = NO;//隐藏定位按钮

    self.mapView.myLocationEnabled = YES;

    [self.rootView addSubview:self.mapView];

    //定位:

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

    self.locationManager.delegate  = self;

    [self.locationManager requestWhenInUseAuthorization];

    [self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];

    [self.locationManager startUpdatingLocation];

}

mark点:我这里是有多个点,你也可以只标注一个点,做着玩。

-(void)showBikeToMap{

    markerArray = [NSMutableArray array];

    for (int i=0; i<[self.arrayBike count]; i++) {

        BikeModel *bike = [self.arrayBike objectAtIndex:i];

        self.marker = [[GMSMarker alloc] init];

        self.marker.position = CLLocationCoordinate2DMake(bike.lat, bike.lng);

        self.marker.appearAnimation = kGMSMarkerAnimationNone;

        self.marker.userData = self.arrayBike[i];

        self.marker.map = _mapView;

        [markerArray addObject:self.marker];    

    }

}

#pragma mark -  CLLocationManagerDelegate

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

    /**

     *    拿到授权发起定位请求

     */

    if (status == kCLAuthorizationStatusAuthorizedWhenInUse) {

        [self.locationManager startUpdatingLocation];

        

    }

}

 

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

    /**

     * 位置更新时调用

     */

    CLLocation *currentLocation = locations.firstObject;

    self.mapView.camera = [[GMSCameraPosition alloc] initWithTarget:currentLocation.coordinate zoom:15 bearing:0 viewingAngle:0];

    //取最新的一个定位值

    self.loc = [locations lastObject].coordinate;

    [self.locationManager stopUpdatingLocation];

}

#pragma  mark - GMSMapview Delegate

//镜头移动完成后调用

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

    

    //反向地理编码

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

        if (response.results) {

            GMSAddress *address = response.results[0];

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

        }

    }];

}

 

//点击大头针时调用

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

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

   self.marker = marker;

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

    self.lastMark = marker;

    //获取路径点数组

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

    return YES;

}

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

//请求GoogleMaps API

- (void)calculateRoutesFrom:(CLLocationCoordinate2D)f to:(CLLocationCoordinate2D)t{

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

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

    NSString *apiUrlStr = [NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/directions/json?origin=%@&destination=%@&mode=walking&key=%@",saddr,daddr,GOOGLEMAPSREQUESTAPIKEY];

    AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc]init];

    manager.responseSerializer = [AFHTTPResponseSerializer serializer];

    [MBProgressHUD showHUDAddedTo:WINDOW animated:YES];

    [manager GET:apiUrlStr parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {

        [MBProgressHUD hideHUDForView:WINDOW animated:YES];

        NSMutableDictionary *jsonDic = [[NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil] mutableCopy];

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

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

        //无路线方案、防崩溃

        if (routesarray.count==0) {

            [MBProgressHUD showErrorWithText:@"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"];

        startAddress = startAddressStr;

        endAddress = 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"];

        NSString *dayStr = [hoursStr stringByReplacingOccurrencesOfString:@"天" withString:@"day"];

        distance = dis;

        duration = dayStr;

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

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

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

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

        //画轨迹线

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

        [self update_rpute_view];

        

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

        [MBProgressHUD hideHUDForView:WINDOW animated:YES];

        [MBProgressHUD showErrorWithText:@"the request timed out"];

    }];

}

 

//得到路径数组

- (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;

}

 

#pragma mark - 画轨迹线

- (void)update_rpute_view{

    self.polyLine.strokeColor = [UIColor greenColor];

    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];

}

 主要画轨迹线,展示路径都在上面,此代码仅为自己以后提供参考,若有道友不喜,勿喷!

 

代码撸的差不多了,现在记录下碰到的一些问题以及我的解决办法:

(1)请求路径无权限,需要申请一个key通过权限;

(2)请求成功,但返回“ZERO_RESULTS”,可能是请求的URL不对,而我当时出的问题就是多加了个“,”号,去掉即可;

(3)展示路径全屏:first:获取到GMSMutablePath对象,如linePath。(注意:必须初始化:

    self.polyLine = [[GMSPolyline alloc]init];

    self.linePath = [GMSMutablePath path];

)

    second:

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

    GMSCameraUpdate *update = [GMSCameraUpdate fitBounds:bounds];

    [self.mapView moveCamera:update];

(4)移除未选中的marker:在获取marker时,将marker加入一个数组中,而非将marker.map加入数组中;然后在需要移除的方法里新建一个GMSMakrer,最后一一赋值,调用marker.map = null即可移除;

(5)报错:-[GMSMapView animateToCameraPosition:];

       解决办法:first:在Other Linker Flages中加入"$(inherited)";

                     second: 在Other Linker Flages中加入"-ObjC";

(6)报错:地图可定位,但不显示,报“400”错误;

       原因:1. 申请的谷歌地图key与包名不匹配;2.key未授权的情况下,在请求googlemaps API时会请求不到数据。

 

总结:以上就是做项目时碰到的一些具体事项,仅供参考,不喜勿喷,谢谢!???,祝各位项目进展顺利,永无bug!!!

转载于:https://www.cnblogs.com/jane-IOS/p/6670616.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值