百度地图相关

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

关于定位

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

你可能感兴趣的:(百度地图相关)