使用高德猎鹰SDK仿滴滴打车,多辆车辆实时更新位置信息

使用高德猎鹰SDK仿滴滴打车,多辆车辆实时更新位置信息。附加服务端对应实现思路。

参考高德地图文档:
点平滑移动
查询终端实时位置

效果

效果图
实现关键点

1、标注使用MAAnimatedAnnotation
2、标注title使用TerminalID,和“查询实时位置回调”中的AMapTrackQueryLastPointRequest *request“ terminalID”对应。
3、同时查询多个终端的实时位置 AMapTrackQueryLastPoint可调用多次。

实现步骤

开始前请先参照高德开发文档创建好工程,高德猎鹰SDK文档。或下载本文中对应的demo

1、获取轨迹上报的参数(serviceID、TerminalID)。

获取serviceID,参照高德服务管理文档
获取TerminalID如下:

- (void)setupTrack {
    AMapTrackManagerOptions *option = [[AMapTrackManagerOptions alloc] init];
    option.serviceID = kAMapTrackServiceID;
    //初始化AMapTrackManager
    self.trackManager = [[AMapTrackManager alloc] initWithOptions:option];
    self.trackManager.delegate = self;
    
    //查询终端是否存在
    AMapTrackQueryTerminalRequest *request = [[AMapTrackQueryTerminalRequest alloc] init];
    request.serviceID = self.trackManager.serviceID;
    request.terminalName = [self saveDeviceModel];
    [self.trackManager AMapTrackQueryTerminal:request];
}

//查询终端结果
- (void)onQueryTerminalDone:(AMapTrackQueryTerminalRequest *)request response:(AMapTrackQueryTerminalResponse *)response
{
    //查询成功
    if ([[response terminals] count] > 0) {
        //查询到结果,使用 Terminal ID
        NSString *terminalID = [[[response terminals] firstObject] tid];
        [self saveTerminalId:terminalID];
        //启动上报服务(service id),参考下一步
    }
    else {
        //查询结果为空,创建新的terminal
        AMapTrackAddTerminalRequest *addRequest = [[AMapTrackAddTerminalRequest alloc] init];
        addRequest.serviceID = self.trackManager.serviceID;
        addRequest.terminalName = [self saveDeviceModel];
        [self.trackManager AMapTrackAddTerminal:addRequest];
    }
}

//创建终端结果
- (void)onAddTerminalDone:(AMapTrackAddTerminalRequest *)request response:(AMapTrackAddTerminalResponse *)response {
    //创建terminal成功
    NSString *terminalID = [response terminalID];
    [self saveTerminalId:terminalID];
    //启动上报服务(service id),参考下一步
}

//错误回调
- (void)didFailWithError:(NSError *)error associatedRequest:(id)request {
    if ([request isKindOfClass:[AMapTrackQueryTerminalRequest class]]) {
        //查询参数错误
    }
    
    if ([request isKindOfClass:[AMapTrackAddTerminalRequest class]]) {
        //创建terminal失败
    }
    NSLog(@"%@", error);
    
    _msgLabel.text = [NSString stringWithFormat:@"初始化失败"];
}
- (void)saveTerminalId:(NSString *)terminalId {
    [[NSUserDefaults standardUserDefaults] setObject:terminalId forKey:@"terminalId"];
    [[NSUserDefaults standardUserDefaults] synchronize];
    
    _msgLabel.text = [NSString stringWithFormat:@"初始化成功:设备terminalId: %@", terminalId];
}

获取完后将terminalID保存本地,供接下来轨迹上报和查询使用。

2、开始轨迹上报

(1)、创建mapview。具体代码参照高德地图文档或demo中代码。
(2)、初始化轨迹上报

- (void)setupReport {
    AMapTrackManagerOptions *option = [[AMapTrackManagerOptions alloc] init];
    option.serviceID = kAMapTrackServiceID;
    
    //初始化AMapTrackManager
    self.trackManager = [[AMapTrackManager alloc] initWithOptions:option];
    self.trackManager.delegate = self;
    
    // 配置猎鹰SDK
    [self.trackManager setAllowsBackgroundLocationUpdates:YES];
    [self.trackManager setPausesLocationUpdatesAutomatically:NO];
    /**
     定位信息的采集周期,单位秒,有效值范围[1, 60]。
     定位信息的上传周期,单位秒,有效值范围[5, 3000]
     */
    [self.trackManager changeGatherAndPackTimeInterval:2 packTimeInterval:2];
    // 配置本地缓存大小,默认最多缓存50MB数据
    [self.trackManager setLocalCacheMaxSize:50];
}

(3)、开启轨迹上报

//开始服务
        AMapTrackManagerServiceOption *serviceOption = [[AMapTrackManagerServiceOption alloc] init];
        serviceOption.terminalID = kAMapTrackTerminalID;
        
        [self.trackManager startServiceWithOptions:serviceOption];
//service 开启结果回调
- (void)onStartService:(AMapTrackErrorCode)errorCode {
    if (errorCode == AMapTrackErrorOK) {
        //开始服务成功,继续开启收集上报
        [self.trackManager startGatherAndPack];
    } else {
        //开始服务失败
        MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
        hud.mode = MBProgressHUDModeIndeterminate;
        hud.label.text = @"开始服务失败";
        [hud hideAnimated:YES afterDelay:1];
    }
}

//gather 开启结果回调
- (void)onStartGatherAndPack:(AMapTrackErrorCode)errorCode {
    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
    hud.mode = MBProgressHUDModeIndeterminate;
    if (errorCode == AMapTrackErrorOK) {
        //开始采集成功
        hud.label.text = @"开始采集成功";
    } else {
        //开始采集失败
        hud.label.text = @"开始采集失败";
    }
    [hud hideAnimated:YES afterDelay:1];
}
3、查询对应终端TerminalID的实时位置信息。

(1)、创建mapview。具体代码参照高德地图文档或demo中代码。
(2)、初始化轨迹查询

- (void)setupReport {
    AMapTrackManagerOptions *option = [[AMapTrackManagerOptions alloc] init];
    option.serviceID = kAMapTrackServiceID;
    
    //初始化AMapTrackManager
    self.trackManager = [[AMapTrackManager alloc] initWithOptions:option];
    self.trackManager.delegate = self;
    
    AMapTrackQueryLastPointRequest *request = [[AMapTrackQueryLastPointRequest alloc] init];
    request.serviceID = self.trackManager.serviceID;
    request.terminalID = kAMapTrackTerminalID;
    // 纠偏
//    request.correctionMode = @"denoise=1,mapmatch=1,threshold=0,mode=driving";
    [self.trackManager AMapTrackQueryLastPoint:request];
}

(3)、初始化标注(地图添加终端对应的标注)。

- (void)setupAnnotation {
    _annotationData = @[].mutableCopy;
    
#warning 设置多个时,数组中添加TerminalID
    NSArray *annotations = @[kAMapTrackTerminalID];
    [annotations enumerateObjectsUsingBlock:^(NSString *annotationTitle, NSUInteger idx, BOOL * _Nonnull stop) {
        MAAnimatedAnnotation *anno = [[MAAnimatedAnnotation alloc] init];
        anno.title = annotationTitle;
        [_annotationData addObject:anno];
    }];
    [self.mapView addAnnotations:_annotationData];
}
(4)、轨迹查询回调(重点在这,查询完后需要将位置、方向信息,让MAAnimatedAnnotation addMoveAnimationWithKeyCoordinates方法调用),并在完成时继续调用AMapTrackQueryLastPoint获取终端最后位置信息。
#pragma mark 查询实时位置回调
- (void)onQueryLastPointDone:(AMapTrackQueryLastPointRequest *)request response:(AMapTrackQueryLastPointResponse *)response {
    //查询成功
    NSLog(@"onQueryLastPointDone%@", response.formattedDescription);
    
    if(!_isLoction){
        self.mapView.centerCoordinate = response.lastPoint.coordinate;
        _isLoction = YES;
    }
    
    AMapTrackPoint *lastPoint = response.lastPoint;
    CLLocationCoordinate2D *coordinate = malloc(sizeof(CLLocationCoordinate2D));
    CLLocationCoordinate2D *point = &coordinate[0];
    point->latitude = lastPoint.coordinate.latitude;
    point->longitude = lastPoint.coordinate.longitude;
    
    __block MAAnimatedAnnotation *anno;
    [_annotationData enumerateObjectsUsingBlock:^(MAAnimatedAnnotation *annotation, NSUInteger idx, BOOL * _Nonnull stop) {
        if([annotation.title isEqualToString:request.terminalID]){
            anno = annotation;
        }
    }];
    anno.movingDirection = lastPoint.direction;
    
    [anno addMoveAnimationWithKeyCoordinates:coordinate count:1 withDuration:1 withName:anno.title completeCallback:^(BOOL isFinished) {
        if(isFinished){
            [self.trackManager AMapTrackQueryLastPoint:request];
        }
    }];
    
}

- (void)didFailWithError:(NSError *)error associatedRequest:(id)request {
    if ([request isKindOfClass:[AMapTrackQueryLastPointRequest class]]) {
        //查询失败
        MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
        hud.mode = MBProgressHUDModeIndeterminate;
        hud.label.text = @"查询失败";
        [hud hideAnimated:YES afterDelay:1];
    }
}

到这里基本功能已经实现了。

服务端对应关系

1、轨迹上报的TerminalID终端ID和服务器单个终端/或用户ID关联(用户信息中包含TerminalID)。TerminalID由高德地图SDK生成,然后传给服务器。TerminalID由terminalName终端名字和高德控制平台serviceID确定。
2、根据服务器列表中的TerminalID,同时查询多个终端的实时位置 AMapTrackQueryLastPoint。
3、轨迹上报,只通知服务器已开启轨迹上报,轨迹的位置信息保存在高德轨迹服务中。

QA:
1、怎么判断地图中实时显示哪些终端?

:由后台接口返回需要显示的终端列表(数据中包含TerminalID),接口判断依据应是当前定位“范围”加“终端是否在实时上报轨迹信息”。

2、怎么判断终端是否在实时上报轨迹信息?

:由自己业务逻辑判断何时开启/关闭。

本文中demo链接:https://github.com/weiweilong/MAPLocationGithub 谢谢阅读!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容