文档章节

关于大头针和覆盖物的一些知识

Virgo_only
 Virgo_only
发布于 2016/10/14 10:59
字数 1655
阅读 140
收藏 0

       在百度地图的开发过程中,一般都是根据model类给出的经纬度在地图上添加大头针,以及当选中当前的大头针的时候在此添加覆盖物以标记这个位置就是当前选中的,与此同时,还要根据选中的大头针来确定选中的是那个model类的对象。

需求一

      地图中一般都有多个大头针的对象,怎么样将所有的大头针都显示在地图的显示范围之内,并且以一个合适的范围,首先的思路是这种 :取出所有的大头针对象,根据大头针对象的经纬度算出当前所有大头针的最大、最小的经纬度,然后 (最大经纬度 + 最小经纬度)/2,就可以得到当前显示范围的中心点的经纬度,最大经纬度-最小经纬度  就可以得到地图的显示范围。

 

上代码

-(void) centerMapWithArray:(NSArray *)routes {
    
    CLLocationDegrees maxLat = 0.0;
    CLLocationDegrees maxLon = 0.0;
    CLLocationDegrees minLat = 0.0;
    CLLocationDegrees minLon = 0.0;
    for(int idx = 0; idx < routes.count; idx++)
    {
        BMKPointAnnotation* currentLocation = [routes objectAtIndex:idx];

        if (idx == 0) {                //以第一个坐标点做初始值
            
            minLat = currentLocation.coordinate.latitude;
            maxLat = currentLocation.coordinate.latitude;
            minLon = currentLocation.coordinate.longitude;
            maxLon = currentLocation.coordinate.longitude;
        }else{
            //对比筛选出最小纬度,最大纬度;最小经度,最大经度
            minLat = MIN(minLat, currentLocation.coordinate.latitude);
            maxLat = MAX(maxLat, currentLocation.coordinate.latitude);
            minLon = MIN(minLon, currentLocation.coordinate.longitude);
            maxLon = MAX(maxLon, currentLocation.coordinate.longitude);
        }
    }
    
    //计算中心点
    CLLocationCoordinate2D centCoor;
    centCoor.latitude = (CLLocationDegrees)((maxLat+minLat) * 0.5f);
    centCoor.longitude = (CLLocationDegrees)((maxLon+minLon) * 0.5f);
    BMKCoordinateSpan span;
    //计算地理位置的跨度,*1.1 防止标注刚好在地图的边缘
    span.latitudeDelta = (maxLat - minLat)*1.1;
    span.longitudeDelta = (maxLon - minLon)*1.1;
    //得出数据的坐标区域
    //    BMKCoordinateRegion region = BMKCoordinateRegionMake(centCoor, span);
    BMKCoordinateRegion region;
    region.center = centCoor;
    region.span = span;
    [_mapView setRegion:region animated:YES];
   
}

通过查看百度地图的API,可以知道

/// 当前地图View的已经添加的标注数组
@property (nonatomic, readonly) NSArray *annotations;

这个数组返回当前地图View中的标注,routes  需要把 self.mapView.annotations作为参数。大家注意到计算显示范围的时候 *1.1,这是防止大头针恰好在地图的最边缘,不合适。

尼玛,写完之后发现百度地图提供了相应的方法:

/**
 *设置地图使显示区域显示所有annotations,如果数组中只有一个则直接设置地图中心为annotation的位置
 *@param annotations 指定的标注
 *@param animated 是否启动动画
 */
- (void)showAnnotations:(NSArray *)annotations animated:(BOOL)animated;

系统的方法还是存在有些标注在当前显示范围的最边缘,所有还是采取了上面一种方式来处理这种情况。

需求二

     点击大头针的话,需要确定当前选中的大头针对象对应的model类的哪一个对象。思路如下,如果可以拿到选中大头针的对象的经纬度的话,就可以根据经纬度确定对应的model类对象。

百度地图提供了这个方法

 

/**
 *当选中一个annotation views时,调用此接口
 *@param mapView 地图View
 *@param views 选中的annotation views
 */
- (void)mapView:(BMKMapView *)mapView didSelectAnnotationView:(BMKAnnotationView *)view;

   在这个方法中可以获取到BMKAnnotationView和BMKMapView对应的对象,显然BMKAnnotationView对于解决问题是有用的。

查看API,BMKAnnotationView并没有经度或者纬度的属性...但是有这个属性

///关联的annotation
@property (nonatomic, strong) id <BMKAnnotation> annotation;

查看BMKAnnotation对应的API

//
//  Copyright 2011 Baidu Inc. All rights reserved.
//

#import <CoreGraphics/CoreGraphics.h>
#import <CoreLocation/CoreLocation.h>
#import <Foundation/Foundation.h>

/// 该类为标注点的protocol,提供了标注类的基本信息函数
@protocol BMKAnnotation <NSObject>

///标注view中心坐标.
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;

@optional

有coordinate属性,通过这个属性就可以获取到选中的大头针对应的经纬度,然后根据经纬度就可以确认此大头针对应的model类对象。

需求三

选中大头针的时候要在这里加一个圆形的覆盖物,以标注选中的状态。这个需求其实不难,系统有添加覆盖物的方法 

/**
 *向地图窗口添加Overlay,需要实现BMKMapViewDelegate的-mapView:viewForOverlay:函数来生成标注对应的View
 *@param overlay 要添加的overlay
 */
- (void)addOverlay:(id <BMKOverlay>)overlay;

需要BMKOverlay的对象,

/**
 *根据中心点和半径生成圆
 *@param coord 中心点的经纬度坐标
 *@param radius 半径,单位:米
 *@return 新生成的圆
 */
+ (BMKCircle *)circleWithCenterCoordinate:(CLLocationCoordinate2D)coord
                                  radius:(CLLocationDistance)radius;

这里圆形覆盖物的半径需要的参数单位为:米。怎么确定这个参数的大小呢???

在网上找了半天也没有发现有营养的信息,只能用笨的方法了。

添加的时候只能靠脸一个个的大小做测试,找到一个合适的大小比如:currectRadius,然后获取到当前显示范围的经度或者纬度,这样的话就可以获取的一个比例,找到这个合适的比例的话,就可以确定圆形覆盖物的半径大小了。

需求四

添加完成覆盖物之后,当地图的显示范围变化的时候,就会出现覆盖物的范围已经不合适了,显示范围变小的时候,覆盖物的半径就太大了,反之,亦然。

不管地图显示范围多大,覆盖物大小不变。

API中有几个方法是和地图显示范围变化有关系的

/**
 *地图区域即将改变时会调用此接口
 *@param mapview 地图View
 *@param animated 是否动画
 */
- (void)mapView:(BMKMapView *)mapView regionWillChangeAnimated:(BOOL)animated;

/**
 *地图区域改变完成后会调用此接口
 *@param mapview 地图View
 *@param animated 是否动画
 */
- (void)mapView:(BMKMapView *)mapView regionDidChangeAnimated:(BOOL)animated;

需求的是覆盖物的半径大小要随着地图显示范围的变化而时时改变,这两个方法都可以实现改变半径,但是和需求并不符合接着找吧。

/**
 *地图渲染每一帧画面过程中,以及每次需要重绘地图时(例如添加覆盖物)都会调用此接口
 *@param mapview 地图View
 *@param status 此时地图的状态
 */
- (void)mapView:(BMKMapView *)mapView onDrawMapFrame:(BMKMapStatus*)status

这个方法是绘图的时候调用的,地图显示范围变化的时候,覆盖物也要重绘,这样的话,这个方法可以实现这个需求。这里以圆形覆盖物为例,实现的代码在这里。

for (BMKOverlayView *lay in mapView.overlays) {
        if ([lay isKindOfClass:[BMKCircle class]]) {//取到当前显示的覆盖物(我这里只有一个)
            BMKCircle *circleView = (BMKCircle *)lay;
            circleView.radius = mapView.region.span.longitudeDelta*合适的比例;//改变覆盖物的半径大小
        }
    }

这些是遇到的一些问题和解决方案,希望有其他方案的朋友可以赐教。

© 著作权归作者所有

Virgo_only
粉丝 7
博文 41
码字总数 12828
作品 0
石家庄
程序员
私信 提问
iOS原生地图开发指南再续——地图覆盖物的应用

iOS原生地图开发指南再续——地图覆盖物的应用 一、引言 在前两篇博客中,将iOS系统的地图框架MapKit中地图的设置与应用以及关于添加大头针和自定义大头针的相关操作做了详细的介绍。链接如下...

珲少
2015/05/16
722
1
iOS原生地图开发进阶——使用导航和附近兴趣点检索

iOS原生地图开发进阶——使用导航和附近兴趣点检索 iOS中的mapKit框架对国际化的支持非常出色。在前些篇博客中,对这个地图框架的基础用法和标注与覆盖物的添加进行了详细的介绍,这篇博客将...

珲少
2015/05/18
1K
0
iOS 高德地图(二)(进阶具体使用的细节)

前面我们配置好了SDK的环境,也在高德的官网中申请了AppKey:de5b39fb2b066ed80c51383bb3a1fe42,接下来我们就可以开始代码的编写,实现一个基本的地图显示了 代码配置显示地图(在开发指南中...

龚志明
2016/03/15
3.8K
1
关于地图SDK3.6.0找不到overlayutil

为了给广大开发者提供更丰富的覆盖物展示能力,自V3.6.0起,原内置覆盖物相关类代码开源(MarkerManager/OverlayManager/PoiOverlay/TransitRouteOverlay/WalkingRouteOverlay/BusLineOverla...

whoisliang
2017/11/17
48
0
关于VUE项目地图开发中大量点标记绘制一些总结

问题说明 在地图开发中,当地图中绘制大量的标记点后,无论是拖动或者缩放,都会感觉到明显的卡顿现象。(一般超过800个点后就比较明显了).在平时的工作业务中,由于公司的实时监控页面需要...

tzpstorm
2018/08/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Vue学习01

我的github地址https://github.com/zhangl-w/VueDemo/tree/master/VueDemo 一、基本代码 1.导入Vue包,导包后浏览器内存中会产生一个Vue的构造函数 2.创建一个Vue实例 3.el 表示,当前我们n...

zhang_l
31分钟前
5
0
centos7.x 安装harbor 1.9.3

首先必须安装docker和docker-compose 推荐使用pip安装docker-compose,因为pip可以为你自动对应版本问题 1.docker安装 curl -sfL https://get.docker.io | sh -systemctl start docker 2.d...

Elson
31分钟前
5
0
每天积累一点:射频阻抗

对我来说,阻抗是一个非常令人困惑的概念(术语)。以下是我第一次学习阻抗概念时脑海中出现的许多问题。同样的问题也让你烦恼吗? 当我第一次在高中物理中学习“电阻(Resistance )”时,它...

demyar
33分钟前
5
0
人生苦短?试试Groovy进行单元测试

如果您今天正在编程,那么您很可能听说过单元测试或测试驱动的开发过程。我还没有遇到一个既没有听说过又没有听说过单元测试并不重要的程序员。在随意的讨论中,大多数程序员似乎认为单元测试...

八音弦
34分钟前
4
0
GMAT词汇怎么背?简单记忆法让你不再害怕背单词

GMAT考试对于词汇的掌握和使用要求高,可以说是GMAT考试的难关之一。面对学术化专业化难度颇高的词汇,考生难免会产生畏惧退缩的情绪。GMAT难词怎么背?有没有轻松背单词的方法呢?下面小编就为...

bole6
36分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部