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