业务需求 :给别人发送当前位置功能
点击查看别人的位置信息,
功能需求 :
1. 点击发送位置按钮, 进入地图界面. 定位到自己当前的位置
2. 定位到自己当前位置的大头针, 不是地图自带的小圆点, 而是自己的头像.
3. 移动屏幕, 大头针始终在屏幕中心. 当停止移动时, 将大头针设置为当前位置.
4. 获得大头针所在位置附近的商圈, 在列表中显示.
5. 点击列表中的位置信息, 大头针跟着移动.
6. 点击定位按钮, 大头针回到自己当前位置
7. 以上所有移动地图的操作 都要保证大头针始终在屏幕中心.
8. 查看别人发送的位置, 别人的位置需要显示头像, 我的位置显示默认小蓝点, 默认显示别人的位置, 点击定位按钮后,回到我的位置.
下面介绍功能实现
- 功能需求一: 点击发送位置按钮, 进入地图界面. 定位到自己当前的位置
实现思路在viewWillappear 中调用开始定位的方法, 这个方法会调用代理方法: didUpdateBMKUserLocation. 在这个代理方法中能拿到 自己当前的经纬度. 将_mapView的中心设置成这个经纬度即可.
// 开始定位 会调用代理 didUpdateBMKUserLocation:
- (IBAction)startLocation:(id)sender{
[_locService startUserLocationService]; // 这就话是重点
_mapView.showsUserLocation = NO;//先关闭显示的定位图层
_mapView.userTrackingMode = BMKUserTrackingModeNone;//设置定位的状态
_mapView.showsUserLocation = YES;//显示定位图层
}
- (void)didUpdateBMKUserLocation:(BMKUserLocation *)userLocation
{
[_mapView updateLocationData:userLocation];
[_mapView setCenterCoordinate:userLocation.location.coordinate animated:YES];
}
- 功能需求二 : 定位到自己当前位置的大头针, 不是地图自带的小圆点, 而是自己的头像.
实现思路. 百度地图的BMKLocationViewDisplayParam类确实提供了更换默认图片的方法. 但是也只能更换图片(提供传入图片名的属性, 且要求必须和默认图片所在的位置相同), 不能是自定义View. 因为我的要求是定位的地方显示的是用户的头像所以不能简单用一个图片代替.
我的做法是. 将百度默认的小蓝点图片换成一张透明的图片, 再获得自己经纬度后放一个大头针在哪个地方, 因为大头针是可以自定义View的.
获得自己经纬度的方法, 请看功能实现1.
//1 . 隐藏默认小蓝点. 在viewWillAppear 中实现
BMKLocationViewDisplayParam *disPlayParamter= [BMKLocationViewDisplayParam new];
disPlayParamter.isRotateAngleValid = NO;
disPlayParamter.isAccuracyCircleShow = NO;
disPlayParamter.locationViewImgName = @"透明图片";
[_mapView updateLocationViewWithParam:disPlayParamter];
// 2. 添加大头针
// BMKPointAnnotation* pointAnnotation;声明这个属性, 怎么写不说了.
- (void)addPointAnnotationWithLatitude:(double)latitude longitude:(double)longitude{
if (pointAnnotation == nil) {
pointAnnotation = [[BMKPointAnnotation alloc]init];
pointAnnotation.title = @"test";
pointAnnotation.subtitle = @"此Annotation可拖拽!";
}
CLLocationCoordinate2D coor;
coor.latitude = latitude;
coor.longitude = longitude;
pointAnnotation.coordinate = coor;
[_mapView addAnnotation:pointAnnotation];
}
// 大头针的代理
// MyAnimatedAnnotationView 这个类是一个自定义大头针的类, 要继承BMKAnnotationView. 就当他是一个View 随便折腾去吧.
- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id <BMKAnnotation>)annotation
{
if (annotation == pointAnnotation) {
MyAnimatedAnnotationView *annotationView = (MyAnimatedAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:tpMapBaiduViewID];
if (!annotationView) {
annotationView = [[MyAnimatedAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:tpMapBaiduViewID];
annotationView.canShowCallout = NO;//在点击大头针的时候会弹出那个黑框框
annotationView.draggable = NO;//禁止标注在地图上拖动
}
[annotationView addAvatarUrl:self.provider.paramters.avatarUrl];
return annotationView;
}
return nil;
}
- 功能需求三: 移动屏幕, 大头针始终在屏幕中心. 当停止移动时, 将大头针设置为当前位置.
这个没有找到百度提供的方法. 用的是自己的土方法实现的. 大致思路是,
1>在self.view上中心上再添加一个viewA (这个view不能放在_mapView上, 要比_mapView晚添加. 不能被_mapView遮住). 这样看起来就好像移动地图时大头针一直在悬浮着(其实根本不是大头针).2> 监听停止地图拖拽的代理(抱歉我只找到了 mapViewDidFinishRendering 地图渲染完成的代理 <>*<>), 给viewA一个动画, 就好像大头针扎下去一样, 其实不是大头针.
// 在self.view中添加viewA的方法就不提供了.
- (void)mapViewDidFinishRendering:(BMKMapView *)mapView{
在这里添加ViewA的动画
}
这样就还有有个问题. 功能需求二添加了一个大头针, 这里有添加了一个ViewA.不就有两个标记了吗? 对的, 因为这个需求, 我把功能二中天天大头针的方法注释了. 因为第一次加载地图成功后也会调用这个方法, 所以, 看上去好像大头针扎在了 定位的地方一样.
在viewWillAppear中调用
// 制定地图中心在屏幕中显示的位置, 你需要将viewA的中心坐标设置上去.
[_mapView setMapCenterToScreenPt:CGPointMake(self.view.width * 0.5, self.view.height * 0.3)];
- 功能需求四 获得大头针所在位置附近的商圈, 在列表中显示.
这个比较简单 百度提供了方法和代理
// 获取位置信息
-(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]};
BMKReverseGeoCodeOption *reverseGeocodeSearchOption = [[BMKReverseGeoCodeOption alloc]init];
reverseGeocodeSearchOption.reverseGeoPoint = pt;
BOOL flag = [_geocodesearch reverseGeoCode:reverseGeocodeSearchOption];
if(flag)
{
NSLog(@"反geo检索发送成功");
}
else
{
NSLog(@"反geo检索发送失败");
}
}
//获取完毕后后调用代理
-(void)onGetReverseGeoCodeResult:(BMKGeoCodeSearch *)searcher result:(BMKReverseGeoCodeResult *)result errorCode:(BMKSearchErrorCode)error
{
}
- 功能需求5 点击列表中的位置信息, 大头针跟着移动.
列表需要自己实现, 这里只提供移动地图中心点的方法
[_mapView setCenterCoordinate:CLLocationCoordinate2DMake(latitude, longitude) animated:YES];
- 功能需求六 点击定位按钮, 大头针回到自己当前位置
我知道在功能需求二中 _mapView.showsUserLocation 设置成NO 也能实现隐藏小蓝点的功能, 但是这样定位就失效了. 所以我才换成透明图片.
// 定位按钮点击了
- (IBAction)locationBtnDidClick:(id)sender {
[self startFollowing:nil];
[_mapView setCenterCoordinate:_locService.userLocation.location.coordinate animated:YES];
}
// 跟随态
-(IBAction)startFollowing:(id)sender{
_mapView.showsUserLocation = NO;
_mapView.userTrackingMode = BMKUserTrackingModeFollow;
_mapView.showsUserLocation = YES;
}
- 功能需求八 查看别人发送的位置被人的头像需要时, 显示头像, 我的位置显示默认小蓝点, 默认显示别人的位置, 点击定位按钮后,回到我的位置.
因为这个需求, 需要在地图控制器内部做一个分流, 用来区分当前是发送, 还是接受. 其他功能都是已经介绍的需求的组装, 需要说的是, 怎么样默认显示别人的位置.
//默认显示别人的位置.
//这两行代码有顺序要求.
[_mapView setCenterCoordinate:CLLocationCoordinate2DMake(self.provider.paramters.latitudeD, self.provider.paramters.longitudeD) animated:YES];
[self startLocation:nil];
好的功能介绍完毕. 如有错误, 请多多指教, 邮箱 2711056454@qq.com 谢谢.
拉起第三方地图 很好的文章http://www.jianshu.com/p/183f66da9d9c