业务需求 :给别人发送当前位置功能
点击查看别人的位置信息,
功能需求 :
1. 点击发送位置按钮, 进入地图界面. 定位到自己当前的位置
2. 定位到自己当前位置的大头针, 不是地图自带的小圆点, 而是自己的头像.
3. 移动屏幕, 大头针始终在屏幕中心. 当停止移动时, 将大头针设置为当前位置.
4. 获得大头针所在位置附近的商圈, 在列表中显示.
5. 点击列表中的位置信息, 大头针跟着移动.
6. 点击定位按钮, 大头针回到自己当前位置
7. 以上所有移动地图的操作 都要保证大头针始终在屏幕中心.
8. 查看别人发送的位置, 别人的位置需要显示头像, 我的位置显示默认小蓝点, 默认显示别人的位置, 点击定位按钮后,回到我的位置.
-(void)startFollowing:(id)sender{
// 指南针
_mapView.settings.compassButton = NO;
// 定位按钮是否显示
_mapView.settings.myLocationButton = NO;
// Listen to the myLocation property of GMSMapView.
[_mapView addObserver:self
forKeyPath:@"myLocation"
options:NSKeyValueObservingOptionNew
context:NULL];
// Ask for My Location data after the map has already been added to the UI.
if (self.provider.paramters.mapType == TPMapType_Receive_GoogleMap) {
dispatch_async(dispatch_get_main_queue(), ^{
_mapView.myLocationEnabled = YES;
});
}
}
#pragma mark - KVO updates 跟随态代理
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if (!_firstLocationUpdate) {
// If the first location update has not yet been recieved, then jump to that
// location.
_firstLocationUpdate = YES;
CLLocation *location = [change objectForKey:NSKeyValueChangeNewKey];
if (!location) {
_mapView.camera = [GMSCameraPosition cameraWithTarget:location.coordinate
zoom:14];
}
}
}
// 点击定位按钮, 回到自己的位置
- (IBAction)locationBtnDidClick:(id)sender {
CLLocation *location = _mapView.myLocation ;
if (!location || !CLLocationCoordinate2DIsValid(location.coordinate)) {
return;
}
_mapView.layer.cameraLatitude = location.coordinate.latitude;
_mapView.layer.cameraLongitude = location.coordinate.longitude;
_mapView.layer.cameraBearing = 0.0;
// Access the GMSMapLayer directly to modify the following properties with a
// specified timing function and duration.
CAMediaTimingFunction *curve =
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
CABasicAnimation *animation;
animation = [CABasicAnimation animationWithKeyPath:kGMSLayerCameraLatitudeKey];
animation.duration = 2.0f;
animation.timingFunction = curve;
animation.toValue = @(location.coordinate.latitude);
[_mapView.layer addAnimation:animation forKey:kGMSLayerCameraLatitudeKey];
animation = [CABasicAnimation animationWithKeyPath:kGMSLayerCameraLongitudeKey];
animation.duration = 2.0f;
animation.timingFunction = curve;
animation.toValue = @(location.coordinate.longitude);
[_mapView.layer addAnimation:animation forKey:kGMSLayerCameraLongitudeKey];
animation = [CABasicAnimation animationWithKeyPath:kGMSLayerCameraBearingKey];
animation.duration = 2.0f;
animation.timingFunction = curve;
animation.toValue = @0.0;
[_mapView.layer addAnimation:animation forKey:kGMSLayerCameraBearingKey];
// Fly out to the minimum zoom and then zoom back to the current zoom!
CGFloat zoom = _mapView.camera.zoom;
NSArray *keyValues = @[@(zoom), @(zoom - 2), @(zoom)];
CAKeyframeAnimation *keyFrameAnimation =
[CAKeyframeAnimation animationWithKeyPath:kGMSLayerCameraZoomLevelKey];
keyFrameAnimation.duration = 2.0f;
keyFrameAnimation.values = keyValues;
[_mapView.layer addAnimation:keyFrameAnimation forKey:kGMSLayerCameraZoomLevelKey];
}
#pragma send location show my icon
- (void)createCCLocationManage{
//定位管理器
_locationManager = [[CLLocationManager alloc]init];
//如果没有授权则请求用户授权
if ([CLLocationManager authorizationStatus]==kCLAuthorizationStatusNotDetermined){
[_locationManager requestWhenInUseAuthorization];
}else if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusAuthorizedWhenInUse){
//设置代理
_locationManager.delegate=self;
//设置定位精度
_locationManager.desiredAccuracy=kCLLocationAccuracyBest;
//定位频率,每隔多少米定位一次
CLLocationDistance distance= 10.0;//十米定位一次
_locationManager.distanceFilter=distance;
//启动跟踪定位
[_locationManager startUpdatingLocation];
}
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
CLLocation *location=[locations firstObject];//取出第一个位置
CLLocationCoordinate2D coordinate=location.coordinate;//位置坐标
// NSLog(@"经度:%f,纬度:%f,海拔:%f,航向:%f,行走速度:%f",coordinate.longitude,coordinate.latitude,location.altitude,location.course,location.speed);
[self addPointAnnotationWithLatitude:coordinate.latitude longitude:coordinate.longitude];
// 第三步, 移动屏幕中心到当前经纬度.
if (!_camera) {
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:coordinate.latitude longitude:coordinate.longitude zoom:16];
_mapView.camera = camera;
}
_location = [[CLLocation alloc] initWithLatitude:coordinate.latitude longitude:coordinate.longitude];
}
//添加大头针
- (IBAction)addPointAnnotationWithLatitude:(double)latitude longitude:(double)longitude{
GMSMarker *anotherSydneyMarker = [[GMSMarker alloc] init];
// TPMapAnnotationView 这是自定义类
TPMapAnnotationView *annotationView = [TPMapAnnotationView new];
[annotationView addAvatarUrl:self.provider.paramters.avatarUrl];
annotationView.frame = CGRectMake(0, 0,40, 50);
anotherSydneyMarker.iconView = annotationView;
anotherSydneyMarker.position = CLLocationCoordinate2DMake(latitude, longitude);
anotherSydneyMarker.map = _mapView;
_markers = [NSMutableArray arrayWithObject:anotherSydneyMarker];
}
#pragma mark - GMSMapViewDelegate 地图拖拽完成
- (void)mapView:(GMSMapView *)mapView didChangeCameraPosition:(GMSCameraPosition *)position{
// 加段动画
// ....
// 通过经纬度获得周边信息
[self reverseGeoShortUrlShareWithLatitude:position.target.latitude longitude:position.target.longitude];
}
pod 'GoogleMaps'
pod 'GooglePlaces'
还有一个记不清得了...
在GoogleMaps 这个库中提供了一个方法获得周边信息的.但是返还的信息好简陋啊, 不忍直视.
-(IBAction)reverseGeoShortUrlShareWithLatitude:(double)latitude longitude:(double)longitude{
//坐标
NSString* _coordinateXText = [NSString stringWithFormat:@"%.6f", longitude];
NSString* _coordinateYText = [NSString stringWithFormat:@"%.6f", latitude];
pt = (CLLocationCoordinate2D){[_coordinateYText floatValue], [_coordinateXText floatValue]};
// GMSCameraPosition zoomAtCoordinate:pt forMeters:kCLLocationAccuracyNearestTenMeters perPoints:<#(CGFloat)#>
__weak typeof(self) weakSelf = self;
GMSReverseGeocodeCallback handler = ^(GMSReverseGeocodeResponse *response, NSError *error) {
GMSAddress *address = response.firstResult;
if (self.provider.paramters.mapType == TPMapType_Receive_GoogleMap && address) {
NSLog(@"Geocoder result: %@", address);
NSLog(@"geocoder country %@",address.country);
NSLog(@"geocoder locality %@", address.locality);
NSLog(@"geocoder subLocality %@", address.subLocality);
NSLog(@"geocoder thoroughfare %@",address.thoroughfare);
NSLog(@"geocoder administrative %@", address.administrativeArea);
}else if (self.provider.paramters.mapType == TPMapType_Send_GoogleMap){
}
};
[_geocoder reverseGeocodeCoordinate:pt completionHandler:handler];
}
后来我翻到了 pod ‘GooglePlaces’库. 要在appdelegate里为这个类注册. 在申请key时要勾选place 这一项.
[GMSServices provideAPIKey:@"googleKey"];
[GMSPlacesClient provideAPIKey:@"googleKey"];
GooglePlaces 提供的周边信息要比GoogleMaps详细的多, 但是, 但是, 还是有缺陷, 我没找到_placesClient 怎么获得指定经纬度的周边信息, 也就是说, 下面这个方法只能获得当前位置的经纬度信息…..操了. 这个我暂时也没找到合适的api, 只能先用GoogleMaps的简陋数据…..
[_placesClient currentPlaceWithCallback:^(GMSPlaceLikelihoodList *placeLikelihoodList, NSError *error){
if (error != nil) {
NSLog(@"Pick Place error %@", [error localizedDescription]);
return;
}
if (placeLikelihoodList != nil) {
if (self.provider.paramters.mapType == TPMapType_Send_GoogleMap){
NSMutableArray *poiList = [NSMutableArray array];
NSInteger i = 0;
for (GMSPlaceLikelihood *likelihood in [placeLikelihoodList likelihoods]) {
GMSPlace *place = [likelihood place];
TPMapBottomViewParamter *paramter = [TPMapBottomViewParamter new];
paramter.latitude = place.coordinate.latitude;
paramter.longitude = place.coordinate.longitude;
paramter.name = place.name;
paramter.addressText = place.formattedAddress;
paramter.showMarker = i == 0? YES : NO;
i++;
[poiList addObject:paramter];
}
[weakSelf fillBottomLocationViewWithParamters:poiList];
}
}
}];
// 实现地图中心移动.
GMSCameraUpdate *newCamera = [GMSCameraUpdate setTarget:CLLocationCoordinate2DMake(paramter.latitude, paramter.longitude)];
[_mapView moveCamera:newCamera];
功能需求六 点击定位按钮, 大头针回到自己当前位置
这个在功能需求一种介绍过, 不在赘述.
功能需求七 在功能五中已经保证.
功能需求八 查看别人发送的位置, 别人的位置需要显示头像, 我的位置显示默认小蓝点, 默认显示别人的位置, 点击定位按钮后,回到我的位置.
这个别的都不难, 就是说一点, 先显示别人的位置
// 在viewWillAppear 中设置即可,
_camera = [GMSCameraPosition cameraWithLatitude:self.provider.paramters.latitudeD longitude:self.provider.paramters.longitudeD
zoom:16];
好了 以上介绍完毕, 如果有不对的地方, 请多指教 邮箱 [email protected], 多谢!!!
下面是我在开发是看到的不错的文章,
拉起第三方 http://www.jianshu.com/p/183f66da9d9c
开发详细步骤: http://www.jianshu.com/p/2a1bf192e496
Google Places API http://blog.csdn.net/wangjia55/article/details/8996256
虽然googleMap 官方提供了cocoapod的集成方法。 但有时候也会出现问题所以贴出几个依赖库,已备检查。
http://stackoverflow.com/questions/17920813/undefined-symbols-for-architecture-i386-glkmatrix3identity-referenced-from
AVFoundation.framework
CoreData.framework
CoreLocation.framework
CoreText.framework
GLKit.framework
ImageIO.framework
libc++.dylib
libicucore.dylib
libz.dylib
OpenGLES.framework
QuartzCore.framework
SystemConfiguration.framework
下载的demo 特意去申请的key。 但是提示
ClientParametersRequest failed, 3 attempts remaining (0 vs 10). Error Domain=com.google.HTTPStatus Code=400 "(null)" UserInfo={data=<..........>}
原因是 key 与 buildID 没有对应起来