我的需求是在指南针模式下的Google maps Apps
(点击两次Current location button
时可以看到演示):
指南针
模式下,地图总是旋转一个角度,以便蓝点箭头
始终指向顶部屏幕。但我不知道如何计算正确的方位
从方位角,俯仰,滚动
值。
public void onSensorChanged(SensorEvent sensorEvent) {
switch (sensorEvent.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
System.arraycopy(sensorEvent.values, 0, mAccelerometers, 0, 3);
break;
case Sensor.TYPE_MAGNETIC_FIELD:
System.arraycopy(sensorEvent.values, 0, mMagnetometers, 0, 3);
break;
default:
break;
}
float[] rotationMatrix = new float[9];
boolean success =
SensorManager.getRotationMatrix(rotationMatrix, null, mAccelerometers, mMagnetometers);
if (success) {
SensorManager.getOrientation(rotationMatrix, mOrientation);
float azimuth = Math.toDegrees(mOrientation[0]);
float pitch = Math.toDegrees(mOrientation[1]);
float roll = Math.toDegrees(mOrientation[2]);
}
// cal to updateBearing();
}
在iOS中,clheading
可以返回真正的heading
。在android
中是否有一个类具有相同的特性,或者如何计算它?
方位角和位置是计算航向所需的唯一参数。
角度计算和转换的惯例是按以下顺序使用:
1)方位角
2)俯仰
3)滚转
检查下面的链接,查看您的问题轴承-示例
轴承-示例
下面的答案也与你的问题相似。
我如何得到正确的方位?
package ymc.ch.bearingexample;
import android.content.Context;
import android.hardware.GeomagneticField;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
/**
* Utility class that provides bearing values to true north.
*/
public class BearingToNorthProvider implements SensorEventListener, LocationListener
{
public static final String TAG = "BearingToNorthProvider";
/**
* Interface definition for a callback to be invoked when the bearing changes.
*/
public static interface ChangeEventListener {
/**
* Callback method to be invoked when the bearing changes.
* @param bearing the new bearing value
*/
void onBearingChanged(double bearing);
}
private final SensorManager mSensorManager;
private final LocationManager mLocationManager;
private final Sensor mSensorAccelerometer;
private final Sensor mSensorMagneticField;
// some arrays holding intermediate values read from the sensors, used to calculate our azimuth
// value
private float[] mValuesAccelerometer;
private float[] mValuesMagneticField;
private float[] mMatrixR;
private float[] mMatrixI;
private float[] mMatrixValues;
/**
* minimum change of bearing (degrees) to notify the change listener
*/
private final double mMinDiffForEvent;
/**
* minimum delay (millis) between notifications for the change listener
*/
private final double mThrottleTime;
/**
* the change event listener
*/
private ChangeEventListener mChangeEventListener;
/**
* angle to magnetic north
*/
private AverageAngle mAzimuthRadians;
/**
* smoothed angle to magnetic north
*/
private double mAzimuth = Double.NaN;
/**
* angle to true north
*/
private double mBearing = Double.NaN;
/**
* last notified angle to true north
*/
private double mLastBearing = Double.NaN;
/**
* Current GPS/WiFi location
*/
private Location mLocation;
/**
* when we last dispatched the change event
*/
private long mLastChangeDispatchedAt = -1;
/**
* Default constructor.
*
* @param context Application Context
*/
public BearingToNorthProvider(Context context) {
this(context, 10, 0.5, 50);
}
/**
* @param context Application Context
* @param smoothing the number of measurements used to calculate a mean for the azimuth. Set
* this to 1 for the smallest delay. Setting it to 5-10 to prevents the
* needle from going crazy
* @param minDiffForEvent minimum change of bearing (degrees) to notify the change listener
* @param throttleTime minimum delay (millis) between notifications for the change listener
*/
public BearingToNorthProvider(Context context, int smoothing, double minDiffForEvent, int throttleTime)
{
mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
mSensorAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
mSensorMagneticField = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
mValuesAccelerometer = new float[3];
mValuesMagneticField = new float[3];
mMatrixR = new float[9];
mMatrixI = new float[9];
mMatrixValues = new float[3];
mMinDiffForEvent = minDiffForEvent;
mThrottleTime = throttleTime;
mAzimuthRadians = new AverageAngle(smoothing);
}
//==============================================================================================
// Public API
//==============================================================================================
/**
* Call this method to start bearing updates.
*/
public void start()
{
mSensorManager.registerListener(this, mSensorAccelerometer, SensorManager.SENSOR_DELAY_UI);
mSensorManager.registerListener(this, mSensorMagneticField, SensorManager.SENSOR_DELAY_UI);
for (final String provider : mLocationManager.getProviders(true)) {
if (LocationManager.GPS_PROVIDER.equals(provider)
|| LocationManager.PASSIVE_PROVIDER.equals(provider)
|| LocationManager.NETWORK_PROVIDER.equals(provider)) {
if (mLocation == null) {
mLocation = mLocationManager.getLastKnownLocation(provider);
}
mLocationManager.requestLocationUpdates(provider, 0, 100.0f, this);
}
}
}
/**
* call this method to stop bearing updates.
*/
public void stop()
{
mSensorManager.unregisterListener(this, mSensorAccelerometer);
mSensorManager.unregisterListener(this, mSensorMagneticField);
mLocationManager.removeUpdates(this);
}
/**
* @return current bearing
*/
public double getBearing()
{
return mBearing;
}
/**
* Returns the bearing event listener to which bearing events must be sent.
* @return the bearing event listener
*/
public ChangeEventListener getChangeEventListener()
{
return mChangeEventListener;
}
/**
* Specifies the bearing event listener to which bearing events must be sent.
* @param changeEventListener the bearing event listener
*/
public void setChangeEventListener(ChangeEventListener changeEventListener)
{
this.mChangeEventListener = changeEventListener;
}
//==============================================================================================
// SensorEventListener implementation
//==============================================================================================
@Override
public void onSensorChanged(SensorEvent event)
{
switch (event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
System.arraycopy(event.values, 0, mValuesAccelerometer, 0, 3);
break;
case Sensor.TYPE_MAGNETIC_FIELD:
System.arraycopy(event.values, 0, mValuesMagneticField, 0, 3);
break;
}
boolean success = SensorManager.getRotationMatrix(mMatrixR, mMatrixI,
mValuesAccelerometer,
mValuesMagneticField);
// calculate a new smoothed azimuth value and store to mAzimuth
if (success) {
SensorManager.getOrientation(mMatrixR, mMatrixValues);
mAzimuthRadians.putValue(mMatrixValues[0]);
mAzimuth = Math.toDegrees(mAzimuthRadians.getAverage());
}
// update mBearing
updateBearing();
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) { }
//==============================================================================================
// LocationListener implementation
//==============================================================================================
@Override
public void onLocationChanged(Location location)
{
// set the new location
this.mLocation = location;
// update mBearing
updateBearing();
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) { }
@Override
public void onProviderEnabled(String s) { }
@Override
public void onProviderDisabled(String s) { }
//==============================================================================================
// Private Utilities
//==============================================================================================
private void updateBearing()
{
if (!Double.isNaN(this.mAzimuth)) {
if(this.mLocation == null) {
Log.w(TAG, "Location is NULL bearing is not true north!");
mBearing = mAzimuth;
} else {
mBearing = getBearingForLocation(this.mLocation);
}
// Throttle dispatching based on mThrottleTime and minDiffForEvent
if( System.currentTimeMillis() - mLastChangeDispatchedAt > mThrottleTime &&
(Double.isNaN(mLastBearing) || Math.abs(mLastBearing - mBearing) >= mMinDiffForEvent)) {
mLastBearing = mBearing;
if(mChangeEventListener != null) {
mChangeEventListener.onBearingChanged(mBearing);
}
mLastChangeDispatchedAt = System.currentTimeMillis();
}
}
}
private double getBearingForLocation(Location location)
{
return mAzimuth + getGeomagneticField(location).getDeclination();
}
private GeomagneticField getGeomagneticField(Location location)
{
GeomagneticField geomagneticField = new GeomagneticField(
(float)location.getLatitude(),
(float)location.getLongitude(),
(float)location.getAltitude(),
System.currentTimeMillis());
return geomagneticField;
}
}
我正在尝试匹配从服务器下载的文件的md5sum。只有当总和匹配时,处理才会继续。 上面的代码并没有每次为某些文件正确提供md5sum。 当我去控制台检查md5sum时 下载文件的vimdiff未提供任何差异。。下载后的文件是正确的。 我无法在上述代码中看到问题。 我正在尝试更改缓冲区大小。但没有运气,所以我猜这不是因为缓冲区大小等。 问候Dheeraj Joshi
我在一个项目中工作,其中在线考试是一个部分,我做这为我的SEM。考试。我正在创建一个在线考试系统(项目的一部分),在那里我可以从数据库中提取问题和答案,但我不能计算正确的答案。我需要帮助。任何帮助都将非常感谢,因为我需要尽快做这件事。 编码是使用jsp scriplet代码来获取数据的: 现在代码看看正确的答案。这里我卡住了... 我可以看到在jsp页面中选择的数据,也可以看到正确的ans,但在计
问题内容: 我遇到了一个问题,我正在开发一个应该能够进行一些数学计算的应用程序。这些计算必须是准确的(或者显然不是错误的) 但是这个简单的代码 给我一个错误的结果c不是预期的0.003048而是0.0030480000000000004这显然是错误的。 第二个代码片段给出了正确的结果。 我知道在使用计算机进行计算时,并不是所有的浮点运算都是精确的,但是我不知道如何解决这个问题。 提前致谢! 路德维
我需要阅读由AutoCAD导出为PDF的平面图,并使用PDFBox在上面放置一些带有文本的标记。除了文字宽度的计算之外,一切都很顺利,文字的宽度写在标记旁边。 我浏览了整个PDF规范,详细阅读了其中涉及图形和文本的部分,但没有任何效果。据我所知,字形坐标空间设置在用户坐标空间的1/1000处。因此,宽度需要放大1000倍,但仍然是实际宽度的一小部分。 这就是我为定位文本所做的: *0.043f可以
晚上好!我是一名律师,我经常要计算被判刑的人多久才能获得福利,比如假释。 它的工作原理如下: 首先,我需要得到一些主要变量,比如那个人开始服刑的那一天(他被捕的那一天)。这将是第一项福利的基准日期。假设有人在2014年11月12日被捕。 我必须做的第二件事是知道每项罪行的判决是什么(有时这个人被判犯有不止一项罪行,对于每项罪行,都有不同的计算方法。假设这个人被判犯有两项罪行: 对于第一项罪行(这是