美文网首页临时收藏iOS学习坚持写
带方向的定位小蓝点--高德地图ios

带方向的定位小蓝点--高德地图ios

作者: just_xam | 来源:发表于2017-01-10 12:08 被阅读4990次

    进入最近很火的摩拜单车,你看到的是这样的

    mobike.gif

    其实很早之前百度地图和高德地图就实现了这个功能,但是他们的SDK并没有可以直接使用的属性来造福大众,想实现虽然不难,但还是要自己动手,建议官方直接加一个 isUserDirectionOpen 属性,岂不美哉!

    实现这个功能说来也简单

    1 获取到用户方向

    2 根据方向旋转箭头


    先做一下前期准备工作

    1.新建一个swift项目,导入高德地图SDK
    我用的是pods安装高德地图SDK
    Podfile文件里面这样写就可以

    platform :ios, "8.0"
    use_frameworks!
    target :'RotateArrow' do
    pod 'AMap3DMap'
    end
    

    2.配置工程
    新建桥接文件,在桥接文件中导入相关库文件

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

    在plist中添加键值
    Privacy - Location When In Use Usage Description

    App Transport Security Settings 的 Allow Arbitrary Loads


    1.获取设备方向

    1). CoreLocation

    CoreLocation里有个heading: CLHeading属性,它包含了当前的方向信息,CLHeading有三个属性,地图中自带此信息

    /*
         *  x
         *  
         *  Discussion:
         *    Returns a raw value for the geomagnetism measured in the x-axis.
         *
         */
        open var x: CLHeadingComponentValue { get }
    
        
        /*
         *  y
         *  
         *  Discussion:
         *    Returns a raw value for the geomagnetism measured in the y-axis.
         *
         */
        open var y: CLHeadingComponentValue { get }
    
        
        /*
         *  z
         *  
         *  Discussion:
         *    Returns a raw value for the geomagnetism measured in the z-axis.
         *
         */
        open var z: CLHeadingComponentValue { get }
    

    以上摘自官方API,方向可根据这三个值算出来

    在高德地图的更新用户位置的代理中可以获取heading信息
    func mapView(_ mapView: MAMapView!, didUpdate userLocation: MAUserLocation!, updatingLocation: Bool) {
          let heading = userLocation.heading     
    }
    

    2). CoreMotion

    CoreMotion里根据deviceMotion里的attitude也可以获取方向,网上有相关教程,有兴趣的朋友可以自行百度下---详说CMDeviceMotion

    2.根据方向旋转箭头

    1). 用带箭头的图片替换官方的小蓝点
    arrow.png

    ...渣图勿喷,我直接在摩拜单车截了个图用ps随便扣的,这应该不算侵权吧

    在viewForAnnotation代理中替换系统视图
    ///返回大头针视图
        func mapView(_ mapView: MAMapView!, viewFor annotation: MAAnnotation!) -> MAAnnotationView! {
            if annotation is MAUserLocation {
                var userView = mapView.dequeueReusableAnnotationView(withIdentifier: userAnnotationIdentifer)
                if userView == nil {
                    userView = MAAnnotationView(annotation: annotation, reuseIdentifier: userAnnotationIdentifer)
                }
                userView!.image = UIImage(named: "arrow")
                return userView!
            }
            return nil
        }
    
    IMG_1433.PNG
    2).旋转此图片
    func mapView(_ mapView: MAMapView!, didUpdate userLocation: MAUserLocation!, updatingLocation: Bool) {
            
            //取得用户大头针视图
            let userView = mapView.view(for: userLocation)
          
            //取方向信息
           let userHeading = userLocation.heading 
            
            //根据方向旋转箭头
            userView.rotateWithHeading(heading: userHeading)
            
        }
    

    rotateWithHeading是一个MAAnnotationView的扩展

    //针对MAAnnotationView的扩展
    extension MAAnnotationView {
        
        /// 根据heading信息旋转大头针视图
        ///
        /// - Parameter heading: 方向信息
        func rotateWithHeading(heading: CLHeading) {
            
            //将设备的方向角度换算成弧度
            let headings = M_PI * heading.magneticHeading / 180.0
            //创建不断旋转CALayer的transform属性的动画
            let rotateAnimation = CABasicAnimation(keyPath: "transform")
            //动画起始值
            let formValue = self.layer.transform
            rotateAnimation.fromValue = NSValue(caTransform3D: formValue)
            //绕Z轴旋转heading弧度的变换矩阵
            let toValue = CATransform3DMakeRotation(CGFloat(headings), 0, 0, 1)
            //设置动画结束值
            rotateAnimation.toValue = NSValue(caTransform3D: toValue)
            rotateAnimation.duration = 0.35
            rotateAnimation.isRemovedOnCompletion = true
            //设置动画结束后layer的变换矩阵
            self.layer.transform = toValue
            
            //添加动画
            self.layer.add(rotateAnimation, forKey: nil)
            
        }
    }
    

    最后效果图

    end.gif

    代码已放到git上 DirectionMap

    附录:其他地图原理类似,百度地图方向实现

    相关文章

      网友评论

      • bill666500:Demo地址404了,求一个链接
      • alelaile:git 404 有没有oc版本的 啊
      • 若如初见0:你好,楼主有没有试过用陀螺仪来实现这个功能呢
      • WARRON:点击气泡 弹出的气泡方向也是改变了, 请问怎么解决呢
      • Fengzesheng:你好 我集成的地图 didUpdateUserLocation 调用迟缓,高德4.6api,设备方向改变几秒钟箭头才旋转是什么原因
        贵叔勇闯天涯:这个有OC版本的吗??
        5ff7e9d9296f:请问:我看官方文档说:
        MAUserLocationRepresentation *r = [[MAUserLocationRepresentation alloc] init];
        r.showsHeadingIndicator = NO;///是否显示方向指示(MAUserTrackingModeFollowWithHeading模式开启)。默认为YES
        就可以了
        [self.mapView updateUserLocationRepresentation:r];
        这样就可以显示小蓝点的方向。
        我弄了,还是不行。所以……就是说他的这个属性是不存在的吗。
        just_xam:@Fengzesheng 有时快有时候慢比较正常,但是如果一直慢可能就有点问题
      • CoderSJun:不错不错 要是是定制小蓝点可以闪烁起来的是怎么样做的?
        just_xam:@CoderSJun 中间那个黑的不是大头针,你会发现它永远在屏幕中间,它的位置其实是没动的,在动的只有地图,它其实就是个imageView,然后center在屏幕中间
        CoderSJun:@just_xam 还有一个问题 摩拜单车屏幕中间的黑黑大头针是自定义POI吗 自行车的位置是自定义POI 如果一样的话 怎么区别呢?
        just_xam:要闪烁的话,你可以继承MAAnnotationView,然后在继承的view里面添加一个闪烁的小蓝点视图,返回MAAnnotationView的时候你就返回你自定义的view就行了
      • Pusswzy:加油
      • f862def1f71c:呦呵,我是沙发:joy: 写的不错,666666

      本文标题:带方向的定位小蓝点--高德地图ios

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