您当前的位置: iOS SDK > 开发指南 > 基础地图
基础地图

简介

开发者可利用SDK提供的接口,使用百度为您提供的基础地图数据。目前百度地图SDK所提供的地图等级为3-21级,所包含的信息有建筑物、道路、河流、学校、公园等内容。

百度地图支持多点触摸、双击放大、多点单击缩小、旋转等手势操作,此外自2.2.0版本起,支持相应的控制接口来开启/关闭这些手势操作;此外,在该版本地图对象实现了多实例特性,即开发者可以在一个页面中建立多个地图对象,并且针对这些对象分别操作且不会产生相互干扰。具体使用方法请参考MultiMapViewDemo的介绍。

地图上自定义的标注点和覆盖物我们统称为地图覆盖物。您可以通过定制BMKAnnotation和BMKOverlay来添加对应的标注点和覆盖物。地图覆盖物的设计遵循数据与View分离的原则,BMKAnnotation和BMKOverlay系列的类主要用来存放覆盖物相关的数据,BMKAnnotaionView和BMKOverlayView系列类为覆盖物对应的View。

SDK支持画点、折线、圆、多边形(包括凹凸两种)、图片图层和自定义覆盖物。从2.0.0开始矢量地图采用OpenGL绘制,新增支持OpenGL绘制的基本线绘制、面绘制接口。详见AnnotationDemo,SDK内置的BMKPolylineOverlay、BMKPolygonOverlay,BMKCircleOverlay均采用OpenGL绘制。

地图类型

百度地图SDK为您提供了3种类型的地图资源(普通矢量地图、卫星图和空白地图),开发者可以利用BMKMapView中的mapType属性来设置地图类型。

空白地图, 基础地图瓦片将不会被渲染。在地图类型中设置为BMKMapTypeNone,将不会使用流量下载基础地图瓦片图层。使用场景:与瓦片图层一起使用,节省流量,提升自定义瓦片图下载速度。

设置空白地图的方法如下:

_mapView.mapType = BMKMapTypeNone;//设置地图为空白类型

开启卫星图的方法如下:

//切换为卫星图  
[_mapView setMapType:BMKMapTypeSatellite];

运行后效果如下:


sdkios-3.png

由卫星图切换为普通矢量图的核心代码如下:

//切换为普通地图  
[_mapView setMapType:BMKMapTypeStandard];

实时交通图

利用地图SDK所提供的接口,开发者可显示当前地图城市内的实时路况信息(点击查看支持实时路况的城市)。此外,自2.0.0版本起,SDK还支持城际(城市之间,如高速)路况。

开启实时路况的核心代码如下:

//打开实时路况图层  
[_mapView setTrafficEnabled:YES];

运行后效果如下:

tra.png

关闭实时路况的核心代码如下:

//关闭实时路况图层  
[_mapView setTrafficEnabled:NO];

百度城市热力图

百度地图SDK继为广大开发者开放热力图本地绘制能力之后,再次进一步开放百度自有数据的城市热力图层,帮助开发者构建形式更加多样的移动端应用。

百度城市热力图的性质及使用与实时交通图类似,只需要简单的接口调用,即可在地图上展现样式丰富的百度城市热力图。

在地图上使用百度城市热力图的核心代码如下:

//打开百度城市热力图图层(百度自有数据)
[_mapView setBaiduHeatMapEnabled:YES];
 
//关闭百度城市热力图图层(百度自有数据)
[_mapView setBaiduHeatMapEnabled:NO];

地图控制和手势

地图控制

地图Logo

默认在左下角显示,不可以移除。 通过logoPosition属性,使用枚举类型控制显示的位置,共支持6个显示位置(左下,中下,右下,左上,中上,右上)。

地图Logo不允许遮挡,可通过mapPadding属性可以设置地图边界区域,来避免UI遮挡。

指南针

指南针默认为开启状态,可以关闭显示 。

比例尺

比例尺默认为开启状态,可以关闭显示。同时支持设置MaxZoomLevel和minZoomLevel。

地图手势

地图平移

控制是否启用或禁用平移的功能,默认开启。如果启用,则用户可以平移地图

地图缩放

控制是否启用或禁用缩放手势,默认开启。如果启用,用户可以双指点击或缩放地图视图。

地图俯视(3D)

控制是否启用或禁用俯视(3D)功能,默认开启。如果启用,则用户可使用双指 向下或向上滑动到俯视图。

地图旋转

控制是否启用或禁用地图旋转功能,默认开启。如果启用,则用户可使用双指 旋转来旋转地图。

3D-Touch手势

自2.10.0起,支持3D Touch回调,可控制是否开启或关闭回调3D-Touch手势,默认为关闭。

禁止所有手势

控制是否一并禁止所有手势,默认关闭。如果启用,所有手势都将被禁用。

地图标注

标注

BMKAnnotation为标注对应的protocal,您可以自定义标注类实现该protocal。百度地图SDK也预置了基本的标注点(BMKPointAnnotation)和一个大头针标注View(BMKPinAnnotationView),您可以直接使用来显示标注。方法如下:

第一步,修改您的ViewController.h文件,添加以下代码,使您的ViewController实现BMKMapViewDelegate协议:

  @interface AnnotationDemoViewController : UIViewController <bmkmapviewdelegate> {     
      IBOutlet BMKMapView* _mapView;      
  }      
  @end

第二步,修改您的ViewController.m文件,实现BMKMapViewDelegate的_mapView:viewForAnnotation:函数,并在viewDidAppear添加标注数据对象,核心代码如下:

- (void) viewDidAppear:(BOOL)animated {    
        // 添加一个PointAnnotation    
        BMKPointAnnotation* annotation = [[BMKPointAnnotation alloc]init];    
        CLLocationCoordinate2D coor; 
        coor.latitude = 39.915;   
        coor.longitude = 116.404;
        annotation.coordinate = coor;    
        annotation.title = @"这里是北京";    
        [_mapView addAnnotation:annotation];    
    }    
// Override  
- (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;  
    }

运行后,会在地图显示对应的标注点,点击会弹出气泡,效果如图:

sdkios-4.png

通过以上几步简单的操作,您就可以实现在地图上添加标注了,相应的删除标注方法如下:

if (annotation != nil) {    
    [_mapView removeAnnotation:annotation];    
}

点聚合功能

自v2.9.0版本起,新增点聚合功能,可通过缩小地图层级,将定义范围内的多个标注点,聚合显示成一个标注点,解决加载大量点要素到地图上产生覆盖现象的问题,并提高性能。已在Demo中开放源码,方便开发者自行修改。


添加点聚合的方法:

1、声明点聚合管理类为全局变量,并初始化,核心代码如下

BMKClusterManager *_clusterManager;//点聚合管理类
 
//初始化点聚合管理类
 
_clusterManager = [[BMKClusterManager alloc] init];

2、向点聚合管理类中添加点,核心代码如下

CLLocationCoordinate2D coor = CLLocationCoordinate2DMake(39.915, 116.404);
    //向点聚合管理类中添加标注
    for (NSInteger i = 0; i < 20; i++) {
        double lat =  (arc4random() % 100) * 0.001f;
        double lon =  (arc4random() % 100) * 0.001f;
        BMKClusterItem *clusterItem = [[BMKClusterItem alloc] init];
        clusterItem.coor = CLLocationCoordinate2DMake(coor.latitude + lat, coor.longitude + lon);
        [_clusterManager addClusterItem:clusterItem];
    }

3.获取聚合后的点,并添加到地图中,核心代码如下

///获取聚合后的标注
    NSArray *array = [_clusterManager getClusters:_clusterZoom];
    NSMutableArray *clusters = [NSMutableArray array];
    for (BMKCluster *item in array) {
        ClusterAnnotation *annotation = [[ClusterAnnotation alloc] init];
        annotation.coordinate = item.coordinate;
        annotation.size = item.size;
        annotation.title = [NSString stringWithFormat:@"我是%ld个", item.size];
        [clusters addObject:annotation];
    }
    [_mapView removeAnnotations:_mapView.annotations];
    [_mapView addAnnotations:clusters];

具体源码请在ClusterDemo中查看。

底图标注

自v2.9.0版本起,SDK给BMKMapView提供了控制底图标注的showMapPoi方法,默认显示底图标注。利用此方法可得到仅显示道路信息的地图。

将底图标注设置为隐藏,方法如下:

//设置隐藏地图标注
 
[_mapView setShowMapPoi:NO];

运行后,底图标注被隐藏,效果如图:


nopoi.png

几何图形

百度地图SDK支持的几何图形有:折线、弧线、多边形和圆,折线、弧线及其他几何图形的边框自v2.6.0版本起支持使用虚线或者纹理图片进行绘制(具体使用方法请参考官方Demo,覆盖物章节的介绍)。开发者可利用相应的接口,在地图上快速绘制这些图形,满足相应的业务需求。

折线

在地图上添加折线的方法如下:

第一步,修改您的ViewController.h文件,添加以下代码,使您的ViewController实现BMKMapViewDelegate协议:

@interface OverlayDemoViewController : UIViewController <BMKMapViewDelegate>{  
    IBOutlet BMKMapView* _mapView;  
}  
@end

第二步,修改您的ViewController.m文件,实现BMKMapViewDelegate的mapView:viewForOverlay:函数,并在viewDidLoad添加折线数据对象:

- (void)viewDidLoad {     
    [super viewDidLoad];    
    // 添加折线覆盖物    
    CLLocationCoordinate2D coors[2] = {0}; 
    coors[0].latitude = 39.315; 
    coors[0].longitude = 116.304;
    coors[1].latitude = 39.515; 
    coors[1].longitude = 116.504;
    BMKPolyline* polyline = [BMKPolyline polylineWithCoordinates:coors count:2];
    [_mapView addOverlay:polyline];    
}    
// Override    
- (BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id <BMKOverlay>)overlay{    
   if ([overlay isKindOfClass:[BMKPolyline class]]){    
        BMKPolylineView* polylineView = [[[BMKPolylineView alloc] initWithOverlay:overlay] autorelease];    
        polylineView.strokeColor = [[UIColor purpleColor] colorWithAlphaComponent:1];
        polylineView.lineWidth = 5.0;
 
        return polylineView;    
   }    
   return nil;    
}

第三步,运行结果:

sdkios-5.png

iOS地图SDK自v2.8.0版本起,新增了折线多段颜色绘制能力,实现的核心代码如下:

第一步,BMKMapView对象,添加分段纹理绘制折线覆盖物,核心代码如下:

//构建顶点数组
CLLocationCoordinate2Dcoords[5] = {0};
coords[0].latitude = 39.965;
coords[0].longitude = 116.404;
coords[1].latitude = 39.925;
coords[1].longitude = 116.454;
coords[2].latitude = 39.955;
coords[2].longitude = 116.494;
coords[3].latitude = 39.905;
coords[3].longitude = 116.654;
coords[4].latitude = 39.965;
coords[4].longitude = 116.704;
//构建分段纹理索引数组
NSArray *textureIndex = [NSArrayarrayWithObjects:
                              [NSNumbernumberWithInt:0],
                              [NSNumbernumberWithInt:1],
                              [NSNumbernumberWithInt:2],
                              [NSNumbernumberWithInt:1], nil];
 
//构建BMKPolyline,使用分段纹理
BMKPolyline* polyLine = [BMKPolylinepolylineWithCoordinates:coordscount:5textureIndex:textureIndex];
//添加分段纹理绘制折线覆盖物
    [_mapViewaddOverlay:polyLine];

第二步,实现BMKMapViewDelegate的mapView:viewForOverlay:回调,核心代码如下:

- (BMKOverlayView*)mapView:(BMKMapView *)map viewForOverlay:(id<BMKOverlay>)overlay
{
if ([overlay isKindOfClass:[BMKPolylineclass]]) {
BMKPolylineView* polylineView = [[BMKPolylineViewalloc] initWithOverlay:overlay];
polylineView.lineWidth = 5;
polylineView.isFocus = YES;// 是否分段纹理绘制(突出显示),默认YES
//加载分段纹理图片,必须否则不能进行分段纹理绘制
        [polylineView loadStrokeTextureImages:
         [NSArrayarrayWithObjects:[UIImageimageNamed:@"road_blue_arrow.png"],
          [UIImageimageNamed:@"road_green_arrow.png"],
          [UIImageimageNamed:@"road_red_arrow.png"],nil]];
returnpolylineView;
    }
returnnil;
}

第三步,运行结果:

1_%E5%89%AF%E6%9C%AC.png


自v2.9.0版本起,新增了折线分段颜色绘制能力

实现的核心代码如下:

第一步,添加折线分段颜色绘制覆盖物,核心代码如下:

CLLocationCoordinate2D coords[5] = {0};
    coords[0].latitude = 39.965;
    coords[0].longitude = 116.404;
    coords[1].latitude = 39.925;
    coords[1].longitude = 116.454;
    coords[2].latitude = 39.955;
    coords[2].longitude = 116.494;
    coords[3].latitude = 39.905;
    coords[3].longitude = 116.554;
    coords[4].latitude = 39.965;
    coords[4].longitude = 116.604;
    //构建分段颜色索引数组
    NSArray *colorIndexs = [NSArray arrayWithObjects:
                            [NSNumber numberWithInt:2],
                            [NSNumber numberWithInt:0],
                            [NSNumber numberWithInt:1],
                            [NSNumber numberWithInt:2], nil];
 
    //构建BMKPolyline,使用分段颜色索引,其对应的BMKPolylineView必须设置colors属性
   BMKPolyline *colorfulPolyline = [BMKPolyline polylineWithCoordinates:coords count:5 textureIndex:colorIndexs];
[_mapView addOverlay:colorfulPolyline];

第二步,实现BMKMapViewDelegate回调,核心代码如下:

//根据overlay生成对应的View
- (BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id <BMKOverlay>)overlay
{
    if ([overlay isKindOfClass:[BMKPolyline class]]) {
        BMKPolylineView* polylineView = [[BMKPolylineView alloc] initWithOverlay:overlay];
        polylineView.lineWidth = 5;
        /// 使用分段颜色绘制时,必须设置(内容必须为UIColor)
        polylineView.colors = [NSArray arrayWithObjects:[UIColor greenColor], [UIColor redColor], [UIColor yellowColor], nil];
        return polylineView;
    }
 
    return nil;
}

第三步,运行结果:

zhexian.png

弧线

百度地图iOS SDK自v2.1.1本起,新增了绘制弧线的方法。用户可以根据三个有序点唯一确定一条弧线,满足您的业务需求。首先,修改您的.m文件,实现BMKMapViewDelegate的_mapView:viewForOverlay:函数,并在viewDidLoad添加弧线数据对象,核心代码如下

    - (void)viewDidLoad {  
        [super viewDidLoad];  
    //添加弧线覆盖物  
    //传入的坐标顺序为起点、途经点、终点  
    CLLocationCoordinate2D coords[3] = {0};
    coords[0].latitude = 39.9374;
    coords[0].longitude = 116.350; 
    coords[1].latitude = 39.9170;
    coords[1].longitude = 116.360; 
    coords[2].latitude = 39.9479;
    coords[2].longitude = 116.373;
 
    BMKArcline *arcline = [BMKArcline arclineWithCoordinates:coords];  
       [_mapView addOverlay:arcline];  
 
    }  
    //根据overlay生成对应的View  
    - (BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id<bmkoverlay>)overlay  
    {  
    if ([overlay isKindOfClass:[BMKArcline class]])  
        {  
            BMKArclineView* arclineView = [[[BMKArclineView alloc] initWithOverlay:overlay] autorelease];  
            arclineView.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.5]; 
            arclineView.lineWidth = 5.0;
 
            return arclineView;  
            }  
        return nil;  
    }

运行后,效果如图:

iosdev16.png

多边形

修改ViewController.h文件,使其实现BMKMapViewDelegate;同时修改ViewController.m文件,实现BMKMapViewDelegate的_mapView:viewForOverlay:函数,并在viewDidLoad添加多边形数据对象。核心代码如下:

- (void)viewDidLoad {     
    [super viewDidLoad];     
    // 添加多边形覆盖物    
    CLLocationCoordinate2D coords[3] = {0};
    coords[0].latitude = 39;
    coords[0].longitude = 116;
    coords[1].latitude = 38;
    coords[1].longitude = 115;
    coords[2].latitude = 38; 
    coords[2].longitude = 117; 
    BMKPolygon* polygon = [BMKPolygon polygonWithCoordinates:coords count:3];
 
    [_mapView addOverlay:polygon];    
}    
// Override    
- (BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id <BMKOverlay>)overlay{  
    if ([overlay isKindOfClass:[BMKPolygon class]]){    
        BMKPolygonView* polygonView = [[[BMKPolygonView alloc] initWithOverlay:overlay] autorelease];    
        polygonView.strokeColor = [[UIColor purpleColor] colorWithAlphaComponent:1];
        polygonView.fillColor = [[UIColor cyanColor] colorWithAlphaComponent:0.2]; 
        polygonView.lineWidth = 5.0;
 
        return polygonView;    
    }    
    return nil;  
}

运行后的显示效果如下图所示:

sdkios-6.png

与多边形实现的方式类似,首先要修改ViewController.h文件,实现BMKMapViewDelegate协议;然后修改ViewController.m文件,实现BMKMapViewDelegate的_mapView:viewForOverlay:函数,并在viewDidLoad添加圆数据对象。核心代码如下:

- (void)viewDidLoad {     
    [super viewDidLoad];    
    // 添加圆形覆盖物    
    CLLocationCoordinate2D coor; 
    coor.latitude = 39.915; 
    coor.longitude = 116.404;
    BMKCircle* circle = [BMKCircle circleWithCenterCoordinate:coor radius:5000];
 
    [_mapView addOverlay:circle];    
}    
// Override    
- (BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id <BMKOverlay>)overlay{    
    if ([overlay isKindOfClass:[BMKCircle class]]){    
        BMKCircleView* circleView = [[[BMKCircleView alloc] initWithOverlay:overlay] autorelease];    
        circleView.fillColor = [[UIColor cyanColor] colorWithAlphaComponent:0.5]; 
        circleView.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.5];
        circleView.lineWidth = 10.0;
 
        return circleView;    
    }    
    return nil;   
}

运行效果如下图所示:

Circle.PNG

地形图图层

自V2.1.0开始,新增图片图层,开发者可在地图的指定位置上添加图片。该图片可随地图的平移、缩放、旋转等操作做相应的变换。图片图层是一种特殊的Overlay, 它位于底图和底图标注层之间(即图片图层不会遮挡地图标注信息), 此外,图片图层的添加顺序不会影响其他图层(例如:POI搜索图层、我的位置图层等)的叠加关系。

图片图层对象初始化的方法有两种:(1)根据指定经纬度坐标生成 (2)根据指定区域生成。下面举例分步说明添加图片图层的步骤:

第一步,修改您的ViewController.h文件,添加以下代码,使您的ViewController实现BMKMapViewDelegate协议:

@interface AnnotationDemoViewController : UIViewController<BMKMapViewDelegate>{  
         IBOutlet BMKMapView* _mapView;  
   }  
end

第二步,修改您的ViewController.m文件,在viewDidLoad添加图片图层对象:

- (void)viewDidLoad {  
        [super viewDidLoad];  
        //添加图片图层覆盖物(第一种:根据指定经纬度坐标生成)  
        CLLocationCoordinate2D coors; 
        coors.latitude = 39.800;
        coors.longitude = 116.404;
        BMKGroundOverlay* ground = [BMKGroundOverlay groundOverlayWithPosition:coors
        zoomLevel:11 anchor:CGPointMake(0.0f,0.0f)
        icon:[UIImage imageWithName:@"test.png"]];
        [_mapView addOverlay:ground];
 
        //添加图片图层覆盖物(第二种:根据指定区域生成) 
        CLLocationCoordinate2Dcoords[2] = {0};
        coords[0].latitude = 39.815;
        coords[0].longitude = 116.404;
        coords[1].latitude = 39.915;
        coords[1].longitude = 116.504;
        BMKCoordinateBounds bound;
        bound.southWest = coords[0];
        bound.northEast = coords[1];
        BMKGroundOverlay* ground2 = [BMKGroundOverlay groundOverlayWithBounds: bound
        icon:[UIImage imageWithName:@"test.png"]];
        [_mapView addOverlay:ground2]; 
 
}

第三步,修改您的ViewController.m文件,实现BMKMapViewDelegate的_mapView:viewForOverlay:函数:

- (BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id<BMKOverlay>)overlay{  
        if ([overlay isKindOfClass:[BMKGroundOverlay class]]){  
            BMKGroundOverlayView* groundView = [[[BMKGroundOverlayView alloc] initWithOverlay:overlay] autorelease];  
            return groundView;  
        }  
        return nil;  
}

运行效果如下图所示:

sdkios7.png

热力图功能

热力图是用不同颜色的区块叠加在地图上描述人群分布、密度和变化趋势的一个产品,百度地图SDK将绘制热力图的能力为广大开发者开放,帮助开发者利用自有数据,构建属于自己的热力图,提供丰富的展示效果。

注意:此处的“热力图功能”不同于“百度城市热力图”。百度城市热力图通过简单的接口调用,开发者可展示百度数据的热力图层。而此处的热力图功能,需要开发者传入自己的位置数据,然后SDK会根据热力图绘制规则为开发者做本地的热力图渲染绘制。

利用热力图功能构建自有数据热力图的方式如下:

//添加热力图
-(void)addHeatMap{
//创建热力图数据类
BMKHeatMap* heatMap = [[BMKHeatMapalloc]init];
//创建渐变色类
UIColor* color1 = [UIColorblueColor];
UIColor* color2 = [UIColoryellowColor];
UIColor* color3 = [UIColorredColor];
NSArray*colorInitialArray = [[NSArrayalloc]initWithObjects:color1,color2,color3, nil];
BMKGradient* gradient = [[BMKGradientalloc]initWithColors:colorInitialArraystartPoints:@[@"0.08f", @"0.4f", @"1f"]];
    [colorInitialArrayrelease];
//如果用户自定义了渐变色则按自定义的渐变色进行绘制否则按默认渐变色进行绘制
heatMap.mGradient = gradient;
 
//创建热力图数据数组
NSMutableArray* data = [NSMutableArrayarray];
int num = 1000;
for(int i = 0; i<num; i++)
{
    //创建BMKHeatMapNode
    BMKHeatMapNode* heapmapnode_test = [[BMKHeatMapNodealloc]init];
    //此处示例为随机生成的坐标点序列,开发者使用自有数据即可
    CLLocationCoordinate2D coor;
    float random = (arc4random()%1000)*0.001;
    float random2 = (arc4random()%1000)*0.003;
    float random3 = (arc4random()%1000)*0.015;
    float random4 = (arc4random()%1000)*0.016;
    if(i%2==0){
        coor.latitude = 39.915+random;
        coor.longitude = 116.403+random2;
    }else{
        coor.latitude = 39.915-random3;
        coor.longitude = 116.403-random4;
    }
    heapmapnode_test.pt = coor;
//随机生成点强度
heapmapnode_test.intensity = arc4random()*900;
//添加BMKHeatMapNode到数组
        [data addObject:heapmapnode_test];
        [heapmapnode_test release];
    }
//将点数据赋值到热力图数据类
heatMap.mData = data;
//调用mapView中的方法根据热力图数据添加热力图
    [_mapView addHeatMap:heatMap];
 
}
//删除热力图
-(void)removeHeatMap{
    [_mapView removeHeatMap];
}

自定义覆盖物

从2.0.0开始,地图渲染采用OpenGL方式实现,因此覆盖物基类BMKOverlayView新增glRender接口,以及绘制基本线renderLinesWithPoints、面renderRegionWithPoints的接口来实现对覆盖物的OpenGL渲染。绘制自定义overlay时,继承BMKOverlayView的子类需实现glRender接口,在glRender中通过调用renderLinesWithPoints、renderRegionWithPoints来组合自己想要实现的图形。

CustomOverlayView继承BMKOverlayPathView,在CustomOverlayView中实现glRender。核心代码如下所示:

- (void)glRender  {     
    //自定义overlay绘制    
    CustomOverlay *customOverlay = [self customOverlay];    
    if (customOverlay.pointCount >= 3) {    
       [self renderRegionWithPoints:customOverlay.points pointCount:customOverlay.pointCount fillColor:self.fillColor usingTriangleFan:YES];//绘制多边形    
    }else    
    {    
        [self renderLinesWithPoints:customOverlay.points pointCount:customOverlay.pointCount strokeColor:self.strokeColor lineWidth:self.lineWidth looped:NO];//绘制线    
    }    
}

如果不实现glRender,则需实现drawMapRect默认使用系统GDI绘制,GDI绘制方式在overlayView尺寸较大时可能有效率问题,因此建议使用glRender来实现自定义overlay绘制。

针对已添加的自定义覆盖物,您可以通过一下方式进行删除操作:

if (overlay != nil) {    
    [_mapView removeOverlay:overlay];    
}

OpenGL绘制功能

自v2.6.0起,iOS地图SDK为广大开发者开放了OpenGL绘制功能,开发者可利用OpenGL的绘制来实现更多复杂的覆盖物绘制。

v2.6.0新增BMKMapViewDelegate中新增-mapView:onDrawMapFrame:,地图渲染每一帧画面过程中,以及每次需要重绘地图时(例如添加覆盖物)都会调用此接口。开发者可以在这个接口中进行opengl的绘制。不需要用户自己创建context和buffer,步骤如下(具体代码请参考BaiduMap_IOSSDK_SampleOpenGL绘制功能 部分):

1、转换坐标(坐标系原点为地图中心点);

2、根据地图的状态,设置旋转和缩放比例;

3、绘制

瓦片图层

iOS地图SDK自v2.9.0起,新增瓦片图层(tileOverlay), 该图层支持开发者添加自有瓦片数据,包括本地加载和在线下载两种方式。

该图层可随地图的平移、缩放、旋转等操作做相应的变换,它仅位于底图之上(即瓦片图层将会遮挡底图,不遮挡其他图层),瓦片图层的添加顺序不会影响其他图层(例如:POI搜索图层、我的位置图层等)的叠加关系,适用于开发者拥有某一区域的地图,并希望使用此区域地图覆盖相应位置的百度地图。


一、瓦片划分规则:

百度地图SDK会根据不同的比例尺将地图划分成若干个瓦片,并且以中心点经纬度(0,0)开始计算瓦片,当地图显示缩放级别增大时,每一个瓦片被划分成4 个瓦片。如:

地图级别为0时,只有1张瓦片

地图级别为1时,会分成 1 * 4 = 4 张瓦片

依次类推,

地图级别为n时,总共划分的瓦片为:4的n次方

为了保证瓦片的显示效果,第n级的瓦片显示的地图level范围为[n - 0.5, n + 0.5)


二、瓦片图层分为本地加载和在线下载两种绘制方式。

1. 本地加载,将图片打包于应用内,适用于图片较小且不需要频繁变更,通过继承BMKSyncTileLayer实现,具体请参考demo,效果如下:

tileioverlay-offline.PNG


2. 在线下载,将图片存放于开发者提供的服务中,提供给SDK一个URL模板,适用于图片需要随时变更,下面举例说明添加在线瓦片图层的步骤:

1.根据URL模版(即指向相关图层图片的URL)创建BMKURLTileLayer对象。

BMKURLTileLayer *urlTileLayer = [[BMKURLTileLayer alloc] initWithURLTemplate:@"http://api0.map.bdimg.com/customimage/tile?&x={x}&y={y}&z={z}&udt=20150601&customid=light"];

2.设置BMKURLTileLayer的可见最大/最小Zoom值。

urlTileLayer.maxZoom = 18;
urlTileLayer.minZoom = 16;

3.设定BMKURLTileLayer的可渲染区域。

urlTileLayer.visibleMapRect = BMKMapRectMake(32994258, 35853667, 3122, 5541);

4.将BMKURLTileLayer对象添加到BMKMapView中

[_mapView addOverlay:urlTileLayer];

5. 实现BMKMapViewDelegate回调,核心代码如下

- (BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id <BMKOverlay>)overlay {
    if ([overlay isKindOfClass:[BMKTileLayer class]]) {
        BMKTileLayerView *view = [[BMKTileLayerView alloc] initWithTileLayer:overlay];
        return view;
    }
    return nil;
}

6. 运行效果如下:

xianshangtupian.png

设置地图区域边界

v2.10.0起,新增了mapPadding方法,支持设置地图区域边界,在被定义边距范围内,对显示和操作地图,做了如下两方面的定义。

(1)百度logo、比例尺、指南针等,可被控制在自定义的地图区域边界内。

(2)自适应MapStatus中心点坐标,由原屏幕中心点调整至设置的区域中心点。

当设计的UI与地图部分重叠时,可以设置地图的操作和显示范围,以防止UI遮挡和重叠

给地图设置边界,设置方法如下:

 
// paddingLeft、 paddingTop、 paddingRight、 paddingBottom  
// 表示距离屏幕左、上、右、下边距离,单位为屏幕坐标下的像素密度
 
_mapView.mapPadding = UIEdgeInsetsMake(0, 0, 28, 0);

设置地图显示范围

v2.10.0起新增了设置地图显示范围,手机屏幕仅显示设定的地图范围,当前不支持旋转地图的情况,请与"禁用旋转手势"配合使用。

使用场景:针对需要展示部分固定范围的地图,如希望设置仅显示北京市区地图,可使用此功能。

使用方法如下:

CLLocationCoordinate2D center = CLLocationCoordinate2DMake(39.924257, 116.403263);
BMKCoordinateSpan span = BMKCoordinateSpanMake(0.038325, 0.028045);
_mapView.limitMapRegion = BMKCoordinateRegionMake(center, span);////限制地图显示范围
_mapView.rotateEnabled = NO;//禁用旋转手势