Android sqlite ordenar en la columna calculada (coordina la distancia)
Estoy utilizando una base de datos SQLITE para almacenar latitudes y longitudes de ubicaciones.
Quiero ser capaz de ordenar los resultados por la distancia aproximada de la ubicación actual. Ya tengo la ubicación actual del dispositivo como un doble (lat, lng), el lat y lng en la base de datos también son dobles.
- Android: sqlite: cursor: getColumnIndex
- Manera correcta de manejar Bidireccional 1: m en Green-DAO
- ArrayAdapter: debe proporcionar un id de recurso para una vista de texto
- Tipos de datos utilizados en SQLite
- Error al leer la fila 0, columna 0 de una CursorWindow que tiene 0 filas, 64 columnas
Lo que quiero es una consulta que va a crear una columna virtual que soy capaz de ordenar los resultados por.
Actualmente utilizo una función para mostrar la distancia de un registro seleccionado:
float pk = (float) (180/3.14159);
float a1 = (float) (db_lat / pk);
float a2 = (float) (db_lon / pk);
float b1 = (float) (current_lat / pk);
float b2 = (float) (current_lon / pk);
float t1 = FloatMath.cos(a1)*FloatMath.cos(a2)*FloatMath.cos(b1)*FloatMath.cos(b2);
float t2 = FloatMath.cos(a1)*FloatMath.sin(a2)*FloatMath.cos(b1)*FloatMath.sin(b2);
float t3 = FloatMath.sin(a1)*FloatMath.sin(b1);
double tt = Math.acos(t1 + t2 + t3);
double dist = (6366000*tt);
Por ejemplo, una selección de MySQL podría ser (tomada de: www.movable-type.co.uk):
Select Lat, Lon, acos(sin($lat)*sin(radians(Lat)) + cos($lat)*cos(radians(Lat)) cos(radians(Lon)-$lon)) $R As dist From MyTable ORDER BY dist DESC
Actualmente selecciono ubicaciones usando lo siguiente:
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; } }
Aceptar ¿es posible utilizar la base de datos SQLITE de esta manera? Si no es la única opción que puedo pensar es tener una columna extra, iterar a través de las filas que ejecutan la función anterior en cada fila y rellenar una columna extra en la fila, a continuación, la clasificación en esa columna?
- Cómo ordenar por nombre y apellido en la barra de búsqueda - Sqlite
- ¿Cómo usar SQLite de Servicios en Android?
- ¿Ordenar fechas en la base de datos sqlite?
- Falta de tabla en SQLite con la versión específica de HTC DESIRE HD
- Cambiar la clave principal de una tabla en SQLite
- Mostrar el contenido de la base de datos sqlite en formato pdf en android
- Obtener id generado después de insertar
- ¿Es posible obtener acceso de sólo lectura a una base de datos sqlite en un apk?
Esto no ayudará completamente, pero para situaciones como esta, considere seriamente el uso de rawQuery()
lugar de query()
, por lo que puede pasar en una instrucción SQL completa frente a tener que cortar en pedazos.
Su mayor problema es que no veo que SQLite tiene funciones trigonométricas.
No indica cómo está utilizando el Cursor
que está recuperando de su consulta. Por ejemplo, si está poniendo el Cursor
en algún tipo de CursorAdapter
, podría:
- Convierta el
Cursor
en unArrayList<Position>
, dondePosition
es una clase Java que define con sus datos - Cierre el
Cursor
, para liberar la memoria RAM que ocupa -
Arrays.sort()
elArrayList<Position>
utilizandoArrays.sort()
- Envuelva el
ArrayList<Position>
en unArrayAdapter<Position>
y utilice aquél donde usted había estado usando suCursorAdapter
Sí, eso funciona perfectamente.
Puede convertirse en un procedimiento almacenado de la siguiente manera:
http://www.thismuchiknow.co.uk/?p=71 [Función de la distancia para sqlite]
También hay la base de datos espacial Prest para Android que es excelente, y la base de datos SpatiaLite espacial que también es impresionante, que podría enlazar en su aplicación.
W / out utilizando un lib especializado, se puede aproximar la distancia de algunas maneras (calcularlo como si fuera planar (rectangular) a continuación, utilizar la fórmula de Haversine para clasificar el subconjunto más tarde, utilice una tabla de búsqueda que se aproxima cos, sin, etc , Localizar grupos en zonas de 5 millas cuadradas y buscar celdas vecinas hasta el máximo, etc …)
En mi aplicación BostonBusMap utilicé una aproximación para acelerar el cálculo de objetos más cercanos a un punto. Puede escalar la longitud por cos(latitude)
y luego usar la fórmula de Pythagorean para calcular una distancia de clasificación (omitiendo la ruta cuadrada ya que no es necesario para una distancia de comparación). Funciona razonablemente bien para distancias pequeñas.
Fuente: http://en.wikipedia.org/wiki/Geographical_distance#Spherical_Earth_projected_to_a_plane
Acabo de escribir una aplicación que necesita ordenar un conjunto de coordenadas basadas en la distancia. Lo que hice fue crear una matriz de ID y Distancias y luego ordenarlas dentro de Java. Entonces podría encontrar los lugares más cercanos y seleccionarlos de la base de datos. Por supuesto, este enfoque puede no funcionar para usted dependiendo de cuántos puntos tiene y cómo acceder a la base de datos. Esto funcionó bien para ~ 350 puntos, en mi aplicación Nando Finder.
Además utilicé Location.distanceBetween (..) desde el SDK para calcular las distancias para mí. Espero que este método se implementará en C para asegurar que es rápido, sin embargo, un rápido vistazo a la fuente SDK muestra que está escrito en Java :(.
- ¿Cómo puedo crear una notificación diferente en el dispositivo y el desgaste?
- Widget de la pantalla de inicio de Android (icono, etiqueta – estilo)