android пример Вычислить расстояние между двумя точками непосредственно в SQLite




sqlite insert android (3)

В моем приложении 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, радианы, грех) не существуют. Есть ли что-то эквивалентное мне для вычисления расстояния непосредственно в базе данных?

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

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

ОБНОВИТЬ

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


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

См. Эту ссылку


Вставьте 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());

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

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

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

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

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

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

Другой подход

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

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





math