高德云图 iOS SDK 使用总结

作者: yanging | 来源:发表于2015-12-01 00:06 被阅读6657次

APP开发需求:加载地图,定位到用户当前的位置,并标注附近的坐标点(上图中的蓝色标注点)。坐标数据由业务人员提供。同时还需要将用户地理位置(城市)上传到服务端。地图sdk选择高德家的,高德地图对开发者比较友好。首先,注册高德开发者账号,注册之后登录帐号,申请用户Key

开发环境配置

高德提供CocoaPods安装方式,这点比百度地图做的好。自动安装比手动安装方便太多了。在Podfile中添加下面两行

pod 'AMap2DMap'
pod 'AMapSearch' #搜索服务SDK

运行命令pod install 安装高德sdk。更详细的步骤移步高德开发者配置文档

地图功能

首先,引入头文件

#import <AMapSearchKit/AMapSearchKit.h>
#import <MAMapKit/MAMapKit.h>

初始化mapview

self.mapView = [[MAMapView alloc] initWithFrame:self.view.bounds];
self.mapView.delegate = self;
self.mapView.showsUserLocation = YES;   //YES 为打开定位,NO为关闭定位
self.mapView.showsCompass = NO;
self.mapView.showsScale = NO;
self.mapView.userTrackingMode = MAUserTrackingModeFollow; // 追踪用户地理位置更新
self.mapView.zoomLevel = 16.1;
self.mapView.alpha = 0.8;

实现 MAMapViewDelegate,获取用户当前经纬坐标:

#pragma mark - MAMapViewDelegate
-(void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation updatingLocation:(BOOL)updatingLocation{
    if(updatingLocation){
        //取出当前位置的坐标
        self.currentCoordinate = userLocation.coordinate;
    }
}

- (void)mapView:(MAMapView *)mapView didFailToLocateUserWithError:(NSError *)error {
    DLog(@"%@",error);
}

当用户手动滑动地图后,可点击界面上的定位按钮,将地图中心定位到用户当前位置

-(void)locationButtonClicked {
    if (self.currentCoordinate.latitude > 0) { 
        CLLocationCoordinate2D myCoordinate = self.currentCoordinate;
        MACoordinateRegion theRegion = MACoordinateRegionMake(myCoordinate, MACoordinateSpanMake(0.2, 0.2)); 
        [self.mapView setScrollEnabled:YES];
        [self.mapView setRegion:theRegion animated:YES];
        [self.mapView setZoomLevel:16.1 animated:NO];
    }
}

通过地理位置经纬坐标获取城市名称,即逆地理编码

逆地理编码,又称地址解析服务,是指从已知的经纬度坐标到对应的地址描述(如行政区划、街区、楼层、房间等)的转换。常用于根据定位的坐标来获取该地点的位置详细信息,与定位功能是黄金搭档。

进行逆地编码时,请求参数类为 AMapReGeocodeSearchRequest,location为必设参数。

- (void)searchLocationWithCoordinate2D:(CLLocationCoordinate2D )coordinate {
    //构造AMapReGeocodeSearchRequest对象
    AMapReGeocodeSearchRequest *regeo = [[AMapReGeocodeSearchRequest alloc] init];
    regeo.location = [AMapGeoPoint locationWithLatitude:coordinate.latitude longitude:coordinate.longitude];
    regeo.radius = 10000;
    regeo.requireExtension = YES;
    
    //发起逆地理编码
    [self.searchAPI AMapReGoecodeSearch: regeo];
}

实现逆地理编码的回调函数

#pragma mark - AMapSearchDelegate
- (void)onReGeocodeSearchDone:(AMapReGeocodeSearchRequest *)request response:(AMapReGeocodeSearchResponse *)response
{
    if(response.regeocode != nil)
    {
        //通过AMapReGeocodeSearchResponse对象处理搜索结果
        NSString *city = response.regeocode.addressComponent.city;
        if (!city || [city length] == 0) {
            city = response.regeocode.addressComponent.province; // 直辖市时获取此字段
        }

        self.city = city;
    }
}

云检索

开发检索自有数据的步骤:

第一步,数据存储。开发者需要将待检索数据存入云图,并对要检索的字段建立索引管理。

第二步,检索。利用SDK为开发者提供的接口检索自己的数据。

第三步,展示。开发者可根据自己的实际需求以多种形式(如结果列表、地图模式等)展现自己的数据。

1.数据存储

由于要导入的数据量比较多,可以调用云图API批量上传数据。利用API创建云图表,需先申请Web服务APIkey,此key和ios端的key是两个独立的key,这个key用于webapi调用。创建表:

 > $apikey=xxxxxxxx;
 > curl -d "key=$apikey&name=test" http://yuntuapi.amap.com/datamanage/table/create

status=1表明创建成功,同时返回的还有tableid,根据这个tableid就可以做数据导入

{"info":"OK","status":1,"tableid":"565c0fa8e4b0dce2a8eabc81"}%

批量上传数据只能以文件的形式:

向指定tableid的数据表中通过上传文件的方式创建多条数据。该接口为异步接口,请求后立即返回后台进程batchid,通过批量创建数据进度查询接口查看任务执行进度和结果。

文件格式和大小有限制:

  • csv文件的二进制流,使用UTF8、GBK编码
  • 数据量不超过10000条且文件大小不超过10M
  • 字段总数不超过40个。
  • 字段命名规则:以英文字母开头,仅由英文字母、数字、下划线组成,总长度不超过20位

文件内容如下,name,address,longitude,latitude这四个字段是必须的,可以自定义其他字段。

name,address,longitude,latitude
543691,北京市东城区故宫博物院,116.312361,39.843083
543692,北京海淀区中关村大街1号海龙大厦,116.365686,40.034993

上传脚本:

#!/bin/bash

key=xxxxxxx
tableid=565c0fa8e4b0dce2a8eabc81
uploadDir=/User/upload

for i in `cat uploadfile.txt`  #uploadfile.txt包含了所有要上传的文件名称
do
echo -n "$i "
curl -F "file=@$uploadDir/$i" http://yuntuapi.amap.com/datamanage/data/batchcreate\\\\?key\\\\=$key\\\\&tableid\\\\=$tableid\\\\&_name\\\\=name\\\\&loctype\\\\=2\\\\&_address\\\\=address\\\\&longitude\\\\=longitude\\\\&latitude\\\\=latitude
echo " "
sleep 60
done

注意sleep 60,没有这个的话,可能无法上传成功,至少我没加sleep就全部请求返回失败。

2.客户端检索和展示:

这里需要实现的是周边检索,周边检索的请求参数对象为 AMapCloudPOIAroundSearchRequest ,其中:center 参数为必填参数。

- (void)searchCloudMapWithCenterLocationCoordinate2D:(CLLocationCoordinate2D )coordinate {
    
    NSString *tableID = self.tableID  // 云图的tableID
       
    AMapCloudPOIAroundSearchRequest *request = [[AMapCloudPOIAroundSearchRequest alloc] init];
    request.tableID = tableID;
    request.center = [AMapGeoPoint locationWithLatitude:coordinate.latitude longitude:coordinate.longitude];
    request.radius = 100000;
    request.offset = 100;  // 最多只能获取100条数据
    request.page = 1;  // 第一页
    
    [self.searchAPI AMapCloudPOIAroundSearch:request];      
}

//实现云检索对应的回调函数,添加标注Annotation
#pragma mark - AMapSearchDelegate
- (void)onCloudSearchDone:(AMapCloudSearchBaseRequest *)request response:(AMapCloudPOISearchResponse *)response {

    NSMutableArray *annotations = [[NSMutableArray alloc] init];
    for (AMapCloudPOI *poi in response.POIs) {
        AMapGeoPoint *point = poi.location;
        MAPointAnnotation *annotation = [[MAPointAnnotation alloc] init];
        annotation.coordinate = CLLocationCoordinate2DMake(point.latitude, point.longitude);
        [annotations addObject:a1];
    }
   
    [self.mapView addAnnotations:[annotations copy]];
    [self.mapView showAnnotations:annotations animated:YES];
}

实现 MAMapViewDelegate 协议中的 mapView:viewForAnnotation:回调函数,设置标注样式。

- (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.image = [UIImage imageNamed:@"location_annotation"];
        }
       
        return annotationView;
    }
    return nil;
}

地图定位加标注的功能就完成了。

相关文章

网友评论

  • LV大树:565c0fa8e4b0dce2a8eabc81 这个tableID要怎么弄的。
  • 4a5a6523f8d2:大神,为什么onReGeocodeSearchDone一直不进呢?我对象都init了。
  • 大好河山_:已经解决了,打扰了,谢谢您的好文!!!!
  • 大好河山_:大神您好,我想请问下在使用高德地图的时候,我要显示10个标注,其中一个标注在其他的省(标注跨度范围比较大),这个时候我调用
    [self.mapView addAnnotations:self.dataScoure];
    [self.mapView showAnnotations:self.dataScoure animated:YES];
    这两个方法,我的界面是蓝屏的,请问您知道原因不?

  • 早上好先生:为啥我找不到AMapReGeocodeSearchRequest这个东西
  • 小_蜡笔:有没有demo,跪求发一份,
  • 北暖37:逆地址解析有没有demo可以参考先,我写的总是有问题,但是又不知道如何解决
    yanging:@慕糖123
    //实现逆地理编码的回调函数
    - (void)onReGeocodeSearchDone:(AMapReGeocodeSearchRequest *)request response:(AMapReGeocodeSearchResponse *)response
    {
    if(response.regeocode != nil)
    {
    //通过AMapReGeocodeSearchResponse对象处理搜索结果
    AMapAddressComponent *address = response.regeocode.addressComponent;

    NSString *township;
    if (address.township != nil && [address.township length] > 0) {
    township = [address.township stringByReplacingOccurrencesOfString:@"街道$" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, [address.township length])];
    } else {
    township = @"";
    }

    NSString *locationString = [NSString stringWithFormat:@"您的位置:%@%@", address.district, township];
    NSLog(@"%@",locationString);
    }
    }

本文标题:高德云图 iOS SDK 使用总结

本文链接:https://www.haomeiwen.com/subject/knyjhttx.html