tutorial studio proyectos insertar espaƱol datos crear consultas conexion con aplicaciones aplicacion sql android sqlite

studio - select sqlite android



Consulta para obtener registros basados en Radius en SQLite? (3)

Aquí hay una implementación en Java para construir una consulta basada en la ubicación en un dispositivo Android. La idea proviene de KennyTM (ver respuesta aceptada) e implica la adición de 4 columnas en su tabla para almacenar valores de seno y coseno de latitud y longitud.

Aquí está el código que prepara los datos para una tabla "Comprar" en el momento de la inserción:

public static void injectLocationValues(ContentValues values, double latitude, double longitude) { values.put(LocationColumns.LATITUDE, latitude); values.put(LocationColumns.LONGITUDE, longitude); values.put(LocationColumns.COSLAT, Math.cos(MathUtil.deg2rad(latitude))); values.put(LocationColumns.SINLAT, Math.sin(MathUtil.deg2rad(latitude))); values.put(LocationColumns.COSLNG, Math.cos(MathUtil.deg2rad(longitude))); values.put(LocationColumns.SINLNG, Math.sin(MathUtil.deg2rad(longitude))); } public static double deg2rad(double deg) { return (deg * Math.PI / 180.0); }

Luego puedes construir tu proyección usando la siguiente función:

/** * Build query based on distance using spherical law of cosinus * * d = acos(sin(lat1).sin(lat2)+cos(lat1).cos(lat2).cos(long2−long1)).R * where R=6371 and latitudes and longitudes expressed in radians * * In Sqlite we do not have access to acos() sin() and lat() functions. * Knowing that cos(A-B) = cos(A).cos(B) + sin(A).sin(B) * We can determine a distance stub as: * d = sin(lat1).sin(lat2)+cos(lat1).cos(lat2).(cos(long2).cos(long1)+sin(long2).sin(long1)) * * First comparison point being fixed, sin(lat1) cos(lat1) sin(long1) and cos(long1) * can be replaced by constants. * * Location aware table must therefore have the following columns to build the equation: * sinlat => sin(radians(lat)) * coslat => cos(radians(lat)) * coslng => cos(radians(lng)) * sinlng => sin(radians(lng)) * * Function will return a real between -1 and 1 which can be used to order the query. * Distance in km is after expressed from R.acos(result) * * @param latitude, latitude of search * @param longitude, longitude of search * @return selection query to compute the distance */ public static String buildDistanceQuery(double latitude, double longitude) { final double coslat = Math.cos(MathUtil.deg2rad(latitude)); final double sinlat = Math.sin(MathUtil.deg2rad(latitude)); final double coslng = Math.cos(MathUtil.deg2rad(longitude)); final double sinlng = Math.sin(MathUtil.deg2rad(longitude)); //@formatter:off return "(" + coslat + "*" + LocationColumns.COSLAT + "*(" + LocationColumns.COSLNG + "*" + coslng + "+" + LocationColumns.SINLNG + "*" + sinlng + ")+" + sinlat + "*" + LocationColumns.SINLAT + ")"; //@formatter:on }

Inyectará una columna de respuesta con la distancia en la que necesita aplicar la siguiente fórmula para convertir en kilómetros:

public static double convertPartialDistanceToKm(double result) { return Math.acos(result) * 6371; }

Si desea solicitar su consulta utilizando la distancia parcial, debe solicitar DESC y no ASC.

Tengo esta consulta que funciona bien en MySQL

SELECT ((ACOS(SIN(12.345 * PI() / 180) * SIN(lat * PI() / 180) + COS(12.345 * PI() / 180) * COS(lat * PI() / 180) * COS((67.89 - lon) * PI() / 180)) * 180 / PI()) * 60 * 1.1515 * 1.609344) AS distance, poi.* FROM poi WHERE lang=''eng'' HAVING distance<=''30''

la distancia está en Kilómetros, la entrada es lat=12.345 y lon=67.89

El SQLite es 3, y no puedo ejecutar funciones personalizadas con él, ya que está en Android. Tampoco tengo acos () etc ... ya que eso no es parte del SQLite estándar.

¿Cómo sería la consulta anterior en SQLite?


Puede crear 4 columnas nuevas, siendo sin y cos de lat y lon . Como cos(a+b) = cos a cos b - sin a sin b , y otras apariencias de sin y cos como SIN(12.345 * PI() / 180) se pueden calcular en el programa antes de ejecutar la consulta, el gran " La expresión "distancia" se reduce a algo de la forma P * SIN_LAT + Q * COS_LAT + ... que puede ser manejado por SQLite3.

Por cierto, vea también Sqlite en Android: Cómo crear una función sqlite dist db: para usar en la aplicación para el cálculo de distancia usando lat, long .


Tuve el mismo problema al trabajar en sqlite3 para iOS, después de jugar un poco con la fórmula aquí hay una forma de hacerlo sin usar la función desde el lado sql (pseudo-código):

  1. Precalcule estos valores para cada artículo que almacena en la base de datos (y guárdelos):

    cos_lat = cos(lat * PI / 180) sin_lat = sin(lat * PI / 180) cos_lng = cos(lng * PI / 180) sin_lng = sin(lng * PI / 180)

  2. Precalcular estos valores en el tiempo de búsqueda (para una posición dada cur_lat, cur_lng)

    CUR_cos_lat = cos(cur_lat * PI / 180) CUR_sin_lat = sin(cur_lat * PI / 180) CUR_cos_lng = cos(cur_lng * PI / 180) CUR_sin_lng = sin(cur_lng * PI / 180) cos_allowed_distance = cos(2.0 / 6371) # This is 2km

  3. Su consulta SQL se verá así (reemplace CUR_ * por los valores que acaba de calcular)

    SELECCIONAR * FROM posición WHERE CUR_sin_lat * sin_lat + CUR_cos_lat * cos_lat * (cos_lng * CUR_cos_lng + sin_lng * CUR_sin_lng)> cos_allowed_distance;