0

나는 이슬람 안드로이드 앱에서 구현하고자하는 보편적 인 qibla 방향 논리를 매우 알고 싶어한다. 방금 영국인, 미국인, 인도인, 스리랑카 또는 기타 지역에 거주하고 있는지 여부에 상관없이 그 사람의 qibla 방향을 찾고자하는 위도와 경도에 상관없이 사용자의 위도와 경도를 얻었습니다. qibla 방향 찾기를위한 유니버설 로직

나는이 공식을 발견하고, 그것이 어떻게 작동하는지 정확히 모른다 :

float lonDelta = (lon2 - lon1); 
float y = Math.sin(lonDelta) * Math.cos(lat2); 
float x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lonDelta); 
float brng = Math.atan2(y, x).toDeg(); 

정확한 공식을 알고 저를 도와주세요.

답변

0

올바른 qibla 방향을 얻으려면 다음 방법을 사용하십시오.

public double calculateQibla(double latitude, double longitude){ 
    double phiK = 21.4 * Math.PI/180.0; 
    double lambdaK = 39.8 * Math.PI/180.0; 
    double phi = latitude*Math.PI/180.0; 
    double lambda = longitude*Math.PI/180.0; 
    double psi = 180.0/Math.PI * Math.atan2(Math.sin(lambdaK-lambda),Math.cos(phi)*Math.tan(phiK)-Math.sin(phi)*Math.cos(lambdaK-lambda)); 
    return Math.round(psi); 
} 

희망 하시겠습니까?

+0

어떤 값을 반환 않습니다 여기에있다? –

+0

은 Kaaba에게 베어링을 반환합니다. – jack

0

어쨌든 사용자의 위치를 ​​먼저 결정해야하므로 Location 개체가 있습니다.

Location 개체는 다른 Location 개체를 매개 변수로 사용하는 bearingTo() 메서드를가집니다. 그것은 메카의 카바 (Kaaba) 좌표입니다. (I 이해했듯이.)

당신이 원하는 사용할 수 있습니다.

Location kaabaLocation = new Location(""); 
kaabaLocation.setLatitude(21.4225); 
kaabaLocation.setLongitude(39.8262); 
float kaabaBearing = userLocation.bearingTo(kaabaLocation); 

그래서 안드로이드는 이미 수학이 내장되어

1

대신이 공식

float lonDelta = (lon2 - lon1); 
float y = Math.sin(lonDelta) * Math.cos(lat2); 
float x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lonDelta); 
float brng = Math.atan2(y, x).toDeg(); 

를 사용하여 이런 식으로 베어링을 간단하게 사용할 수 있습니다.

Location userLoc=new Location("service Provider"); 
    //get longitudeM Latitude and altitude of current location with gps class and set in userLoc 
    userLoc.setLongitude(longitude); 
    userLoc.setLatitude(latitude); 
    userLoc.setAltitude(altitude); 

    Location destinationLoc = new Location("service Provider"); 
    destinationLoc.setLatitude(21.422487); //kaaba latitude setting 
    destinationLoc.setLongitude(39.826206); //kaaba longitude setting 
    float bearTo=userLoc.bearingTo(destinationLoc); 

bearingTo는 -180부터 180까지의 범위를 제공하므로 약간 혼란 스럽습니다. 올바른 회전을 얻으려면이 값을 0에서 360 범위로 변환해야합니다.

그래서 우리는 당신이 SensorEventListener를 구현해야 할 bearTo

// If the bearTo is smaller than 0, add 360 to get the rotation clockwise. 

    if (bearTo < 0) { 
    bearTo = bearTo + 360; 
    //bearTo = -100 + 360 = 260; 
} 

후이 코드를 추가해야하고 bearingTo 우리에게

+-----------+--------------+ 
| bearingTo | Real bearing | 
+-----------+--------------+ 
| 0   | 0   | 
+-----------+--------------+ 
| 90  | 90   | 
+-----------+--------------+ 
| 180  | 180   | 
+-----------+--------------+ 
| -90  | 270   | 
+-----------+--------------+ 
| -135  | 225   | 
+-----------+--------------+ 
| -180  | 180   | 
+-----------+--------------+ 

를주는 무슨에 비해, 우리가 정말 원하는 것을 테이블입니다 그 기능 (onSensorChanged, onAcurracyChabge) onSensorChanged 안에 모든 코드를 작성하십시오.

전체 코드는 여기에서 있습니다. F의 Qibla 나침반

public class QiblaDirectionCompass extends Service implements SensorEventListener{ 
public static ImageView image,arrow; 

// record the compass picture angle turned 
private float currentDegree = 0f; 
private float currentDegreeNeedle = 0f; 
Context context; 
Location userLoc=new Location("service Provider"); 
// device sensor manager 
private static SensorManager mSensorManager ; 
private Sensor sensor; 
public static TextView tvHeading; 
    public QiblaDirectionCompass(Context context, ImageView compass, ImageView needle,TextView heading, double longi,double lati,double alti) { 

    image = compass; 
    arrow = needle; 


    // TextView that will tell the user what degree is he heading 
    tvHeading = heading; 
    userLoc.setLongitude(longi); 
    userLoc.setLatitude(lati); 
    userLoc.setAltitude(alti); 

    mSensorManager = (SensorManager) context.getSystemService(SENSOR_SERVICE); 
    sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); 
    if(sensor!=null) { 
     // for the system's orientation sensor registered listeners 
     mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_GAME);//SensorManager.SENSOR_DELAY_Fastest 
    }else{ 
     Toast.makeText(context,"Not Supported", Toast.LENGTH_SHORT).show(); 
    } 
    // initialize your android device sensor capabilities 
this.context =context; 
@Override 
public void onCreate() { 
    // TODO Auto-generated method stub 
    Toast.makeText(context, "Started", Toast.LENGTH_SHORT).show(); 
    mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_GAME); //SensorManager.SENSOR_DELAY_Fastest 
    super.onCreate(); 
} 

@Override 
public void onDestroy() { 
    mSensorManager.unregisterListener(this); 
Toast.makeText(context, "Destroy", Toast.LENGTH_SHORT).show(); 

    super.onDestroy(); 

} 
@Override 
public void onSensorChanged(SensorEvent sensorEvent) { 

float degree = Math.round(sensorEvent.values[0]); 
float head = Math.round(sensorEvent.values[0]); 
float bearTo; 
Location destinationLoc = new Location("service Provider"); 

destinationLoc.setLatitude(21.422487); //kaaba latitude setting 
destinationLoc.setLongitude(39.826206); //kaaba longitude setting 
float bearTo=userLoc.bearingTo(destinationLoc); 

    //bearTo = The angle from true north to the destination location from the point we're your currently standing.(asal image k N se destination taak angle) 

    //head = The angle that you've rotated your phone from true north. (jaise image lagi hai wo true north per hai ab phone jitne rotate yani jitna image ka n change hai us ka angle hai ye) 



GeomagneticField geoField = new GeomagneticField(Double.valueOf(userLoc.getLatitude()).floatValue(), Double 
     .valueOf(userLoc.getLongitude()).floatValue(), 
     Double.valueOf(userLoc.getAltitude()).floatValue(), 
     System.currentTimeMillis()); 
head -= geoField.getDeclination(); // converts magnetic north into true north 

if (bearTo < 0) { 
    bearTo = bearTo + 360; 
    //bearTo = -100 + 360 = 260; 
} 

//This is where we choose to point it 
float direction = bearTo - head; 

// If the direction is smaller than 0, add 360 to get the rotation clockwise. 
if (direction < 0) { 
    direction = direction + 360; 
} 
tvHeading.setText("Heading: " + Float.toString(degree) + " degrees"); 

RotateAnimation raQibla = new RotateAnimation(currentDegreeNeedle, direction, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); 
raQibla.setDuration(210); 
raQibla.setFillAfter(true); 

arrow.startAnimation(raQibla); 

currentDegreeNeedle = direction; 

// create a rotation animation (reverse turn degree degrees) 
RotateAnimation ra = new RotateAnimation(currentDegree, -degree, 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 
image.startAnimation(ra); 

currentDegree = -degree; 
} 
@Override 
public void onAccuracyChanged(Sensor sensor, int i) { 

} 
@Nullable 
@Override 
public IBinder onBind(Intent intent) { 
    return null; 
} 

XML 코드는 마지막으로

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:background="@drawable/flag_pakistan"> 
<TextView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:id="@+id/heading" 
    android:textColor="@color/colorAccent" 
    android:layout_centerHorizontal="true" 
    android:layout_marginBottom="100dp" 
    android:layout_marginTop="20dp" 
    android:text="Heading: 0.0" /> 
<RelativeLayout 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:layout_below="@+id/heading" 
android:scaleType="centerInside" 
android:layout_centerVertical="true" 
android:layout_centerHorizontal="true"> 

<ImageView 
    android:id="@+id/imageCompass" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:scaleType="centerInside" 
    android:layout_centerVertical="true" 
    android:layout_centerHorizontal="true" 
    android:src="@drawable/images_compass"/> 

<ImageView 
    android:id="@+id/needle" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_centerVertical="true" 
    android:layout_centerHorizontal="true" 
    android:scaleType="centerInside" 
    android:src="@drawable/arrow2"/> 
</RelativeLayout> 
</RelativeLayout> 
+0

tvHeading.setText ("Heading :"+ Float.toString (degrees) + "degrees"); 여기 학위는 뭐니? 당신은 어디에도 선언하지 않았습니다! – Husnain

+0

코드가 편집되었습니다. –

+0

Kashif Bro, 어디에서 QiblaDirectionCompas를 호출 했습니까 ?? 뭔가 놓친거야? 또는 다른 clas ?? 그렇다면..그런 다음 여기에 게시하십시오. –