美文网首页
百度地图相关

百度地图相关

作者: wpf_register | 来源:发表于2017-05-17 11:44 被阅读39次

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

    关于定位

    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. 整个项目的这种做法,虽然实现了所有功能,但仍有卡顿感。
      应该还有更好的实现方法或优化空间。

    相关文章

      网友评论

          本文标题:百度地图相关

          本文链接:https://www.haomeiwen.com/subject/tdarxxtx.html