Android 两点之间的定位轴承+;地球曲率问题
我想实施三件事: 1) 基于位置传感器实现罗盘+获取当前坐标 2) 将方位设置为固定目的地 3) 一旦轴承设置,我想设置一个红色的指南针,将继续指向该固定轴承,无论手机旋转 到目前为止,我已经完成了1+2。至于3-我已经设法指向正确的方向针,但随着手机旋转-针也旋转,失去了正确的方向。我尝试了很多东西,但我就是不能让它工作 还有一个问题:如果bearingTo()方法计算两个位置之间的度数,它会考虑地球曲率吗?如果不是,这仅适用于近距离。。。希望如此:-) 我将感谢任何帮助 下面是我的代码检查注释以供解释。提前谢谢Android 两点之间的定位轴承+;地球曲率问题,android,location,bearing,Android,Location,Bearing,我想实施三件事: 1) 基于位置传感器实现罗盘+获取当前坐标 2) 将方位设置为固定目的地 3) 一旦轴承设置,我想设置一个红色的指南针,将继续指向该固定轴承,无论手机旋转 到目前为止,我已经完成了1+2。至于3-我已经设法指向正确的方向针,但随着手机旋转-针也旋转,失去了正确的方向。我尝试了很多东西,但我就是不能让它工作 还有一个问题:如果bearingTo()方法计算两个位置之间的度数,它会考虑地球曲率吗?如果不是,这仅适用于近距离。。。希望如此:-) 我将感谢任何帮助 下面是我的代码检查注
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
tvCurrAzim = (TextView) findViewById(R.id.tvaz);
tvCurrLat = (TextView) findViewById(R.id.tvlat);
tvCurrLng = (TextView) findViewById(R.id.tvlng);
tvBearing = (TextView) findViewById(R.id.tvbearing);
tvIndicator = (TextView) findViewById(R.id.tvindicator);
ivCompass = (ImageView) findViewById(R.id.imageView1); //compass ImageView
ivArrow = (ImageView) findViewById(R.id.imageView2); //Red Needle ImageView
// Get the location manager
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// Define the criteria how to select the location provider -> use
// default
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, true);
location = locationManager.getLastKnownLocation(provider);
tvCurrLat.setText(String.valueOf(location.getLatitude()));
tvCurrLng.setText(String.valueOf(location.getLongitude()));
from = new Location(location); //creating new Location object
to = new Location(location); //creating new Location object
//setting lat,lng to destination Location
to.setLatitude(newLat);
to.setLongitude(newLng);
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mCompass = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
}
// Compass Sensor Methods:
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
@Override
public void onSensorChanged(SensorEvent event) {
// setting animation for compass
azimuth = Math.round(event.values[0]);
tvCurrAzim.setText(Float.toString(azimuth));
// get the angle around the z-axis rotated
// float degree = Math.round(event.values[0]);
// create a rotation animation (reverse turn degree degrees)
RotateAnimation ra = new RotateAnimation(currentDegree, -azimuth,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
// how long the animation will take place
ra.setDuration(210);
// set the animation after the end of the reservation status
ra.setFillAfter(true);
// Start the animation
ivCompass.startAnimation(ra);
currentDegree = -azimuth;
pointArrow();
}
// Location Manager Methods:
public void setBearing() {
from.setLatitude(location.getLatitude()); //setting lat,lng to origin Location
from.setLongitude(location.getLongitude());
bearing = Math.round(from.bearingTo(to));
tvBearing.setText(String.valueOf(bearing));
hasBearing = true;
ivArrow.setVisibility(View.VISIBLE);
}
public void pointArrow() {
if (hasBearing) { //once bearing is set
// get the angle around the z-axis rotated
float degree1 = Math.round(azimuth) - (float) bearing;
// create a rotation animation (reverse turn degree degrees)
RotateAnimation ra1 = new RotateAnimation(currentDegree1, -degree1,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
// how long the animation will take place
ra1.setDuration(210);
// set the animation after the end of the reservation status
ra1.setFillAfter(true);
// Start the animation
ivArrow.startAnimation(ra1);
currentDegree1 = -degree1;
//THIS METHOD WORKS TO POINT THE NEEDLE IN CORRECT DIRECTION, BUT AS PHONE ROTATES THE NEEDLE ROTATES TOO.
//I WANT IT TO KEEP POINTING IN FIXED DIRECTION REGARDLESS OF PHONE ROTATION
}
}
@Override
public void onLocationChanged(Location location) {
tvCurrLat.setText(String.valueOf(location.getLatitude()));
tvCurrLng.setText(String.valueOf(location.getLongitude()));
setBearing();
locationManager.removeUpdates(this);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
protected void onPause() {
// Unregister the listener
super.onPause();
locationManager.removeUpdates(this);
mSensorManager.unregisterListener(this);
ivArrow.setVisibility(View.INVISIBLE);
}
@Override
protected void onResume() {
super.onResume();
locationManager.requestLocationUpdates(provider, 1000, 1, this);
mSensorManager.registerListener(this, mCompass,
SensorManager.SENSOR_DELAY_GAME);
}
Android docs说,
bearingTo()
使用WGS84椭球体,所以是的,它考虑了地球曲率
要使罗盘在设备旋转时保持稳定,使用位置传感器是不够的,还应使用磁场传感器。大多数安卓设备都有
您需要查看
SensorManager.getOrientation()
:谢谢您的回答。。你知道如何完成我在问题中提到的第三部分吗?谢谢@gilonm在textview tvCurrAzim中,当设备旋转时,文本是否会更改?@gilonm如果是,问题在于重新绘制指针,而不是获取设备方向…@gilonm为了使代码更清晰、可读且易于测试,请将与指向箭头相关的所有方法和属性集中在一个单独的类中。它应该存储arrow的当前旋转、角度和动画资源-因此在接收到新方向后,您只需调用定点arrow对象的更新方法,它就可以自己完成所有其他工作。@gilonm我制作了这样一个对象来处理方向更新,看一看