百度地图相关

最近项目中使用到了百度地图,用地图查找房源,并显示指定区域内房源数量,项目完成后码出来梳理记录一下。

关于定位

iOS 系统不允许使用第三方定位,所以地图SDK中的定位方法其实际上还是对原生定位的二次封装,以便开发者方便使用。

当然如果需要可以选择将定位功能封装成一个单例。

 //初始化BMKLocationService  
 _locService = [[BMKLocationService alloc]init];  
 _locService.delegate = self;  
 //启动LocationService  
 [_locService startUserLocationService];  

//实现相关delegate 处理位置信息更新  
//处理方向变更信息  
- (void)didUpdateUserHeading:(BMKUserLocation *)userLocation{  
    //NSLog(@"heading is %@",userLocation.heading);  
}  
//处理位置坐标更新  
- (void)didUpdateBMKUserLocation:(BMKUserLocation *)userLocation  {  
    //NSLog(@"didUpdateUserLocation lat %f,long %f",userLocation.location.coordinate.latitude,userLocation.location.coordinate.longitude);  
}

//以下_mapView为BMKMapView对象  
_mapView.showsUserLocation = YES;//显示定位图层  
[_mapView updateLocationData:userLocation];
自定义标注

项目原先需求是要做类似于百度聚合的效果,显示每个行政区内房源数量,但聚合功能现提供的算法是根据区块距离相近时,自动聚合。所以变通的处理是,根据地图放大级别显示不同的标注。

//地图区域改变完成后会调用此接口 
- (void)mapView:(BMKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
    
    if (mapView.zoomLevel >= 13.500000) {
        
       //取消地图上的所有区域标注,并添加详情标注
        [mapView removeAnnotations:self.annotationArr];
        [self addDetailAnnotation];
    }else{
        //取消地图上所有的详情标注,并添加区域标注
        [mapView removeAnnotations:self.detailAnnotationArr];
        [self addAnnotation];
    } 
}
- (void)addAnnotation{
    [self postWithApiName: APIName
               parameters:parameter
                  success:^(NSDictionary *resultDict) {
                    
                      //请求回来后再次判断一下当前地图放大级别
                      //如若不然效果会较诡异
                      if (_mapView.zoomLevel >= 13.500000) { return ; }
                      
                      //清空现有标注
                      [_mapView removeAnnotations:self.annotationArr];
                      [self.annotationArr removeAllObjects];
                      
                      NSArray *arr = resultDict[@"result"];
                      for (NSDictionary *dic in arr) {
                          CLLocationCoordinate2D coor = CLLocationCoordinate2DMake([dic[@"latitude"] floatValue], [dic[@"longitude"] floatValue]);
                          CustomPointAnnotation *annotation=[[CustomPointAnnotation alloc]init];
                          annotation.coordinate = coor;
                          annotation.title = dic[@"area"];
                          annotation.subtitle = dic[@"total"];
                         
                         //加载标注点
                          [self.annotationArr addObject:annotation];
                          [_mapView addAnnotation:annotation];
                      }

                  
                  } failure:^(NSError *error) { }];

}
- (void)addDetailAnnotation{

   /***得到当前地图页面左上角右下角经纬度*****/
    CLLocationCoordinate2D coor1 = [_mapView convertPoint:CGPointMake(0, 0) toCoordinateFromView:_mapView ];
    CLLocationCoordinate2D coor2 = [_mapView convertPoint:CGPointMake(kWidth, CGRectGetMaxY(_mapView.frame)) toCoordinateFromView:_mapView ];
  
    [self postWithApiName:ApiName
               parameters:@{@"longitude_min":@(coor1.longitude),
                            @"longitude_max":@(coor2.longitude),
                            @"latitude_min":@(coor1.latitude),
                            @"latitude_max":@(coor2.latitude)}
                  success:^(NSDictionary *resultDict) {
                     
                  //请求回来后再次判断一下当前地图放大级别
                  //如若不然效果会较诡异
                  if (_mapView.zoomLevel < 13.500000) {
                      return ;
                  }

                  //清除详情标注
                  [_mapView removeAnnotations:self.detailAnnotationArr];
                  [self.detailAnnotationArr removeAllObjects];
                  
              
                      //快速遍历所有房源
                      for (NSDictionary *dic in arr) {
                          //得到楼楼经纬度
                          CLLocationCoordinate2D coor = CLLocationCoordinate2DMake([dic[@"latitude_y"] floatValue], [dic[@"longitude_x"] floatValue]);
                       
                          CustomDetailPointAnnotation *annotation=[[CustomDetailPointAnnotation alloc]init];
                          
                          annotation.coordinate = coor;
                          annotation.title = dic[@"name"];
                          annotation.subtitle = dic[@"sale"];
                          annotation.houseID = dic[@"houseID"];
                  
                          [_mapView addAnnotation:annotation];//加载标注点
                          [self.detailAnnotationArr addObject:annotation];     
                      }      
    } failure:^(NSError *error) { }];  
}
#pragma mark -  根据anntation生成对应的View
- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id <BMKAnnotation>)annotation{
    
    //详情标注
    if ([annotation isKindOfClass:[CustomDetailPointAnnotation class]]) {
        
        //涉及重用机制
        BMKPinAnnotationView *annotationView = (BMKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:@"AnnotationID"];
        if (!annotationView) {
            annotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"AnnotationID"];
        }
        annotationView.canShowCallout = NO;//不弹出汽泡
        
        //自定义样式
        UIView *bgView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 45)];
        UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 45)];
        [bgView addSubview:imageView];

        UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 100, 20)];
        label.font = [UIFont systemFontOfSize:12];
        label.textAlignment = NSTextAlignmentCenter;
        [bgView addSubview:label];
        label.text = [NSString stringWithFormat:@"%@",annotation.title];
        label.textColor = [UIColor blackColor];
        
        UILabel *sublabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 15, 100, 20)];
        sublabel.textColor = APP_THEME_COLOR;
        sublabel.font = [UIFont systemFontOfSize:12];
        sublabel.textAlignment = NSTextAlignmentCenter;
        [bgView addSubview:sublabel];
        sublabel.text = [NSString stringWithFormat:@"¥%@元/平",annotation.subtitle];

        CustomPointAnnotation *ann = (CustomPointAnnotation*)annotation;
      
        //选中和非选中状态下两种底图
        if ([ann.houseID isEqualToString: self.flag]) {
            imageView.image = [UIImage imageNamed:@"ft2"];
            annotationView.selected = YES;
        }else{
            imageView.image = [UIImage imageNamed:@"ft1"];
            annotationView.selected = NO;
        }
        //***根据bigView得到一张图片***//
        annotationView.image  = [self getImageFromView:bgView];
        annotationView.annotation = annotation;
        return annotationView;
    }
    
    //区域标注
    if ([annotation isKindOfClass:[CustomPointAnnotation class]]) {
    
        BMKPinAnnotationView *annotationView = (BMKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:@"BigAnnotationID"];
        //涉及重用
        if (!annotationView) {
            annotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"BigAnnotationID"];
        }
        annotationView.canShowCallout = NO;//不弹出汽泡
        
        UIView *bgView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 62, 60)];
        UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 62, 60)];
        imageView.image = [UIImage imageNamed:@"fr"];
        [bgView addSubview:imageView];


        UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 62, 60)];
        label.textColor = [UIColor whiteColor];
        label.font = [UIFont systemFontOfSize:12];
        label.textAlignment = NSTextAlignmentCenter;
        label.numberOfLines = 2;
        [bgView addSubview:label];
      
        label.text = [NSString stringWithFormat:@"%@\n%@",annotation.title,annotation.subtitle];
        label.textColor = [UIColor whiteColor];
        annotationView.image  = [self getImageFromView:bgView];
        annotationView.annotation = annotation;
        return annotationView;
    }
   
    //其它标注,默认就用系统的
    if ([annotation isKindOfClass:[BMKPointAnnotation class]]) {
        
        BMKPinAnnotationView *annotationView = (BMKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:@"otherAnnotationID"]; 
        if (!annotationView) {
            annotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"otherAnnotationID"];
        }
        annotationView.animatesDrop = YES; 
    }  
    return nil;
}
- (UIImage*)getImageFromView:(UIView *)view{  
    CGSize s = view.bounds.size;
    // 下面方法,第一个参数表示区域大小。
    // 第二个参数表示是否是非透明的。
    // 如果需要显示半透明效果,需要传NO,否则传YES。
    // 第三个参数就是屏幕密度了
    UIGraphicsBeginImageContextWithOptions(s, NO, [UIScreen mainScreen].scale);
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage*image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

实现下面这两个代理方法目的是点击标注时能快速改变背景图片

#pragma mark - 选中标注视图时的方法
- (void)mapView:(BMKMapView *)mapView didSelectAnnotationView:(BMKAnnotationView *)view{
    //判断是否是详情标注
    if ([view.annotation isKindOfClass:[CustomDetailPointAnnotation class]]) {
        
        view.selected = YES;

        CustomDetailPointAnnotation *ann = (CustomDetailPointAnnotation*)view.annotation;
        //改变点击后标注颜色,
        //其实主要是改变一图底图
        UIView *bgView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 45)];
        UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 45)];
        [bgView addSubview:imageView];
        imageView.image = [UIImage imageNamed:@"ft2"];
        
        UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 100, 20)];
        label.font = [UIFont systemFontOfSize:12];
        label.textAlignment = NSTextAlignmentCenter;
        [bgView addSubview:label];
        label.text = [NSString stringWithFormat:@"%@",ann.title];
        label.textColor = [UIColor blackColor];
        
        UILabel *sublabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 15, 100, 20)];
        sublabel.textColor = APP_THEME_COLOR;
        sublabel.font = [UIFont systemFontOfSize:12];
        sublabel.textAlignment = NSTextAlignmentCenter;
        [bgView addSubview:sublabel];
        sublabel.text = [NSString stringWithFormat:@"¥%@元/
        
        view.image  = [self getImageFromView:bgView];
        view.annotation = ann;
        self.flag = ann.houseID;
        [mapView setCenterCoordinate:ann.coordinate animated:YES];

       
    }else if([view.annotation isKindOfClass:[CustomPointAnnotation class]]){

        //如果点击的是区域标注则放大地图
        self.flag = @"";
        [mapView setZoomLevel:mapView.zoomLevel+1];
        
    }else{
        
    }
}

#pragma mark - 取消选中标注视图时的方法

- (void)mapView:(BMKMapView *)mapView didDeselectAnnotationView:(BMKAnnotationView *)view{
    
    if ([view.annotation isKindOfClass:[CustomDetailPointAnnotation class]]) {
        
        view.selected = NO;
        
        CustomPointAnnotation *ann = (CustomPointAnnotation*)view.annotation;
        //改变点击后标注颜色
        UIView *bgView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 45)];
        UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 45)];
        [bgView addSubview:imageView];
        imageView.image = [UIImage imageNamed:@"ft1"];
        
        UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 100, 20)];
        label.font = [UIFont systemFontOfSize:12];
        label.textAlignment = NSTextAlignmentCenter;
        [bgView addSubview:label];
        label.text = [NSString stringWithFormat:@"%@",ann.title];
        label.textColor = [UIColor blackColor];
        
        UILabel *sublabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 15, 100, 20)];
        sublabel.textColor = APP_THEME_COLOR;
        sublabel.font = [UIFont systemFontOfSize:12];
        sublabel.textAlignment = NSTextAlignmentCenter;
        [bgView addSubview:sublabel];
        sublabel.text = [NSString stringWithFormat:@"¥%@元/平",ann.subtitle];
        
        
        view.image  = [self getImageFromView:bgView];
        view.annotation = ann;
    }
}
#pragma mark - 自定义的Annotation
//区域标注
@interface CustomPointAnnotation : BMKPointAnnotation
@property (nonatomic,retain)NSString *houseID;
@end
@implementation CustomPointAnnotation
@end

//详情标注
@interface CustomDetailPointAnnotation : BMKPointAnnotation
@property (nonatomic,retain) NSString *houseID;
@property (nonatomic,retain) NSString *area;
@property (nonatomic,retain) NSString *address;
@end
@implementation CustomDetailPointAnnotation
@end

PS:
在项目功能实现时遇到的问题是:

  1. 请情标注较多时不可避免的出现卡顿,所以请求时只请求当前面的标注。
  2. 点击详情标注时将标注移动到地图中央,同时请求当前页标注,
    请求回来后要再次判断当前页面放大级别。另外为了有点击回馈,
    实现了点击和取消点的方法。
  3. 整个项目的这种做法,虽然实现了所有功能,但仍有卡顿感。
    应该还有更好的实现方法或优化空间。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,829评论 1 331
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,603评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,846评论 0 226
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,600评论 0 191
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,780评论 3 272
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,695评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,136评论 2 293
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,862评论 0 182
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,453评论 0 229
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,942评论 2 233
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,347评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,790评论 2 236
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,293评论 3 221
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,839评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,448评论 0 181
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,564评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,623评论 2 249

推荐阅读更多精彩内容

  • 一.配置百度地图SDK 1. 申请密钥 进入应用管理平台,点击创建应用 然后点击提交 密钥就申请成功了!!在左侧的...
    黑白灰的绿i阅读 1,373评论 0 2
  • 地图不能拖动问题 如果不能销毁的界面,离开界面执行[mapView viewWillDisappear]后,不要在...
    焉逢12阅读 266评论 0 0
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,050评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,472评论 25 707
  • 你有没有过那么一瞬间,感觉无论四周环绕着多少嬉笑怒骂的人,无论有多么亲密无间的朋友陪伴在你身边,你依然觉得孤独。 ...
    冬柯一梦_BTS_army阅读 383评论 0 0