开发 iOS 地图SDK 概述

概述 最后更新时间: 2025年12月03日

重要:由于个人信息保护法的实施,从地图8.1.0版本起对旧版本SDK不兼容,请务必确保调用SDK任何接口前先调用更新隐私合规updatePrivacyShow、updatePrivacyAgree两个接口,否则可能导致功能不可用等异常情况。具体可参考开发指南-其他配置注意事项-隐私合规接口说明传入相关参数。

高德地图iOS SDK简介

高德开放平台目前开放了 iOS 地图 SDK 以及 iOS 地图 SDK 专业版两套地图SDK工具。

高德地图 iOS SDK 是一套基于 iOS 8.0 及以上版本的地图应用程序开发接口,供开发者在自己的iOS应用中加入地图相关的功能,包括:地图显示(含室内、室外地图)、与地图交互、在地图上绘制、兴趣点搜索、地理编码、离线地图等功能。

高德地图 iOS SDK 专业版是在 iOS SDK 已有服务的基础上,新增支持了自定义地图在线加载、自定义地图元素纹理等功能,便于开发者完成基于自身场景的更深层、更个性化地图的开发需求。

  • 展示地图
    /*创建地图并添加到父view上*/
     self.mapView = [[MAMapView alloc] initWithFrame:self.view.bounds];
     self.mapView.delegate = self;
     [self.view addSubview:self.mapView];
  • Marker
    /*添加annotation*/
    self.annotations = [NSMutableArray array];
     CLLocationCoordinate2D coordinates[10] = {
     {39.992520, 116.336170},
     {39.992520, 116.336170},
     {39.998293, 116.352343},
     {40.004087, 116.348904},
     {40.001442, 116.353915},
     {39.989105, 116.353915},
     {39.989098, 116.360200},
     {39.998439, 116.360201},
     {39.979590, 116.324219},
     {39.978234, 116.352792}}; 
     for (int i = 0; i < 10; ++i)
     {
     MAPointAnnotation *a1 = [[MAPointAnnotation alloc] init];
     a1.coordinate = coordinates[i];
     a1.title = [NSString stringWithFormat:@"anno: %d", i];
     [self.annotations addObject:a1];
     }
    - (void)viewDidAppear:(BOOL)animated
    {
     [super viewDidAppear:animated]; 
     [self.mapView addAnnotations:self.annotations];
     [self.mapView showAnnotations:self.annotations edgePadding:UIEdgeInsetsMake(20, 20, 20, 80) animated:YES];
    }
    /* 实现代理方法:*/
    - (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id<MAAnnotation>)annotation
    {
     if ([annotation isKindOfClass:[MAPointAnnotation class]])
     {
     static NSString *pointReuseIndetifier = @"pointReuseIndetifier";
     MAPinAnnotationView *annotationView = (MAPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:pointReuseIndetifier];
     if (annotationView == nil)
     {
     annotationView = [[MAPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pointReuseIndetifier];
     }
     annotationView.canShowCallout = YES;
     annotationView.animatesDrop = YES;
     annotationView.draggable = YES;
     annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
     annotationView.pinColor = [self.annotations indexOfObject:annotation] % 3;
     return annotationView;
     }
     return nil;
    }
  • 驾车路线规划
    AMapDrivingRouteSearchRequest *navi = [[AMapDrivingRouteSearchRequest alloc] init];
     navi.requireExtension = YES;
     navi.strategy = 5;
     /* 出发点. */
     navi.origin=[AMapGeoPoint locationWithLatitude:self.startCoordinate.latitude
     longitude:self.startCoordinate.longitude];
     /* 目的地. */
     navi.destination = [AMapGeoPoint locationWithLatitude:self.destinationCoordinate.latitude
     longitude:self.destinationCoordinate.longitude];
     [self.search AMapDrivingRouteSearch:navi];
  • 搜索POI
    /* 根据ID来搜索POI. */
    - (void)searchPoiByID
    {
     AMapPOIIDSearchRequest *request = [[AMapPOIIDSearchRequest alloc] init];
     request.uid = @"B000A7ZQYC";
     request.requireExtension = YES;
     
     [self.search AMapPOIIDSearch:request];
     
    }
    /* 根据关键字来搜索POI. */
    - (void)searchPoiByKeyword
    {
     AMapPOIKeywordsSearchRequest *request = [[AMapPOIKeywordsSearchRequest alloc] init];
     
     request.keywords = @"北京大学";
     request.city = @"北京";
     request.types = @"高等院校";
     request.requireExtension = YES;
     
     /* 搜索服务 3.2.0 中新增加的功能,只搜索本城市的POI。*/
     request.cityLimit = YES;
     request.requireSubPOIs = YES;
     
     [self.search AMapPOIKeywordsSearch:request];
    }
  • 自定义OpenGL渲染
    /* 计算经纬度坐标对应的OpenGL坐标,每次地图坐标系有变化均会调用这个方法。 */
    - (void)referenceDidChange
    {
     [super referenceDidChange];
     
     //根据z=0平面的尺寸计算新的参考坐标系距离单位
     CGPoint * bottomGlPts = [self glPointsForMapPoints:_bottomMapPts count:2];
     
     _cubePointCount = totalVertexCount;
     
     CGFloat sideLenOnGL = [self lengthBetweenPointA:bottomGlPts[0] andPointB:bottomGlPts[1]];
     
     float w = sideLenOnGL * 0.5f;
     _move = Vertex(w,0,0);
     
     /*计算模型中心的GL坐标。*/
     MAMapPoint center = MAMapPointForCoordinate(self.overlay.coordinate);
     CGPoint centerGL = [self glPointForMapPoint:center];
     _cubeCenterGL = Vertex(centerGL.x, centerGL.y, w);
     /* 创建vertex。 */
     _cubePoints[0] = Vertex(-w, -w, -w);
     _cubePoints[1] = Vertex(-w, -w, w);
     _cubePoints[2] = Vertex(w, -w, -w);
     _cubePoints[3] = Vertex(w, -w, w);
     _cubePoints[4] = Vertex(w, w, -w);
     _cubePoints[5] = Vertex(w, w, w);
     _cubePoints[6] = Vertex(-w, w, -w);
     _cubePoints[7] = Vertex(-w, w, w);
     
     free(bottomGlPts);
     
     /* 创建index。 */
     const GLuint indexCountOnSideFace = 24;
     //4个侧面
     for (int i = 0, j = 0; i < _cubePointCount && j < indexCountOnSideFace; i = i + 2)
     {
     _cubeIndices[j++] = i;
     _cubeIndices[j++] = i+1;
     _cubeIndices[j++] = (i+2)%_cubePointCount;
     
     _cubeIndices[j++] = i+1;
     _cubeIndices[j++] = (i+3)%_cubePointCount;
     _cubeIndices[j++] = (i+2)%_cubePointCount;
     }
     
     //顶面和底面
     for (int i = 0, j = indexCountOnSideFace; i < 2 && j < indexCount; i++)
     {
     _cubeIndices[j++] = i;
     _cubeIndices[j++] = i + 2;
     _cubeIndices[j++] = i + 4;
     
     _cubeIndices[j++] = i;
     _cubeIndices[j++] = i + 4;
     _cubeIndices[j++] = i + 6;
     }
     
    }
    /* OpenGL绘制。 */
    - (void)glRender
    {
     glEnable(GL_DEPTH_TEST);
     glDepthFunc(GL_ALWAYS);
     
     glEnable(GL_BLEND);
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     
     glDisable(GL_TEXTURE_2D);
     glEnableClientState(GL_VERTEX_ARRAY);
     
     //进行位移
     glPushMatrix();
     
     const float speed = 0.1;
     static float i = 0;
     glTranslatef(_cubeCenterGL.x + _move.x * i, _cubeCenterGL.y + _move.y * i, _cubeCenterGL.z + _move.z * i);
     float forward = speed;
     if (i > 6)
     {
     forward = -speed;
     }else if(i < -6)
     {
     forward = speed;
     }
     i = i + forward;
     glVertexPointer(3, GL_FLOAT, 0, _cubePoints);
     const GLuint faceCount = 6;
     const GLuint indexCountPerFace = 6;
     
     GLfloat r,b,g;
     for(int i = 0; i < faceCount; i++)
     {
     r = 0.5 + 0.5 * (i&1);
     g = 0.5 + 0.5 * (i&2);
     b = 0.5 + 0.5 * (i&4);
     glColor4f(r, g, b, 0.5);
     glDrawElements(GL_TRIANGLES, indexCountPerFace, GL_UNSIGNED_SHORT, &_cubeIndices[i*indexCountPerFace]);
     }
     
     glPopMatrix();
     //结束位移
     
     glDisableClientState(GL_VERTEX_ARRAY);
     glDisable(GL_BLEND);
     glDisable(GL_DEPTH_TEST);
    }
  • 离线地图
    [[MAOfflineMap sharedOfflineMap] downloadItem:item shouldContinueWhenAppEntersBackground:YES downloadBlock:^(MAOfflineItem * downloadItem, MAOfflineMapDownloadStatus downloadStatus, id info) {
     
     if (![self.downloadingItems containsObject:downloadItem])
     {
     [self.downloadingItems addObject:downloadItem];
     [self.downloadStages setObject:[NSMutableDictionary dictionary] forKey:downloadItem.adcode];
     }
     
     /* Manipulations to your application’s user interface must occur on the main thread. */
     dispatch_async(dispatch_get_main_queue(), ^{
     
     NSMutableDictionary *stage = [self.downloadStages objectForKey:downloadItem.adcode];
     
     if (downloadStatus == MAOfflineMapDownloadStatusWaiting)
     {
     [stage setObject:[NSNumber numberWithBool:YES] forKey:DownloadStageIsRunningKey2];
     }
     else if(downloadStatus == MAOfflineMapDownloadStatusProgress)
     {
     [stage setObject:info forKey:DownloadStageInfoKey2];
     }
     else if(downloadStatus == MAOfflineMapDownloadStatusCancelled
     || downloadStatus == MAOfflineMapDownloadStatusError
     || downloadStatus == MAOfflineMapDownloadStatusFinished)
     {
     [stage setObject:[NSNumber numberWithBool:NO] forKey:DownloadStageIsRunningKey2];
     
     // clear
     [self.downloadingItems removeObject:downloadItem];
     [self.downloadStages removeObjectForKey:downloadItem.adcode];
     }
     
     [stage setObject:[NSNumber numberWithInt:downloadStatus] forKey:DownloadStageStatusKey2];
     
     /* Update UI. */
     //更新触发下载操作的item涉及到的UI
     [self updateUIForItem:item atIndexPath:indexPath];
     
     if (downloadStatus == MAOfflineMapDownloadStatusFinished)
     {
     self.needReloadWhenDisappear = YES;
     }
     });
     }];

下载完整示例代码

账号与Key的申请

注册成为高德开发者需要分三步:

第一步,注册高德开发者;

第二步,去控制台创建应用;

第三步,获取Key。

具体步骤可参看下图

获取 API Key

兼容性

高德地图iOS 地图 SDK 4.4.0以下版本支持iOS 6.0及以上系统;

高德地图iOS 地图 SDK 4.4.0及以上版本支持 iOS 7.0及以上系统;

高德地图iOS 地图 SDK 6.7.0及以上版本支持 iOS 8.0及以上系统。

开发者使用注意事项

(1)法人或非法人组织使用平台服务应事先购买技术服务许可以获取许可。若您未购买技术服务许可,平台向您提供的KEY和服务配额仅供您用于短期、少量的测试目的;若您超出前述范围使用平台服务(包括但不限于您开始向第三方或公众销售或提供您的应用、将您的应用用于参与第三方投标、您的应用在应用程序分发平台上架或已经可以被公众获取使用、您的应用开始收费或发布广告或以其他方式获益、在组织内部使用的您的应用已上线运营、您的应用长期或大量调用平台服务等情形),构成未许可使用,平台有权采取相应措施。关于具体使用规则,请参阅《高德地图开放平台服务协议》获得详细信息。

(2)iOS V2.0.6.1(含)之前版本的SDK搜索服务将于2015年2月底停止使用,涉及到POI查询、地理编码、逆地理编码、路径规划、公交查询。如您已采用旧版iOS SDK进行开发,建议您采用最新版本的 iOS SDK进行开发,请参阅升级方案

(3)iOS SDK V2.4.0(含)之后版本适配了arm 64架构,免除您的app提交到app store的后顾之忧。

示例中心 常见问题

AltStyle によって変換されたページ (->オリジナル) /