본문 바로가기
안드로이드 자바

[ Android][Java] 두 좌표(위도, 경도)간 거리 구하기

by teamnova 2023. 5. 19.
728x90

지도를 이용한 서비스 혹은 유저의 위치를 기반해 서비스를 만들다 보면 좌표간 거리를 구해야하는일이 있습니다. 

 

오늘은 이런 경우 사용할 수 있는 두 지점간의 거리를 구하는 함수를 예제로 만들어 보았습니다. 

 

Math 클래스를 이용한 방법과 

안드로이드 내부 Location 

 

다음은 두 지점의 위도 경도를 입력하면 두 지점간의 거리를 m 단위로 반환해 주는 함수 입니다.

public double DistanceByDegree(double _latitude1, double _longitude1, double _latitude2, double _longitude2){
    double theta, dist;
    theta = _longitude1 - _longitude2;
    dist = Math.sin(DegreeToRadian(_latitude1)) * Math.sin(DegreeToRadian(_latitude2)) + Math.cos(DegreeToRadian(_latitude1))
            * Math.cos(DegreeToRadian(_latitude2)) * Math.cos(DegreeToRadian(theta));
    dist = Math.acos(dist);
    dist = RadianToDegree(dist);

    dist = dist * 60 * 1.1515;
    dist = dist * 1.609344;    // 단위 mile 에서 km 변환.
    dist = dist * 1000.0;      // 단위  km 에서 m 로 변환

    return dist;
}

    //degree->radian 변환
    public double DegreeToRadian(double degree){
        return degree * Math.PI / 180.0;
    }

    //randian -> degree 변환
    public double RadianToDegree(double radian){
        return radian * 180d / Math.PI;
    }

같은 작업을 하는 함수 이지만 안드로이드 내부 Location class 를 이용한 메서드 입니다. 

//안드로이드 - 두지점(위도,경도) 사이의 거리
public double DistanceByDegreeAndroid(double _latitude1, double _longitude1, double _latitude2, double _longitude2){
    Location startPos = new Location("PointA");
    Location endPos = new Location("PointB");

    startPos.setLatitude(_latitude1);
    startPos.setLongitude(_longitude1);
    endPos.setLatitude(_latitude2);
    endPos.setLongitude(_longitude2);

    double distance = startPos.distanceTo(endPos);

    return distance;
}

안드로이드 에서 임의의 두 위치의 거리를 위 함수를 이용해 출력해 보겠습니다. 

 

MainActivity

public class MainActivity extends AppCompatActivity {


    //UI
    TextView txtJava;
    TextView txtAndroid;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //UI
        txtJava = (TextView)findViewById(R.id.txtJava);
        txtAndroid = (TextView)findViewById(R.id.txtAndroid);

        txtJava.setText(DistanceByDegree(37.476780, 126.981429, 37.504445, 127.049317)+"m");
        txtAndroid.setText(DistanceByDegreeAndroid(37.476780, 126.981429, 37.504445, 127.049317)+"m");
    }

    //두지점(위도,경도) 사이의 거리
    public double DistanceByDegree(double _latitude1, double _longitude1, double _latitude2, double _longitude2){
        double theta, dist;
        theta = _longitude1 - _longitude2;
        dist = Math.sin(DegreeToRadian(_latitude1)) * Math.sin(DegreeToRadian(_latitude2)) + Math.cos(DegreeToRadian(_latitude1))
                * Math.cos(DegreeToRadian(_latitude2)) * Math.cos(DegreeToRadian(theta));
        dist = Math.acos(dist);
        dist = RadianToDegree(dist);

        dist = dist * 60 * 1.1515;
        dist = dist * 1.609344;    // 단위 mile 에서 km 변환.
        dist = dist * 1000.0;      // 단위  km 에서 m 로 변환

        return dist;
    }

    //안드로이드 - 두지점(위도,경도) 사이의 거리
    public double DistanceByDegreeAndroid(double _latitude1, double _longitude1, double _latitude2, double _longitude2){
        Location startPos = new Location("PointA");
        Location endPos = new Location("PointB");

        startPos.setLatitude(_latitude1);
        startPos.setLongitude(_longitude1);
        endPos.setLatitude(_latitude2);
        endPos.setLongitude(_longitude2);

        double distance = startPos.distanceTo(endPos);

        return distance;
    }

    //degree->radian 변환
    public double DegreeToRadian(double degree){
        return degree * Math.PI / 180.0;
    }

    //randian -> degree 변환
    public double RadianToDegree(double radian){
        return radian * 180d / Math.PI;
    }

}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:text="(37.476780, 126.981429) 와 (37.504445, 127.049317) 사이의 거리"
        android:textSize="24dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/txtJava"
        android:textSize="24dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/txtAndroid"
        android:textSize="24dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

결과값

위와 같이 계산결과가 나오는것을 확인할 수 있습니다. 

두 방식에 있어서 계산오차가 조금 있는것 같으니 이부분은 두 방식중 본인의 서비스에서 오차가 적은 방식으로 선택하여 사용하면 될듯 합니다.