Вопрос по sqlite, android, math – Рассчитать расстояние между двумя точками непосредственно в SQLite

8

В моем приложении web / MySQL у меня есть что-то вроде этого, чтобы получить расстояние между двумя точками:

6371 * acos(cos(radians(-19.83996)) * cos(radians(lat)) * cos(radians(-43.94910) - radians(lng)) + sin(radians(-19.83996)) * sin(radians(lat)))

Но я тестировал в SQLite и этих математических функций (acos, cos, радианы, sin) не существует. Есть ли что-то эквивалентное для меня, чтобы рассчитать расстояние непосредственно в базе данных?

Тем не менее, у меня есть приложение для iPhone, которое используетЭтот метод вычислять. Работает отлично, но теперь мне нужно выполнить этот же поиск в базе данных в приложении для Android.

Заранее спасибо.

UPDATE

У меня есть 9000 точек, чтобы рассчитать расстояние и получить 5 близлежащих местоположений данной точки.

Мне нужно 5 ближайших пунктов. Я использовал расстояние, потому что я думал, что это необходимо дляorder by а такжеlimit. Paulo Rodrigues
Вам действительно нужны расстояния или только 5 ближайших точек? reinierpost
Я не понимаю, что вы имеете в виду, когда говорите & apos; Я тестировал в SQLite, и эти математические функции (acos, cos, радианы, sin) не существуют. & Apos; DGomez
Извините, я имел в виду, что когда я запускаю этот код, я получаю сообщение "Ошибка: нет такой функции: acos" Paulo Rodrigues

Ваш Ответ

4   ответа
-3

нам нужно инициализировать класс location, и в нем у нас есть метод distanceBetween (), который дает расстояние между двумя геопоинтами.

Отослать этоССЫЛКА НА САЙТ

Error: User Rate Limit Exceeded Paulo Rodrigues
0

Ответ Angel не решает проблему для SQLite, поскольку он все еще включает функцию ACOS, которой нет в SQLite

После тщательного исследования я пришел к выводу, что следует выбрать приблизительную оценку для использования в SQLite по следующей формуле:

Оценка расстояния для км:

SQRT(SQUARE((TO_LAT-FROM_LAT)*110)+
     SQUARE((TO_LONG-FROM_LONG)*COS(TO_LAT)*111)) 
6

Вот что я бы сделал:

Возьмите свое мнение. Измерьте a (это произвольное значение, подлежащее уточнению) ~ 2 км в ширину вокруг него и возьмите значения для границ восток / запад / север / юг.

Сделайте запрос для элементов внутри этого квадрата. Это легко, вам просто нужно

select * from points where lat between ? and ? and lon between ? and ?

Посчитай свой результат. Недостаточно результата (очевидно, меньше 5, но я бы сказал, что вдвое больше), повторите попытку с большим радиусом. Слишком много (скажем, более 100), попробуйте еще раз с меньшим радиусом.

Когда у вас будет достаточно, загрузите их, убедитесь, что все 5 необходимых вам элементов находятся не только в квадрате шириной X км, но и в круге радиуса X км (чтобы избежать обнаружения потенциального элемента ближе в предыдущем приближении).

Another approach

Действителен только в том случае, если ваша точка зрения относительно близка к тем, которые вы ищете.

Измерьте локальное приближение плоской земли. Рядом с вашей точкой вы можете рассмотреть линейную зависимость между широтой, долготой и расстоянием. Это позволяет сделать запрос, отсортированный по простому исчислению. (умножение и сложение). Опять же, выберите немного больше точек, чтобы сделать правильный расчет после запроса SQLite.

Error: User Rate Limit Exceeded Paulo Rodrigues
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Paulo Rodrigues
3

Вставьте cos_lat_rad, sin_lat_rad, cos_lon_rad, sin_lon_rad в свой стол

contentValues.put("cos_lat_rad", Math.cos(deg2rad(latitude)));
contentValues.put("sin_lat_rad", Math.sin(deg2rad(latitude)));
contentValues.put("cos_lon_rad", Math.cos(deg2rad(longitude)));
contentValues.put("sin_lon_rad", Math.sin(deg2rad(longitude)));

градус в радиан

public static double deg2rad(double deg) {
    return (deg * Math.PI / 180.0);
}

запрос, расстояние в км

 Cursor c=database.dis(String.valueOf(Math.cos((double) distance / (double) 6380)), Math.cos(deg2rad(latitude)), Math.sin(deg2rad(latitude)), Math.cos(deg2rad(longitude)), Math.sin(deg2rad(longitude)));

запрос

public Cursor dis(String dis, double cos_lat_rad, double sin_lat_rad, double cos_lon_rad, double sin_lon_rad) {

    Cursor cursor = sqLiteDatabase.rawQuery("SELECT * ,(" + sin_lat_rad + "*\"sin_lat_rad\"+" + cos_lat_rad + "*\"cos_lat_rad\"*(" + sin_lon_rad + "*\"sin_lon_rad\"+" + cos_lon_rad + "*\"cos_lon_rad\")) AS \"distance_acos\" FROM parish WHERE ("+sin_lat_rad+" * \"sin_lat_rad\" +"+ cos_lat_rad +"* \"cos_lat_rad\" * (+"+sin_lon_rad +"* \"sin_lon_rad\" + "+cos_lon_rad +"* \"cos_lon_rad\")) >"+dis+ " ORDER BY \"distance_acos\" DESC ", null);
    return cursor;

}

преобразовать distance_acos в км

 if(c.moveToFirst())
        do {
            double distance_acos= c.getDouble(c.getColumnIndex("distance_acos"));
                     String Distance=String.valueOf(Math.acos(distance_acos) * 6380); 
        }while (c.moveToNext());

Похожие вопросы