Overlay 称为多点覆盖物,它包括:折线、多边形(凹和凸)、圆、大地曲线、图片覆盖物以及自定义覆盖物这5种类型。同样也是采用数据与View分离的原则,其中:
在地图上添加一个 Overlay 的步骤如下:
折线类为 MAPolyline,由一组经纬度坐标组成,并以有序序列形式建立一系列的线段。iOS SDK支持在3D矢量地图上绘制带箭头或有纹理等样式的折线,同时可设置折线端点和连接点的类型,以满足各种绘制线的场景。
在地图添加折线的步骤如下:
示例代码:
#import "ViewController.h"
#import
@interface ViewController ()<MAMapViewDelegate>
{
MAMapView *_mapView;// 地图视图
}
@end
@implementation ViewController
-(void) viewDidLoad {
//构造折线数据对象
CLLocationCoordinate2D commonPolylineCoords[4];
commonPolylineCoords[0].latitude = 39.832136;
commonPolylineCoords[0].longitude = 116.34095;
commonPolylineCoords[1].latitude = 39.832136;
commonPolylineCoords[1].longitude = 116.42095;
commonPolylineCoords[2].latitude = 39.902136;
commonPolylineCoords[2].longitude = 116.42095;
commonPolylineCoords[3].latitude = 39.902136;
commonPolylineCoords[3].longitude = 116.44095;
//构造折线对象
MAPolyline *commonPolyline = [MAPolyline polylineWithCoordinates:commonPolylineCoords count:4];
//在地图上添加折线对象
[_mapView addOverlay: commonPolyline];
}
// 添加覆盖物视图
- (MAOverlayView *)mapView:(MAMapView *)mapView viewForOverlay:(id )overlay {
if ([overlay isKindOfClass:[MAPolyline class]])
{
// 初始化折线视图
MAPolylineView *polylineView = [[MAPolylineView alloc] initWithPolyline:overlay];
// 设置折线视图属性
polylineView.lineWidth = 10.f;
polylineView.strokeColor = [UIColor colorWithRed:0 green:0 blue:1 alpha:0.6];
polylineView.lineJoin = kCGLineJoinRound;//连接类型
polylineView.lineCap = kCGLineCapRound;//端点类型
return polylineView;
}
return nil;
}
@end
在上面的回调函数中,调用 MAPolylineView 的 loadStrokeTextureImage 方法可以设置折线的纹理图片(仅3D矢量地图支持)。
注意:纹理图片必须是正方形,宽高是2的整数幂,如64*64,否则无效;若设置了纹理图片,设置线颜色、连接类型和端点类型将无效,目前仅支持设置折线纹理。
设置纹理图片的代码如下:
[polylineView loadStrokeTextureImage:[UIImage imageNamed:@"arrowTexture"]];
多边形类为MAPolygon,与MAPolyline类似,包括有序序列的一系列坐标,但是多边形包含有内部区域。在地图添加多边形的步骤如下:
示例代码:
-(void) loadRect {
//构造多边形数据对象
CLLocationCoordinate2D coordinates[4];
coordinates[0].latitude = 39.810892;
coordinates[0].longitude = 116.233413;
coordinates[1].latitude = 39.816600;
coordinates[1].longitude = 116.331842;
coordinates[2].latitude = 39.762187;
coordinates[2].longitude = 116.357932;
coordinates[3].latitude = 39.733653;
coordinates[3].longitude = 116.278255;
MAPolygon *polygon = [MAPolygon polygonWithCoordinates:coordinates count:4];
//在地图上添加多边形对象
[_mapView addOverlay: polygon];
}
- (MAOverlayView *)mapView:(MAMapView *)mapView viewForOverlay:(id )overlay {
if ([overlay isKindOfClass:[MAPolygon class]])
{
MAPolygonView *polygonView = [[MAPolygonView alloc] initWithPolygon:overlay];
polygonView.lineWidth = 5.f;
polygonView.strokeColor = [UIColor colorWithRed:0.6 green:0.6 blue:0.6 alpha:0.8];
polygonView.fillColor = [UIColor colorWithRed:0.77 green:0.88 blue:0.94 alpha:0.8];
polygonView.lineJoin = kCGLineJoinRound;//连接类型
return polygonView;
}
return nil;
}
圆类为MACircle,圆对象由中心点(经纬度)和半径(米)构成。
在地图绘制圆的步骤如下:
示例代码:
-(void) loadCircle{
//构造圆
MACircle *circle = [MACircle circleWithCenterCoordinate:CLLocationCoordinate2DMake(39.952136, 116.50095) radius:5000];
//在地图上添加圆
[_mapView addOverlay: circle];
}
- (MAOverlayView *)mapView:(MAMapView *)mapView viewForOverlay:(id )overlay {
if ([overlay isKindOfClass:[MACircle class]])
{
MACircleView *circleView = [[MACircleView alloc] initWithCircle:overlay];
circleView.lineWidth = 5.f;
circleView.strokeColor = [UIColor colorWithRed:0.6 green:0.6 blue:0.6 alpha:0.8];
circleView.fillColor = [UIColor colorWithRed:1.0 green:0.8 blue:0.0 alpha:0.8];
return circleView;
}
return nil;
}
大地曲线类为MAGeodesicPolyline,继承自MAPolyline。在地图添加大地曲线的步骤如下:
示例代码:
- (void) loadGeodesicPolyline {
CLLocationCoordinate2D geodesicCoords[2];
geodesicCoords[0].latitude = 39.905151;
geodesicCoords[0].longitude = 116.401726;
geodesicCoords[1].latitude = 38.905151;
geodesicCoords[1].longitude = 70.401726;
//构造大地曲线对象
MAGeodesicPolyline *geodesicPolyline = [MAGeodesicPolyline polylineWithCoordinates:geodesicCoords count:2];
[_mapView addOverlay:geodesicPolyline];
}
- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id )overlay
{
if ([overlay isKindOfClass:[MAGeodesicPolyline class]])
{
MAPolylineRenderer *polylineRenderer = [[MAPolylineRenderer alloc] initWithPolyline:overlay];
polylineRenderer.lineWidth = 4.f;
polylineRenderer.strokeColor = [UIColor colorWithRed:0 green:0 blue:1 alpha:1];
return polylineRenderer;
}
return nil;
}
图片覆盖物类为MAGroundOverlay,可完成将一张图片以合适的大小贴在地图指定的位置上的功能。
添加图片覆盖物的步骤如下:
代码示例:
- (void)loadGroundOverlay {
MACoordinateBounds coordinateBounds = MACoordinateBoundsMake(CLLocationCoordinate2DMake(39.939577, 116.388331),CLLocationCoordinate2DMake(39.935029, 116.384377));
MAGroundOverlay *groundOverlay = [MAGroundOverlay groundOverlayWithBounds:coordinateBounds icon:[UIImage imageNamed:@"category_3"]];
[_mapView addOverlay:groundOverlay];
_mapView.visibleMapRect = groundOverlay.boundingMapRect;
}
- (MAOverlayView *)mapView:(MAMapView *)mapView viewForOverlay:(id )overlay
{
if ([overlay isKindOfClass:[MAGroundOverlay class]])
{
MAGroundOverlayView *groundOverlayView = [[MAGroundOverlayView alloc] initWithGroundOverlay:overlay];
return groundOverlayView;
}
return nil;
}
通过自定义图层可对基础底层地图添加额外的特性,如:某个商场的室内信息、某个景区的详情等等。自定义图层类是MATileOverlay,它定义了能添加到基础底层地图的图片集合。
添加自定义图层的前提是使用球面墨卡托投影生成了相应的瓦片,并按照生成的格式部署在服务器上。在地图上显示自定义图层的步骤如下:
示例代码:
#define TileOverlayViewControllerCoordinate CLLocationCoordinate2DMake(39.910695, 116.372830)
- (void)loadTileOverlay {
_mapView.centerCoordinate = TileOverlayViewControllerCoordinate;
_mapView.zoomLevel = 19;
[_mapView addOverlay:[self constructTileOverlayWithFloor:2]];
}
- (MATileOverlay *)constructTileOverlayWithFloor:(NSInteger)floor {
/* 构建tileOverlay的URL模版. */
NSString *URLTemplate = [NSString stringWithFormat: @"http://sdkdemo.amap.com:8080/tileserver/Tile?x={x}&y={y}&z={z}&f=%ld", (long)floor];
MATileOverlay *tileOverlay = [[MATileOverlay alloc] initWithURLTemplate:URLTemplate];
tileOverlay.minimumZ = 18; //设置可见最小Zoom值
tileOverlay.maximumZ = 20; //设置可见最大Zoom值
tileOverlay.boundingMapRect = MAMapRectForCoordinateRegion(MACoordinateRegionMakeWithDistance(TileOverlayViewControllerCoordinate, 200, 200)); //设置可渲染区域
return tileOverlay;
}
- (MAOverlayView *)mapView:(MAMapView *)mapView viewForOverlay:(id )overlay {
if ([overlay isKindOfClass:[MATileOverlay class]]) {
MATileOverlayView *tileOverlayView = [[MATileOverlayView alloc] initWithTileOverlay:overlay];
return tileOverlayView;
}
return nil;
}
热力图图层是以颜色变化展现分布情况的图层。高德地图iOS SDK自V2.6.0版本提供了热力图图层的绘制功能,开发者可利用自有数据(入学热力图、人流热力图等等),创建可用于指导您决策的热力图。在地图上添加热力图的步骤如下:
示例代码:
- (void)loadHeatMapTileOverlay {
//构造热力图图层对象
MAHeatMapTileOverlay *heatMapTileOverlay = [[MAHeatMapTileOverlay alloc] init];
//构造热力图数据,从locations.json中读取经纬度
NSMutableArray* data = [NSMutableArray array];
NSData *jsdata = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"heatMapData" ofType:@"json"]];
if (jsdata)
{
NSArray *dicArray = [NSJSONSerialization JSONObjectWithData:jsdata options:NSJSONReadingAllowFragments error:nil];
for (NSDictionary *dic in dicArray)
{
MAHeatMapNode *node = [[MAHeatMapNode alloc] init];
CLLocationCoordinate2D coordinate;
coordinate.latitude = [dic[@"lat"] doubleValue];
coordinate.longitude = [dic[@"lng"] doubleValue];
node.coordinate = coordinate;
node.intensity = 1;//设置权重
[data addObject:node];
}
}
heatMapTileOverlay.data = data;
//构造渐变色对象
MAHeatMapGradient *gradient = [[MAHeatMapGradient alloc] initWithColor:@[[UIColor blueColor],[UIColor greenColor], [UIColor redColor]] andWithStartPoints:@[@(0.2),@(0.5),@(0.9)]];
heatMapTileOverlay.gradient = gradient;
//将热力图添加到地图上
[_mapView addOverlay: heatMapTileOverlay];
}
- (MAOverlayView *)mapView:(MAMapView *)mapView viewForOverlay:(id )overlay
{
if ([overlay isKindOfClass:[MATileOverlay class]])
{
MATileOverlayView *tileOverlayView = [[MATileOverlayView alloc] initWithTileOverlay:overlay];
return tileOverlayView;
}
return nil;
}
地图控件可帮您直观的了解当前的地图的状态,iOS SDK提供“地图Logo”、“指南针”和“比例尺”三种地图控件。
iOS SDK默认的Logo为“高德地图”字样,显示在地图的左下方。地图Logo不能移除,但可通过MAMapView.logoCenter属性来调整Logo的显示位置。
指南针默认是开启状态,显示在地图的右上角。通过MAMapView的showsCompass属性用来控制指南针的可见性。compassOrigin属性可改变指南针的显示位置。
2.3 比例尺
比例尺表示地图上两点间距离与实际与之对应的两点距离的比,在不同的缩放级别下,比例尺代表的长度也是不同的。在iOS SDK中,比例尺默认显示在地图的左上角。MAMapView的showScale属性用来控制比例尺的可见性,scaleOrigin属性用来改变比例尺的显示位置。
示例代码:
#import "ViewController.h"
#import
@interface ViewController ()<MAMapViewDelegate>
{
MAMapView *_mapView;// 地图视图
}
@end
@implementation ViewController
-(void) viewDidLoad {
// 初始化地图
_mapView = [[MAMapView alloc] initWithFrame:self.view.bounds];
_mapView.delegate = self;
[self.view addSubview:_mapView];
// 设置logo位置
_mapView.logoCenter = CGPointMake(self.view.frame.size.width -100, self.view.frame.size.height -100);
// 指南针
_mapView.showsCompass= YES; // 设置成NO表示关闭指南针;YES表示显示指南针
_mapView.compassOrigin= CGPointMake(_mapView.compassOrigin.x, 100); //设置指南针位置
// 比例尺
_mapView.showsScale= YES; //设置成NO表示不显示比例尺;YES表示显示比例尺
_mapView.scaleOrigin= CGPointMake(_mapView.scaleOrigin.x, 100); //设置比例尺位置
}
@end
iOS SDK支持丰富的地图交互手势功能,通过代码也可以实现对应的手势功能。手势功能默认都是开启的,可通过代码将其禁用。
缩放手势可改变地图的缩放级别,地图响应的手势如下:
通过MAMapView的scrollEnabled属性可以禁用或启用缩放手势。禁用缩放手势不会影响用户使用地图上的缩放控制按钮。地图的缩放级别的范围是[3-19],调用MAMapView的setZoomLevel方法设置地图的缩放级别,用来缩放地图。
用户可以用手指拖动地图四处滚动(平移)或用手指滑动地图(动画效果)。通过 MAMapView的scrollEnabled属性可以禁用或开启平移(滑动)手势。地图平移时,缩放级别不变,可通过改变地图的中心点来移动地图,
用户可以用两个手指在地图上转动,可以旋转3D矢量地图。通过调用类MAMapView的rotateEnabled属性禁用或开启旋转手势。旋转角度的范围是[0.f 360.f],以逆时针为正向。调用MAMapView的setRotationDegree方法设置地图的旋转角度。
用户可以在地图上放置两个手指,移动它们一起向下或向上去增加或减小倾斜角。通过MAMapView的rotateCameraEnabled属性禁用或启用倾斜手势。倾斜角度范围为[0.f, 45.f],调用MAMapView的setCameraDegree方法设置地图的倾斜角度。
iOS SDK支持对选定的屏幕地图区域(CGRect)进行截屏,截取的内容包括:地图、地图覆盖物、弹出气泡。使用 MAMapView 中的 takeSnapshotInRect 方法进行截屏,该方法返回UIImage对象。
注意:地图截屏功能依赖于地图显示,即:只有内容先显示在地图上,才能进行截屏。
该功能为用户提供了WIFI方式下载离线地图数据,离线地图数据以 MAOfflineItem 为单位进行下载。离线数据项 MAOfflineItem 包含城市编码、城市名称、数据状态等离线地图数据包的基本信息,是离线数据省信息(MAOfflineProvince)和离线数据城市信息(MAOfflineCity)的基类。
离线数据城市信息(MAOfflineCity)又派生出三个子类,
示例代码:
- (void)setupCities {
self.sectionTitles = @[@"全国", @"直辖市", @"省份"];
self.cities = [MAOfflineMap sharedOfflineMap].cities;//普通城市和直辖市
self.provinces = [MAOfflineMap sharedOfflineMap].provinces;//省
self.municipalities = [MAOfflineMap sharedOfflineMap].municipalities;//直辖市
}
- (MAOfflineItem *)itemForIndexPath:(NSIndexPath *)indexPath {
MAOfflineItem *item = nil;
switch (indexPath.section) {
case 0:{
item = [MAOfflineMap sharedOfflineMap].nationWide;//全国概要图
break;
} case 1:{
item = self.municipalities[indexPath.row];//直辖市
break;
} case 2:{
item = nil;
break;
} default:{
MAOfflineProvince *pro = self.provinces[indexPath.section - self.sectionTitles.count];
if (indexPath.row == 0) {
item = pro; //整个省
} else {
item = pro.cities[indexPath.row - 1]; //市
}
break;
}
}
return item;
}
示例代码:
- (void)download:(MAOfflineItem *)item
{
if (item == nil || item.itemStatus == MAOfflineItemStatusInstalled)
{
return;
}
NSLog(@"download :%@", item.name);
[[MAOfflineMap sharedOfflineMap] downloadItem:item shouldContinueWhenAppEntersBackground:YES downloadBlock:^(MAOfflineMapDownloadStatus downloadStatus, id info) {
/* Manipulations to your application’s user interface must occur on the main thread. */
dispatch_async(dispatch_get_main_queue(), ^{
if (downloadStatus == MAOfflineMapDownloadStatusWaiting)
{
NSLog(@"状态为: %@", @"等待下载");
}
else if(downloadStatus == MAOfflineMapDownloadStatusStart)
{
NSLog(@"状态为: %@", @"开始下载");
}
else if(downloadStatus == MAOfflineMapDownloadStatusProgress)
{
NSLog(@"状态为: %@", @"正在下载");
}
else if(downloadStatus == MAOfflineMapDownloadStatusCancelled) {
NSLog(@"状态为: %@", @"取消下载");
}
else if(downloadStatus == MAOfflineMapDownloadStatusCompleted) {
NSLog(@"状态为: %@", @"下载完成");
}
else if(downloadStatus == MAOfflineMapDownloadStatusUnzip) {
NSLog(@"状态为: %@", @"下载完成,正在解压缩");
}
else if(downloadStatus == MAOfflineMapDownloadStatusError) {
NSLog(@"状态为: %@", @"下载错误");
}
else if(downloadStatus == MAOfflineMapDownloadStatusFinished) {
NSLog(@"状态为: %@", @"全部完成");
[self.mapView reloadMap]; //激活离线地图
}
});
}];
}
示例代码:
- (void)pause:(MAOfflineItem *)item {
NSLog(@"pause :%@", item.name);
[[MAOfflineMap sharedOfflineMap] pauseItem:item];
//暂停所有离线地图下载的函数为 :
[[MAOfflineMap sharedOfflineMap] cancelAll];
}
支持商场、火车站、机场等大型室内建筑的室内外一体化地图显示。支持通过楼层控件进行自由切换室内对应楼层,显示室内精细化地图。通过MAMapView类的showsIndoorMap接口设置是否显示室内地图,默认状态为开启:_mapView.showsIndoorMap = YES;
在开启显示室内地图之后,可通过实现代理方法获取室内地图取楼层变化,
示例代码:
/**
* 室内地图信息发生变化的回调
* @param mapView 地图View
* @param indoorBuilding 室内地图信息
*/
- (void)mapview:(MAMapView *)mapView didIndoorBuildingValueChanged:(MAIndoorBuilding *)indoorBuilding
{
MAIndoorBuilding *indoorInfo = indoorBuilding;
NSLog(@"floorName = %@",indoorBuilding.floorName); //楼层名
NSLog(@"floor = %d",indoorBuilding.floor); //楼层数
NSLog(@"buildingName = %@",indoorBuilding.buildingName); //楼块名(中文名)
NSLog(@"poiID = %@",indoorBuilding.poiID); //楼块ID
NSLog(@"numberOfFloor = %d",indoorBuilding.numberOfFloor);//楼层总数
}