开发 iOS 地图SDK 开发指南 在地图上绘制 绘制面

绘制面 最后更新时间: 2021年01月22日

绘制圆

通过 MACircle 类绘制圆,圆是由中心点(经纬度)和半径(米)构成。

在地图绘制圆的步骤如下:

(1) 在ViewController.m的viewDidLoad方法中根据中心点和半径构造圆对象。

    //构造圆
    MACircle *circle = [MACircle circleWithCenterCoordinate:CLLocationCoordinate2DMake(39.952136, 116.50095) radius:5000];
    
    //在地图上添加圆
    [_mapView addOverlay: circle];
let circle: MACircle = MACircle(center: CLLocationCoordinate2D(latitude: 39.996441, longitude: 116.411146), radius: 10000)
 mapView.add(circle)

(2) 继续在ViewController.m文件中,实现<MAMapViewDelegate>协议中的mapView:rendererForOverlay:回调函数,设置圆的样式。示例代码如下:

- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id <maoverlay>)overlay
{
    if ([overlay isKindOfClass:[MACircle class]])
    {
        MACircleRenderer *circleRenderer = [[MACircleRenderer alloc] initWithCircle:overlay];
        
        circleRenderer.lineWidth    = 5.f;
        circleRenderer.strokeColor  = [UIColor colorWithRed:0.6 green:0.6 blue:0.6 alpha:0.8];
        circleRenderer.fillColor    = [UIColor colorWithRed:1.0 green:0.8 blue:0.0 alpha:0.8];
        return circleRenderer;
    }
    return nil;
}
func mapView(_ mapView: MAMapView!, rendererFor overlay: MAOverlay!) -> MAOverlayRenderer! {
		if overlay.isKind(of: MACircle.self) {
            let renderer: MACircleRenderer = MACircleRenderer(overlay: overlay)
            renderer.lineWidth = 8.0
            renderer.strokeColor = UIColor.blue
            renderer.fillColor = UIColor.red.withAlphaComponent(0.4)
            
            return renderer
        }
        return nil
    }

运行程序,效果如下所示:

绘制热力图

热力图是以颜色变化展现分布情况的图层。高德地图iOS SDK自V2.6.0版本提供了热力图图层的绘制功能,您可根据业务数据(人员热度数据、人口流动热度等数据)创建可用于指导您决策的热力图。

在地图上添加热力图的步骤如下:

1.构造MAHeatMapTileOverlay 对象。

2.配置热力图图层的参数。

参数列表

名称

说明

data

数据数组,数组中是 MAHeatMapNode 对象(包含:点坐标和权重值)

radius

半径,默认值为 12ps

opacity

透明度,默认值为 0.6

gradient

渐变色对象

3.将MAHeatMapTileOverlay添加到MAMapView中。

4.实现MAMapViewDelegate的mapView:viewForOverlay:函数,在地图上显示热力图。

我们提前将数据将存放在locations.json文件中(这一步您可以采用远程服务下发的形式)。在地图上添加热力图的示例代码如下:

//构造热力图图层对象
MAHeatMapTileOverlay  *heatMapTileOverlay = [[MAHeatMapTileOverlay alloc] init];

//构造热力图数据,从locations.json中读取经纬度
NSMutableArray* data = [NSMutableArray array];

NSData *jsdata = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"locations" ofType:@"json"]];

@autoreleasepool {
    
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];
func initOverlay() {
        heatMap = MAHeatMapTileOverlay.init()
        
        let data: Data? = try! Data.init(contentsOf: URL.init(fileURLWithPath: Bundle.main.path(forResource: "heatMapData", ofType: "json")!))
        
        if(data != nil) {
            let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments) as! [[String:Any]]
            
            
            var arr:Array<MAHeatMapNode> = Array.init()
            
            for element in jsonObj! {
                let lat = element["lat"]
                let lon = element["lng"]
                
                let node = MAHeatMapNode.init()
                node.coordinate = CLLocationCoordinate2DMake(lat as! CLLocationDegrees, lon as! CLLocationDegrees)
                node.intensity = 1.0
                
                arr.append(node)
            }

            heatMap.data = arr
        }
    }
//构造渐变色对象
self.heatMap.gradient = MAHeatMapGradient.init(color: [UIColor.blue, UIColor.green, UIColor.red], andWithStartPoints: [0.2, 0.5, 0.9])

//将热力图添加到地图上
mapView.add(heatMap)

实现 MAMapViewDelegate 的 mapView:rendererForOverlay: 函数,在热力图显示在地图View上。示例代码如下:

- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id <MAOverlay>)overlay
{
    if ([overlay isKindOfClass:[MATileOverlay class]])
    {
        MATileOverlayRenderer *tileOverlayRenderer = [[MATileOverlayRenderer alloc] initWithTileOverlay:overlay];
        
        return tileOverlayRenderer;
    }
    
    return nil;
}
func mapView(_ mapView: MAMapView!, rendererFor overlay: MAOverlay!) -> MAOverlayRenderer! {
        
        if (overlay.isKind(of: MAHeatMapTileOverlay.self))
        {
            let renderer = MATileOverlayRenderer.init(tileOverlay: overlay as! MATileOverlay!)
            return renderer;
        }
        return nil;
    }

运行效果如下所示:

绘制overlay(自定义图层)

图片覆盖物

图片覆盖物类为 MAGroundOverlay,可完成将一张图片以合适的大小贴在地图指定的位置上的功能。

添加图片覆盖物的步骤如下:

(1) 在ViewController.m的viewDidLoad方法中根据范围和图片构造图片覆盖物。

- (void) viewDidLoad
{
    MACoordinateBounds coordinateBounds = MACoordinateBoundsMake(CLLocationCoordinate2DMake
(39.939577, 116.388331),CLLocationCoordinate2DMake(39.935029, 116.384377));
    
    MAGroundOverlay *groundOverlay = [MAGroundOverlay groundOverlayWithBounds:coordinateBounds icon:[UIImage imageNamed:@"GWF"]];
    
    [_mapView addOverlay:groundOverlay];
    _mapView.visibleMapRect = groundOverlay.boundingMapRect;
}
let coordBounds = MACoordinateBounds.init(northEast: CLLocationCoordinate2DMake(39.939577, 116.388331), southWest: CLLocationCoordinate2DMake(39.935029, 116.384377));
        groundOverlay = MAGroundOverlay.init(bounds: coordBounds, icon: UIImage.init(named: "GWF"))

(2) 实现<MAMapViewDelegate>协议中的mapView:rendererForOverlay:回调函数,以在地图上显示图片覆盖物。

- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id<MAOverlay>)overlay
{
    if ([overlay isKindOfClass:[MAGroundOverlay class]])
    {
        MAGroundOverlayRenderer *groundOverlayRenderer = [[MAGroundOverlayRenderer alloc] initWithGroundOverlay:overlay];
        
        return groundOverlayRenderer;
    }

    return nil;
}
func mapView(_ mapView: MAMapView!, rendererFor overlay: MAOverlay!) -> MAOverlayRenderer! {
        
        if (overlay.isKind(of: MAGroundOverlay.self))
        {
            let renderer = MAGroundOverlayRenderer.init(groundOverlay: overlay as! MAGroundOverlay)
            return renderer;
        }
        return nil;
    }

运行效果如下所示:

绘制瓦片图层

通过瓦片图层可对基础底层地图添加额外的特性,如:某个商场的室内信息、某个景区的详情等等。自定义图层类是MATileOverlay,它定义了能添加到基础底层地图的图片集合。

添加瓦片图层的前提是使用球面墨卡托投影生成了相应的瓦片,并按照生成的格式部署在您的服务器上。在地图上显示自定义图层的步骤如下:

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

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

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

4.将MATileOverlay对象添加到MAMapView中。

我们提前准备了其他地图的瓦片数据,并部署到了测试服务器上。在地图上显示的示例代码如下:

(1) 修改ViewController.m文件,在viewDidLoad方法中构造2层的对应的MATileOverlay对象,并添加到地图上。

#define kTileOverlayRemoteServerTemplate @"http://cache1.arcgisonline.cn/arcgis/rest/services/ChinaCities_Community_BaseMap_ENG/BeiJing_Community_BaseMap_ENG/MapServer/tile/{z}/{y}/{x}"
#define kTileOverlayRemoteMinZ      4
#define kTileOverlayRemoteMaxZ      17

#define kTileOverlayLocalMinZ       11
#define kTileOverlayLocalMaxZ       13

- (MATileOverlay *)constructTileOverlayWithType:(NSInteger)type
{
    MATileOverlay *tileOverlay = nil;
    if (type == 0)
    {
        tileOverlay = [[LocalTileOverlay alloc] init];
        tileOverlay.minimumZ = kTileOverlayLocalMinZ;
        tileOverlay.maximumZ = kTileOverlayLocalMaxZ;
    }
    else // type == 1
    {
        tileOverlay = [[MATileOverlay alloc] initWithURLTemplate:kTileOverlayRemoteServerTemplate];
        
        /* minimumZ 是tileOverlay的可见最小Zoom值. */
        tileOverlay.minimumZ = kTileOverlayRemoteMinZ;
        /* minimumZ 是tileOverlay的可见最大Zoom值. */
        tileOverlay.maximumZ = kTileOverlayRemoteMaxZ;
        
        /* boundingMapRect 是用来 设定tileOverlay的可渲染区域. */
        tileOverlay.boundingMapRect = MAMapRectWorld;
    }
    
    return tileOverlay;
}
func buildOverlay(type:UInt) -> MATileOverlay! {
        var tileOverlay:MATileOverlay!
        if (type == 0)
        {
            tileOverlay = LocalTileOverlay.init()
            tileOverlay.minimumZ = 4;
            tileOverlay.maximumZ = 17;
        }
        else // type == 1
        {
            tileOverlay = MATileOverlay.init(urlTemplate: "http://cache1.arcgisonline.cn/arcgis/rest/services/ChinaCities_Community_BaseMap_ENG/BeiJing_Community_BaseMap_ENG/MapServer/tile/{z}/{y}/{x}")
            
            /* minimumZ 是tileOverlay的可见最小Zoom值. */
            tileOverlay.minimumZ = 11;
            /* minimumZ 是tileOverlay的可见最大Zoom值. */
            tileOverlay.maximumZ = 13;
            
            /* boundingMapRect 是用来 设定tileOverlay的可渲染区域. */
            tileOverlay.boundingMapRect = MAMapRectWorld;
        }
        return tileOverlay;
    }

(2) 实现MAMapViewDelegate的mapView:viewForOverlay:函数,在瓦片显示在地图View上。示例代码如下:

- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id <maoverlay>)overlay
{
    if ([overlay isKindOfClass:[MATileOverlay class]])
    {
        MATileOverlayRenderer *renderer = [[MATileOverlayRenderer alloc] initWithTileOverlay:overlay];
        return renderer;
    } 
    return nil;
}
func mapView(_ mapView: MAMapView!, rendererFor overlay: MAOverlay!) -> MAOverlayRenderer! {
        
        if (overlay.isKind(of: MATileOverlay.self))
        {
            let renderer = MATileOverlayRenderer.init(tileOverlay: overlay as! MATileOverlay!)
            return renderer;
        }
        return nil;
    }

运行效果如下图所示:

返回顶部 示例中心 常见问题 智能客服 公众号
二维码