百度地图 拖动时时定位

思路:

(1)把图片放到屏幕的中间,这样在拖动的时候就不会跟随着地图移动了。
(2)百度地图提供了,View坐标和地理坐标转换的方法。正式这个方法的存在,方便我们及时的获取拖动后的,屏幕中间的图片所在位置的经纬度。

代码如下:

@interface HomeViewController ()<BMKMapViewDelegate,BMKLocationServiceDelegate,BMKGeoCodeSearchDelegate>{
    
    BMKLocationService * _locService;
    
}
@property (nonatomic,strong) UIView * locationView;
@property (nonatomic,strong) UIImageView * locImageView;
@property (nonatomic,strong) UIView * messageView;
@property (nonatomic,strong) UILabel * addressLabel;
@property (nonatomic,strong) UIButton * sureButton;
@property (nonatomic,strong) NSString * name;
@property (nonatomic,assign) CLLocationCoordinate2D location2D;

@property (nonatomic, strong)BMKGeoCodeSearch *searchAddress;
@property (strong, nonatomic)BMKMapView *mapView;
@property (nonatomic,strong)BMKUserLocation *userLocation; //定位功能

@end

@implementation HomeViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    [self setupDatasource];
    [self setupNav];
    [self setupViews];
    [self setupGoBack];
}

-(void)setupDatasource {
    
}

-(void)setupNav {
    
    self.title = @"首页";
    self.navigationItem.leftBarButtonItem = [UIBarButtonItem itemWithImage:@"me" highImage:@"me" target:self action:@selector(goMe:)];
    
}
//跳转个人中心
-(void)goMe : (id)sender {
    
}

-(void)setupViews {
    
    self.mapView = [[BMKMapView alloc] initWithFrame:CGRectMake(0, 0, YSWIDTH, YSHEIGHT - 64)];
    self.mapView.delegate =self;
    //设置地图的显示样式
    self.mapView.mapType = BMKMapTypeStandard;//标准地图
    //设定地图是否打开路况图层
    self.mapView.trafficEnabled = YES;
    //底图poi标注
    self.mapView.showMapPoi = YES;
    //在手机上当前可使用的级别为3-21级
    self.mapView.zoomLevel = 21;
    //设定地图View能否支持旋转
    self.mapView.rotateEnabled = NO;
    //设定地图View能否支持用户移动地图
    self.mapView.scrollEnabled = YES;
    //添加到view上
    [self.view addSubview:self.mapView];
    
    [self initlocationService];

}

-(void)setupGoBack {
    
    UIButton *gobackBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    gobackBtn.frame = CGRectMake(10, YSHEIGHT - 10 - 64 - 40, 40, 40);
    gobackBtn.backgroundColor = [UIColor redColor];
    [gobackBtn setImage:[UIImage imageNamed:@""] forState:UIControlStateNormal];
    [gobackBtn addTarget:self action:@selector(locationButtonClick:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:gobackBtn];
    
}
#pragma mark --initlocationService--定位

-(void)initlocationService{
    
    _locService = [[BMKLocationService alloc]init];
    _locService.delegate = self;
    [_locService startUserLocationService];
    _mapView.showsUserLocation = NO;//先关闭显示的定位图层
    _mapView.userTrackingMode = BMKUserTrackingModeNone;//设置定位的状态
    _mapView.showsUserLocation = YES;//显示定位图层
    _mapView.showMapScaleBar = YES;//显示比例尺
    CGPoint point = CGPointMake(55, YSHEIGHT - 10 - 64 - 20);
    _mapView.mapScaleBarPosition = point;//比例尺位置
    _mapView.zoomLevel = 17;//地图显示的级别
    _mapView.logoPosition = BMKLogoPositionRightBottom;//logo位置
    
    
    _searchAddress = [[BMKGeoCodeSearch alloc]init];
    _searchAddress.delegate = self;
    
}
//这里是创建中心显示的图片和显示详细地址的View

- (void)createLocationSignImage{
    
    //LocationView定位在当前位置,换算为屏幕的坐标,创建的定位的图标
    
    self.locationView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 28, 35)];
    self.locImageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 28, 35)];
    self.locImageView.image = [UIImage imageNamed:@"CenterPointBlackImage"];
    [self.locationView addSubview:self.locImageView];
    
    //messageView 展示定位信息的View和Label和button
    
    self.messageView = [[UIView alloc]init];
    self.messageView.backgroundColor = [UIColor whiteColor];
    
    //把当前定位的经纬度换算为了View上的坐标
    
    CGPoint point = [self.mapView convertCoordinate:_mapView.centerCoordinate toPointToView:_mapView];
    
    //当解析出现错误的时候,会出现超出屏幕的情况,一种是大于了屏幕,一种是小于了屏幕
    if(point.x > YSWIDTH || point.x < YSWIDTH / 5){
        
        point.x = _mapView.centerX;
        point.y = _mapView.centerY - 64;
        
    }
    
    YSLog(@"Point======%f=======%f",point.x,point.y);
    //重新定位了LocationView
    self.locationView.center = point;
    [self.locationView setFrame:CGRectMake(point.x - 14, point.y - 18, 28, 35)];
    
    //重新定位了messageView
    [self.messageView setFrame:CGRectMake(30, point.y - 40 - 20, YSWIDTH - 60, 40)];
    
    //展示地址信息的label
    self.addressLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 0, self.messageView.frame.size.width - 80, 40)];
    
    self.addressLabel.adjustsFontSizeToFitWidth = YES;
    
    [self.messageView addSubview:self.addressLabel];
    
    //把地址信息传递到上个界面的button
    
    self.sureButton = [[UIButton alloc]initWithFrame:CGRectMake(self.addressLabel.frame.origin.x + self.addressLabel.frame.size.width, 0,self.messageView.frame.size.width - self.addressLabel.frame.origin.x - self.addressLabel.frame.size.width, 40)];
    
    [self.messageView addSubview:self.sureButton];
    
    self.sureButton.backgroundColor =colorWithHex(0x2ecb7d);
    
    [self.sureButton setTitle:@"确定" forState:UIControlStateNormal];
    
    self.sureButton.titleLabel.font = [UIFont systemFontOfSize:13.0f];
    
    [self.sureButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    
    [self.sureButton addTarget:self action:@selector(sureButtonClick:) forControlEvents:UIControlEventTouchUpInside];
    
    [self.mapView addSubview:self.messageView];
    
    [self.mapView addSubview:self.locationView];
    
}

/**
 *用户位置更新后,会调用此函数
 *@param userLocation 新的用户位置
 */
- (void)didUpdateBMKUserLocation:(BMKUserLocation *)userLocation{
    
    BMKCoordinateRegion region;
    
    region.center.latitude  = userLocation.location.coordinate.latitude;
    region.center.longitude = userLocation.location.coordinate.longitude;
    region.span.latitudeDelta = 0;
    region.span.longitudeDelta = 0;
    
    YSLog(@"当前的坐标是:%f,%f",userLocation.location.coordinate.latitude,userLocation.location.coordinate.longitude);
    
    
    [_mapView updateLocationData:userLocation];
    [_locService stopUserLocationService];//取消定位  这个一定要写,不然无法移动定位了
    _mapView.centerCoordinate = userLocation.location.coordinate;
    YSLog(@" _mapView.centerCoordinate------%f-----%f", _mapView.centerCoordinate.latitude, _mapView.centerCoordinate.longitude);
    if (_messageView == nil && _locationView == nil) {
        [self createLocationSignImage];
    }
    
    
}


//定位地理位置确定按钮的点击
- (void)sureButtonClick:(UIButton *)button{
    
    
}


/**
 *当点击annotation view弹出的泡泡时,调用此接口
 *@param mapView 地图View
 *@param view 泡泡所属的annotation view
 */
- (void)mapView:(BMKMapView *)mapView annotationViewForBubble:(BMKAnnotationView *)view{
    YSLog(@"点击了");
    CLLocationCoordinate2D pt=(CLLocationCoordinate2D){0,0};
    pt=(CLLocationCoordinate2D){mapView.region.center.latitude,mapView.region.center.longitude};
    BMKReverseGeoCodeOption * option = [[BMKReverseGeoCodeOption alloc]init];
    option.reverseGeoPoint = pt;
    BOOL flag=[_searchAddress reverseGeoCode:option];
    
    if (flag) {
        // _mapView.showsUserLocation=NO;//不显示自己的位置
        
    }
}

//自定义大头针
- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id <BMKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[BMKPointAnnotation class]]) {
        BMKPinAnnotationView *newAnnotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"myAnnotation"];
        newAnnotationView.pinColor = BMKPinAnnotationColorPurple;
        newAnnotationView.animatesDrop = YES;// 设置该标注点动画显示
        return newAnnotationView;
    }
    return nil;
}
//地图被拖动的时候,需要时时的渲染界面,当渲染结束的时候我们就去定位然后获取图片对应的经纬度
- (void)mapView:(BMKMapView *)mapView onDrawMapFrame:(BMKMapStatus*)status{
    YSLog(@"onDrawMapFrame");
}

- (void)mapView:(BMKMapView *)mapView regionWillChangeAnimated:(BOOL)animated{
    YSLog(@"regionWillChangeAnimated");
}

- (void)mapView:(BMKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
    YSLog(@"regionDidChangeAnimated");
    
    CGPoint touchPoint = self.locationView.center;
    
    CLLocationCoordinate2D touchMapCoordinate =
    [self.mapView convertPoint:touchPoint toCoordinateFromView:self.mapView];//这里touchMapCoordinate就是该点的经纬度了
    YSLog(@"touching %f,%f",touchMapCoordinate.latitude,touchMapCoordinate.longitude);
    
    BMKReverseGeoCodeOption * option = [[BMKReverseGeoCodeOption alloc]init];
    option.reverseGeoPoint = touchMapCoordinate;
    BOOL flag=[_searchAddress reverseGeoCode:option];
    
    if (flag) {
        //        _mapView.showsUserLocation=NO;//不显示自己的位置
    }
}

//定位自己的位置
- (void)locationButtonClick:(UIButton *)sender {
    
    [_locService startUserLocationService];
    _mapView.showsUserLocation = NO;//先关闭显示的定位图层
    _mapView.userTrackingMode = BMKUserTrackingModeNone;//设置定位的状态
    _mapView.showsUserLocation = YES;//显示定位图层
}

//点击地图的空白区域
- (void)mapView:(BMKMapView *)mapView onClickedMapBlank:(CLLocationCoordinate2D)coordinate{
    
    YSLog(@"onClickedMapBlank-latitude==%f,longitude==%f",coordinate.latitude,coordinate.longitude);
}

//点击地图中的背景有标记的区域
- (void)mapView:(BMKMapView *)mapView onClickedMapPoi:(BMKMapPoi *)mapPoi{
    YSLog(@"点击onClickedMapPoi---%@",mapPoi.text);
    
    /**
     //点击地图上有标注位置的地方添加大头针
    CLLocationCoordinate2D coordinate = mapPoi.pt;
    //长按之前删除所有标注
    NSArray *arrayAnmation=[[NSArray alloc] initWithArray:_mapView.annotations];
    [_mapView removeAnnotations:arrayAnmation];
    //设置地图标注
    BMKPointAnnotation* annotation = [[BMKPointAnnotation alloc]init];
    annotation.coordinate = coordinate;
    annotation.title = mapPoi.text;
    [_mapView addAnnotation:annotation];
    BMKReverseGeoCodeOption *re = [[BMKReverseGeoCodeOption alloc] init];
    re.reverseGeoPoint = coordinate;
    [MBProgressHUD showHUDAddedTo:self.view animated:YES];
    [_searchAddress reverseGeoCode:re];
    BOOL flag =[_searchAddress reverseGeoCode:re];
    if (!flag){
        YSLog(@"search failed!");
    }
     */
}

//根据经纬度返回点击的位置的名称
-(void)onGetReverseGeoCodeResult:(BMKGeoCodeSearch *)searcher result:(BMKReverseGeoCodeResult *)result errorCode:(BMKSearchErrorCode)error{
    
    [MBProgressHUD hideHUDForView:self.view animated:YES];
    NSString * resultAddress = @"";
    NSString * houseName = @"";
    
    CLLocationCoordinate2D  coor = result.location;
    
    if(result.poiList.count > 0){
        BMKPoiInfo * info = result.poiList[0];
        if([info.name rangeOfString:@"-"].location != NSNotFound){
            houseName = [info.name componentsSeparatedByString:@"-"][0];
        }else{
            houseName = info.name;
        }
        resultAddress = [NSString stringWithFormat:@"%@%@",result.address,info.name];
    }else{
        resultAddress =result.address;
    }
    
    if(resultAddress.length == 0){
        self.addressLabel.text = @"位置解析错误,请拖动重试!";
        return;
    }
    
    self.addressLabel.text = resultAddress;
    
    self.location2D = coor;
    self.name = houseName;
}

//点击一个大头针
- (void)mapView:(BMKMapView *)mapView didSelectAnnotationView:(BMKAnnotationView *)view{
    YSLog(@"点击didSelectAnnotationView-");
}

/**
 *在地图View将要启动定位时,会调用此函数
 */
- (void)willStartLocatingUser
{
    YSLog(@"start locate");
}

/**
 *用户方向更新后,会调用此函数
 *@param userLocation 新的用户位置
 */
- (void)didUpdateUserHeading:(BMKUserLocation *)userLocation
{
    [_mapView updateLocationData:userLocation];
    YSLog(@"heading is %@",userLocation.heading);
}


/**
 *在地图View停止定位后,会调用此函数
 */
- (void)didStopLocatingUser
{
    YSLog(@"stop locate");
}

/**
 *定位失败后,会调用此函数
 *@param error 错误号,参考CLError.h中定义的错误号
 */
- (void)didFailToLocateUserWithError:(NSError *)error
{
    YSLog(@"location error");
}

- (void)dealloc {
    
    if (_mapView) {
        _mapView = nil;
    }
}



- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,326评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,228评论 1 304
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,979评论 0 252
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,489评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,894评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,900评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,075评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,803评论 0 205
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,565评论 1 249
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,778评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,255评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,582评论 3 261
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,254评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,151评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,952评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,035评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,839评论 2 277

推荐阅读更多精彩内容