밍쎄의 코딩공간

스크랩 17 - SQLite에서 일정거리내의 위치 Query 본문

스크랩

스크랩 17 - SQLite에서 일정거리내의 위치 Query

밍쎄 2023. 8. 26. 15:55

SQLite에 좌표값 (위도, 경도)이 저장되어있는 경우, 쿼리를 통해 현재 위치에서 일정 거리내의 위치값을 갖는 데이터를 가져오기 위한 방법.

 

이를 위한 공식은 다음과 같다.

 

distance = 6371 * acos cos rad lat1 ) * cos rad lat2 )

    * cos ( rad ( lng2 ) - rad lng1 ) ) 
    + sin ( rad lat1 ) ) * sin ( rad ( lat2 ) ) )

 

acos 내부의 식을 x라고 한다면

 

distance = 6371 * acos(x)

acos(x) = distance/6371

x = cos(distance/6371) 이다.

 

그리고 x식을 사용하기 위해서 cos(x-y) = cos x cos y + sin x sin y 공식을 이용하면

 

x = cos rad lat1 ) * cos rad lat2 ) 

* cos ( rad ( lng2 ) - rad lng1 ) ) 

     + sin ( rad lat1 ) ) * sin ( rad ( lat2 ) ) 

  = cos ( rad lat1 ) ) * cos ( rad lat2 ) ) 

* ( cos( rad lng2 ) ) * cos( rad lng1 ) ) + sin( rad lng2 ) ) * sin( rad lng1 ))) 

+ sin ( rad lat1 ) ) * sin( rad lat2 ) )

 

으로 변환할 수 있다.

 

 

위의 공식을 코드로 구현한다면 다음과 같다.

 

 

1. SQLite Insert

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public void addData(MyData data) {
 
        SQLiteDatabase db = this.getWritableDatabase();
 
        double lat = data.getLatitude();
        double lng = data.getLongitude();
 
        ContentValues values = new ContentValues();
        values.put(LATITUDE, lat);
        values.put(LONGITUDE, lng);
        values.put(SIN_LATITUDE, Math.sin(Math.toRadians(lat)));
        values.put(SIN_LONGITUDE, Math.sin(Math.toRadians(lng)));
        values.put(COS_LATITUDE, Math.cos(Math.toRadians(lat)));
        values.put(COS_LONGITUDE, Math.cos(Math.toRadians(lng)));
 
        db.insert(TABLE_MYDATA, null, values);
        db.close();
}
cs

 

위와 같이 위도,경도 값의 sin, cos값을 함께 DB에 넣어준다.

 

 

 

2. 계산식 생성

 

1
2
3
4
5
6
7
8
9
10
11
12
13
private String buildDistanceQuery(double latitude, double longitude) {
 
        final double sinLat = Math.sin(Math.toRadians(latitude));
        final double cosLat = Math.cos(Math.toRadians(latitude));
        final double sinLng = Math.sin(Math.toRadians(longitude));
        final double cosLng = Math.cos(Math.toRadians(longitude));
 
        return "(" + cosLat + "*" + COS_LATITUDE
                + "*(" + COS_LONGITUDE + "*" + cosLng
                + "+" + SIN_LONGITUDE + "*" + sinLng
                + ")+" + sinLat + "*" + SIN_LATITUDE 
                + ")";        
}
cs

 

위에서 설명한 x에 해당하는 식을 생성

 

 

 

3. 일정 거리내의 데이터리스트를 반환

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public List<MyData> getList(double latitude, double longitude, double distance) {
 
    List<MyData> dataList = new ArrayList<MyData>();
 
    String selectQuery = "SELECT *" + ", " + buildDistanceQuery(latitude, longitude)
                + " AS partial_distance"
                + " FROM " + TABLE_MYDATA
                + " WHERE partial_distance >= " 
                + Math.cos(distance/6371);                
 
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.rawQuery(selectQuery, null);
 
    if(cursor.moveToFirst()) {
        do {        
 
            MyData data = new MyData(cursor.getInt(0), cursor.getDouble(1), cursor.getDouble(2));
            dataList.add(data);    
 
        } while(cursor.moveToNext());
    }
 
    return dataList;
}    
cs

 

(distance의 단위는 km)

 


출처 

https://king24.tistory.com/4

 

[Android] SQLite에서 일정거리내의 위치 Query (위도,경도)

SQLite에 좌표값 (위도, 경도)이 저장되어있는 경우, 쿼리를 통해 현재 위치에서 일정 거리내의 위치값을 갖는 데이터를 가져오기 위한 방법. 이를 위한 공식은 다음과 같다. distance = 6371 * acos ( cos

king24.tistory.com

 

728x90