I'm developing an android application where I want the compass to point to a particular latitude longitude position instead of the usual north location. Can anyone suggest how to implement this. I've developed an application which points to north direction.
Thanks in advance in how to implement this. Any demo application which does this would be of great help.
How to make compass point to my particular latitude longitude location based on my current location?
Asked
Active
Viewed 6,979 times
2
1 Answers
3
You can implement simple compass from here. It obviously pointing to north, but in order to make compass points to certain location or coordinates you can do some thing like this.
Add this method in your activity, it finds the bearing between two coordinates.
protected double bearing(double startLat, double startLng, double endLat, double endLng){
double longitude1 = startLng;
double longitude2 = endLng;
double latitude1 = Math.toRadians(startLat);
double latitude2 = Math.toRadians(endLat);
double longDiff= Math.toRadians(longitude2-longitude1);
double y= Math.sin(longDiff)*Math.cos(latitude2);
double x=Math.cos(latitude1)*Math.sin(latitude2)-Math.sin(latitude1)*Math.cos(latitude2)*Math.cos(longDiff);
return (Math.toDegrees(Math.atan2(y, x))+360)%360;
}
In onSensorChanged Method in Compass Class, do this
azimuth -= bearing(yourlatitude, yourlongitude, latWhereToPoint, lngWhereToPoint);
latitude, longitude -> your current latitude, longitude latWhereToPoint, lngWheretoPoint -> location where you wants to point.
In the End your onSensorChanged would be like this.
@Override
public void onSensorChanged(SensorEvent event) {
final float alpha = 0.97f;
synchronized (this) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
mGravity[0] = alpha * mGravity[0] + (1 - alpha)
* event.values[0];
mGravity[1] = alpha * mGravity[1] + (1 - alpha)
* event.values[1];
mGravity[2] = alpha * mGravity[2] + (1 - alpha)
* event.values[2];
// mGravity = event.values;
// Log.e(TAG, Float.toString(mGravity[0]));
}
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
// mGeomagnetic = event.values;
mGeomagnetic[0] = alpha * mGeomagnetic[0] + (1 - alpha)
* event.values[0];
mGeomagnetic[1] = alpha * mGeomagnetic[1] + (1 - alpha)
* event.values[1];
mGeomagnetic[2] = alpha * mGeomagnetic[2] + (1 - alpha)
* event.values[2];
// Log.e(TAG, Float.toString(event.values[0]));
}
float R[] = new float[9];
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mGravity,
mGeomagnetic);
if (success) {
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);
// Log.d(TAG, "azimuth (rad): " + azimuth);
azimuth = (float) Math.toDegrees(orientation[0]); // orientation
azimuth = (azimuth + 360) % 360;
azimuth -= bearing(yourlatitude, yourlongitude, latWhereToPoint, lngWhereToPoint);
// Log.d(TAG, "azimuth (deg): " + azimuth);
adjustArrow();
}
}
}

Asad Haider
- 504
- 1
- 5
- 17
-
Bearing method is the best version I found so far. I found it not be 100% accurate. You should really round results to 0 precision numbers because it is not accurate when it comes to fractions of degree. Better have it integer. – Stan Sokolov Jun 21 '18 at 21:43