Android sqlite сортировать по вычисляемому столбцу (расстояние координат) - PullRequest
4 голосов
/ 09 января 2010

Я использую базу данных SQLITE для хранения широт и долгот местоположений.

Я хочу иметь возможность сортировать результаты по приблизительному расстоянию от текущего местоположения. У меня уже есть текущее местоположение устройства как double (lat, lng), lat и lng в базе данных также удваиваются.

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

В настоящее время я использую функцию для отображения расстояния для выбранной записи:

float pk = (float) (180/3.14159);<br> float a1 = (float) (db_lat / pk);<br> float a2 = (float) (db_lon / pk);<br> float b1 = (float) (current_lat / pk);<br> float b2 = (float) (current_lon / pk);<br> float t1 = FloatMath.cos(a1)*FloatMath.cos(a2)*FloatMath.cos(b1)*FloatMath.cos(b2);<br> float t2 = FloatMath.cos(a1)*FloatMath.sin(a2)*FloatMath.cos(b1)*FloatMath.sin(b2);<br> float t3 = FloatMath.sin(a1)*FloatMath.sin(b1);<br> double tt = Math.acos(t1 + t2 + t3);<br> double dist = (6366000*tt);

Например, выбор MySQL может быть (взят из: www.movable-type.co.uk):

Select Lat, Lon, acos(sin($lat)*sin(radians(Lat)) + cos($lat)*cos(radians(Lat))<em>cos(radians(Lon)-$lon))</em>$R As dist From MyTable ORDER BY dist DESC

В настоящее время я выбираю местоположения, используя следующее:

public Cursor locationGetAllRows(long groupid) { try { return db.query(LOCATION_DATABASE_TABLE, new String[] { "_id", "lat","lon","groupid"}, "groupid="+groupid, null, null, null, null); } catch (SQLException e) { Log.e("Exception on query: ", e.toString()); return null; } }

ОК, можно ли таким образом использовать базу данных SQLITE? Если не единственный вариант, о котором я могу подумать, это иметь дополнительный столбец, перебирать строки, выполняющие вышеуказанную функцию в каждой строке и заполняя дополнительный столбец в строке, затем сортировать по этому столбцу?

Ответы [ 4 ]

4 голосов
/ 09 января 2010

Это не совсем поможет, но для подобных ситуаций серьезно подумайте об использовании rawQuery() вместо query(), чтобы вы могли передать полный оператор SQL вместо необходимости разбивать его на части.


Ваша большая проблема в том, что я не вижу, чтобы SQLite имел тригонометрические функции.

Вы не указываете, как вы используете Cursor, который вы получаете от своего запроса. Например, если вы помещаете Cursor в какой-то CursorAdapter, вы можете:

  • преобразует Cursor в ArrayList<Position>, где Position - это некоторый класс Java, который вы определяете с помощью своих данных
  • закрыть Cursor, для освобождения оперативной памяти требуется
  • сортировка ArrayList<Position> с использованием Arrays.sort()
  • заверните ArrayList<Position> в ArrayAdapter<Position> и используйте его там, где вы использовали CursorAdapter
3 голосов
/ 17 сентября 2012

В моем приложении BostonBusMap я использовал аппроксимацию для ускорения расчета ближайших объектов к точке.Вы можете масштабировать долготу на cos(latitude), а затем просто использовать формулу Пифагора для вычисления расстояния сортировки (опуская квадратный маршрут, так как он не требуется для расстояния сравнения).Работает достаточно хорошо для небольших расстояний.

Источник: http://en.wikipedia.org/wiki/Geographical_distance#Spherical_Earth_projected_to_a_plane

3 голосов
/ 09 января 2010

Да, это прекрасно работает.

это можно превратить в хранимую процедуру следующим образом:

http://www.thismuchiknow.co.uk/?p=71 [Функция расстояния для sqlite]

есть также пространственная база данных Perst для android , которая превосходна, и пространственная база данных SpatiaLite , которая также великолепна, на которую вы можете ссылаться в своем приложении.

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

0 голосов
/ 09 января 2010

Я только что написал приложение, которое должно сортировать набор координат по расстоянию. Я создал массив идентификаторов и расстояний, а затем отсортировал их в Java. Тогда я мог бы найти ближайшие места и выбрать их из базы данных. Конечно, этот подход может не работать для вас, в зависимости от того, сколько у вас очков и как вы получаете доступ к базе данных. В приложении Finder моего Nando это работало нормально ~ 350 баллов.

Кроме того, я использовал Location.distanceBetween (..) из SDK, чтобы вычислить расстояния для меня. Я надеюсь, что этот метод будет реализован на C, чтобы обеспечить его быструю работу, однако быстрый взгляд на исходный код SDK показывает, что он написан на Java: (.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...