Google Map 开发(二):根据方向传感器对 Marker 进行旋转

这是最近做的一个小功能,虽然很简单,网上却很少有相关例子,关于怎么使用地磁和加速度传感器的例子是有了,怎么旋转 Google Map Marker 也能 Google 到一些,但是结合起来就基本没看到,也可能是我搜索方式不对,所以还是自己来实现了。

首先找找 Google Map Marker 相关的文档,如何使用可以参见这个:

https://developers.google.com/maps/documentation/android-sdk/marker?hl=zh-cn

对于 Marker 类可以参考:

https://developers.google.com/android/reference/com/google/android/gms/maps/model/Marker?hl=zh-cn

(2018/06/29 验证)

Marker 有一个很重要的属性:Anchor,请记者这个小东西,后面要用到它,官方的解释是 :

The point on the image that will be placed at the LatLng position of the marker. This defaults to 50% from the left of the image and at the bottom of the image.

接着说说怎么利用方向传感器,在 Android 中,方位是通过加速度传感器和地磁传感器共同确定。

1sensorManager = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE); 2Sensor magnetic = null; 3if (sensorManager != null) { 4 magnetic = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); 5} 6Sensor acceleromter = null; 7if (sensorManager != null) { 8 acceleromter = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 9} 10if (sensorManager != null) { 11 sensorManager.registerListener(sensorEventListener, magnetic, SensorManager.SENSOR_DELAY_GAME); 12} 13if (sensorManager != null) { 14 sensorManager.registerListener(sensorEventListener, acceleromter, SensorManager.SENSOR_DELAY_GAME); 15}

在获取到传感器的数据后,可以获取用户此时旋转了多少度,然后再对 Marker 进行旋转。

1private SensorEventListener sensorEventListener = new SensorEventListener() { 2 @Override 3 public void onSensorChanged(SensorEvent event) { 4 5 } 6 @Override 7 public void onAccuracyChanged(Sensor sensor, int accuracy) { 8 } 9 };

我们的逻辑代码就写在 onSensorChanged 方法里,准备两个 float 类型的数据,分别存储地磁传感器和加速度传感器的数据。

1 float[] magneticValues = new float[3]; 2 float[] acceleromterValues = new float[3];

传感器的数据更新是非常快的,为了避免 Marker 旋转像是遇到了鬼一样,我们对时间间隔和更新角度信息做个显示,定义两个变量分别表示上次旋转的角度和上次传感器数据更新的时间。

1private float lastRotateDegree; 2private long lastUpdatetime;

将传感器数据赋值给数组:

1 // 判断数据来源于哪个传感器 2 if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { 3 acceleromterValues = event.values.clone(); 4 } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { 5 magneticValues = event.values.clone(); 6 }

为了得到传感器的航向角、俯仰角、横滚角等数据,我们需要计算一个旋转矩阵,不过 SensorManager 已经提供了,只需要调用就可以了,并用新的数组保存他们。

1float[] R = new float[9]; 2float[] values = new float[3]; 3SensorManager.getRotationMatrix(R, null, acceleromterValues, magneticValues); 4SensorManager.getOrientation(R, values);

接下来计算出旋转角度,并用 0~360° 表示。

1 float roteteDegree = -(float) Math.toDegrees(values[0]); 2 if (roteteDegree < 0) roteteDegree = 360 + roteteDegree; 3 if (roteteDegree < 0 || roteteDegree > 360) return;

计算本次旋转角度更新的度数,定义如果在 0.5°之间是属于抖动,直接过滤掉,不予更新。

1float offset = roteteDegree - lastRotateDegree; 2if (Math.abs(offset) < 0.5f) return;

在得到了 roteteDegree 的值后,就已经可以把角度传递给 Marker,Google Map Marker 中的 setRotation 方法可以让 Marker 进行旋转。

 gUserMarker.setRotation(roteteDegree);

好了,真机运行看看,emmm... Marker 的旋转十分奇怪啊,怎么以边界为原点进行旋转,而不是以中心点旋转,这就像一个圆形的门牌,最上面边缘的钉子掉了一样。这时再回顾看看 Marker 类中 Anchor,setAnchor 可以设定它的值,文档地址:

https://developers.google.com/android/reference/com/google/android/gms/maps/model/Marker?hl=zh-cn#setAnchor(float,%20float)

官方画了一个直击灵魂的图表示这个属性值是什么作用:

所以,给它设定 0.5,0.5 就圆点居中了,不信阔以试一试~

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Google Map 开发(二):根据方向传感器对 Marker 进行旋转 - HelloWorld