将来跳槽用iOS开发笔录iOS学习

iOS 使用高德地图实现路径绘制及回放

2017-07-04  本文已影响1645人  话里长巷

近日状况

好久没更新了,因为换了份工作,当前公司项目在都在忙着加班赶项目,现在项目快结束了,乘这时间(其实是我懒=≡Σ(((つ•̀ω•́)つ)给更新。

瞎扯

人们生活水平高了,对自己的身体开始注意了,运动类的App开始抢占市场(我记得是14年开始的,说得自己像是一个老程序员一样) 今天我就给大家分享一篇项目中的运动模块对路径绘制及重播的部分。
先给你看一下实现的效果:


轨迹绘制及播放

因为在模拟器上测试,坐标是在地图之外,显示的是灰色的

概述

  • 这里是基于高德地图的实现的
  • 实时轨迹的绘制以及路径重播

配置

我想来看这的对于高德地图的配置应该是知道的了,如果有什么疑问参考官方。

这里使用的是高德地图4.6.1版本 基础SDK是1.4 记得使用高德地图5.0.0版本的时候坐标会飘 是的回飘,如果有用最新版的可以自行测试一下,是不是还会出现在这样的情况。

实现

1.绘制

- (void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation updatingLocation:(BOOL)updatingLocation{
    
    if (!updatingLocation) {
        return;
    }
    
    if (self.isRecording)
    {
        //传感器活动状态
//        BOOL deviceActivity  = ([StepSampleManage shareManage].deviceActivityState != SADeviceActivityStateNotMoving && [StepSampleManage shareManage].deviceActivityState != SADeviceActivityStateUnknown);
//        if (SIMULATOR_TEST) {
//            deviceActivity = YES;
//        }
        BOOL deviceActivity = YES;
        if (userLocation.location.horizontalAccuracy < 40 && userLocation.location.horizontalAccuracy > 0 && deviceActivity)
        {

            if (self.currentRecord.totalDistance >= 100 && !self.existStartPointed) {
                MAPointAnnotation *annotation = [[MAPointAnnotation alloc]init];
                annotation.coordinate = self.currentRecord.coordinates[0];
                [mapView addAnnotation:annotation];
                self.existStartPointed = YES;
            }
        
            [self.locationsArray addObject:userLocation.location];
            
            NSLog(@"date: %@,now :%@",userLocation.location.timestamp,[NSDate date]);
            [self.tipView showTip:[NSString stringWithFormat:@"has got %ld locations",self.locationsArray.count]];
            
            [self.currentRecord addLocation:userLocation.location];
        
            [self.mutablePolyline appendPoint:MAMapPointForCoordinate(userLocation.location.coordinate)];
            
            [self.mapView setCenterCoordinate:userLocation.location.coordinate animated:YES];
            
            [self.mutableView referenceDidChange];
        }
    }
#ifdef DEBUG
    [self.statusView showStatusWith:userLocation.location];
#endif
}

通过代理获取的坐标的传入Record模型中,这里的模型是一个Demo的模型,你们可以根据自己的实际情况定义
mutablePolyline和mutableView相当于画笔和画板,没错这样去理解(大概就是这个意思)获取到的点在地图变成线

2.播放

播放这里使用mutablePolyline和MAMutablePolylineRenderer *mutableView 是一个能提供有多种颜色的画板去理解,读取之前保存的记录 (我之前实际项目是保存在数据库中的) 这里主要是播放速度和播放点的
控制

- (void)animateToNextCoordinate
{
    if (self.myLocation == nil)
    {
        return;
    }
    
    CLLocationCoordinate2D *coordinates = [self.record coordinates];
    if (self.currentLocationIndex == [self.record numOfLocations] )
    {
        self.currentLocationIndex = 0;
        [self actionPlayAndStop];
        return;
    }
    
    CLLocationCoordinate2D nextCoord = coordinates[self.currentLocationIndex];
    CLLocationCoordinate2D preCoord = self.currentLocationIndex == 0 ? nextCoord : self.myLocation.coordinate;
    
    self.heading = [self coordinateHeadingFrom:preCoord To:nextCoord];
    CLLocationDistance distance = MAMetersBetweenMapPoints(MAMapPointForCoordinate(nextCoord), MAMapPointForCoordinate(preCoord));
    NSTimeInterval duration = distance / (self.averageSpeed * 1000 * self.multiple);
    
    CLLocationCoordinate2D coords[2];
    coords[0] = preCoord;
    coords[1] = nextCoord;
    
    
    @weakify(self)
    [self.myLocation addMoveAnimationWithKeyCoordinates:coords count:2 withDuration:duration + 0.01 withName:kUserLoctionAnimatedKey completeCallback:^(BOOL isFinished) {
        @strongify(self)
        self.currentLocationIndex ++;
        self.playSlier.value = (float)self.currentLocationIndex/[self.record numOfLocations];
        if (isFinished) {
            [self animateToNextCoordinate];
        }
    }];
    self.myLocation.movingDirection = self.heading;
}

获取保存的当前坐标点和上一个点的动画时间

动画时间 = 距离 / (播放速度*播放倍数)

 for(MAAnnotationMoveAnimation *animation in [self.myLocation allMoveAnimations]) {
        if ([animation.name isEqualToString:kUserLoctionAnimatedKey]) {
               [animation cancel];
        }
  }

使用上述的方法去取消动画,如果对方向有要求的记录一下停止之前的方向然后再试下

self.myLocation.movingDirection = self.heading;

以上就是整个绘制和播放了

  • 如果后台绘制需要后台定位权限
  • 如果暂停的时候,我们要处理这过程可能发生的情况
  • 为了节省空间没有上传地图,demo克隆下来后重新pod update
  • 如果有什么问题,可以提出来大家讨论一下类似我的位置飘的问题,我这里是通过陀螺仪的来判断的

源码地址:路径绘制及播放

参考

https://github.com/amapapi/iOS_3D_RecordPath

结束语

  • 还有就是...就是...那个...那个...Demo是简化版的,搬过来有点花时间和上面的UI有不一样的地方 👻
  • 下一次更新陀螺仪获取步数
  • 如果对你有所帮助,请我给我一颗star作为鼓励
我不管我最帅,我是你们的小可爱
上一篇 下一篇

猜你喜欢

热点阅读