밍쎄의 코딩공간
스크랩 17 - SQLite에서 일정거리내의 위치 Query 본문
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)
출처
[Android] SQLite에서 일정거리내의 위치 Query (위도,경도)
SQLite에 좌표값 (위도, 경도)이 저장되어있는 경우, 쿼리를 통해 현재 위치에서 일정 거리내의 위치값을 갖는 데이터를 가져오기 위한 방법. 이를 위한 공식은 다음과 같다. distance = 6371 * acos ( cos
king24.tistory.com
'스크랩' 카테고리의 다른 글
스크랩 18 - 신입 개발자의 첫 홀로서기 (0) | 2023.08.27 |
---|---|
스크랩 16. Spring Transaction 관리 (0) | 2023.08.24 |
스크랩 15. 개발자가 맥북을 사용하는 이유 (3) | 2023.08.22 |
스크랩 14. 개발자의 영어공부 (0) | 2023.08.19 |
스크랩 13. 신입 서버 개발자의 1인분 해내기 (0) | 2023.08.18 |