没有这样的acos功能

时间:2013-01-04 21:13:43

标签: android sqlite math geometry cos

我有一个问题。我想在Android应用程序中获取谷歌地图上最近的点数。不同的点/坐标存储在sqlite数据库中。我必须从他们那里得到最接近的5。我正在使用的查询是:

SELECT id, ( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance FROM markers HAVING distance < 25 ORDER BY distance LIMIT 0 , 5;

但我收到一个错误,即“没有这样的功能: acos 存在”。 什么是它的正确解决方案

2 个答案:

答案 0 :(得分:3)

默认情况下,SQLite不支持任何三角函数,因此您无法在SQL查询中使用它们。

您可以获取坐标列表并在应用程序代码中处理它,或者您可以尝试在SQLite中使用用户定义的函数公开Java的三角函数(请参阅How can I create a user-defined function in SQLite?)。

答案 1 :(得分:1)

您可以在C中创建实现三角函数的扩展,例如:

/* sql_trig.c */
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1;
#include <stdlib.h>

/* this bit is required to get M_PI out of MS headers */
#if defined( _WIN32 )
#define _USE_MATH_DEFINES
#endif /* _WIN32 */

#include <math.h>

#define RADIANS(d) (( d / 180.0 ) * M_PI)

static void sql_trig_sin( sqlite3_context *ctx, int num_values, sqlite3_value **values )
{
    double a = RADIANS(sqlite3_value_double( values[0] ));
    sqlite3_result_double( ctx, sin( a ) );
}

static void sql_trig_cos( sqlite3_context *ctx, int num_values, sqlite3_value **values )
{
    double a = RADIANS(sqlite3_value_double( values[0] ));
    sqlite3_result_double( ctx, cos( a ) );
}

static void sql_trig_acos( sqlite3_context *ctx, int num_values, sqlite3_value **values )
{
    double a = sqlite3_value_double( values[0] );
    sqlite3_result_double( ctx, acos( a ) );
}

static void sql_trig_radians( sqlite3_context *ctx, int num_values, sqlite3_value **values )
{
    sqlite3_result_double( ctx, RADIANS(sqlite3_value_double( values[0] ) ));
}


int sqlite3_extension_init( sqlite3 *db, char **error, const sqlite3_api_routines *api )
{
    SQLITE_EXTENSION_INIT2(api);

    sqlite3_create_function( db, "sin",1,
        SQLITE_UTF8, NULL, &sql_trig_sin, NULL, NULL );
    sqlite3_create_function( db, "cos",1,
        SQLITE_UTF8, NULL, &sql_trig_cos, NULL, NULL );
    sqlite3_create_function( db, "acos",1,
        SQLITE_UTF8, NULL, &sql_trig_acos, NULL, NULL );

    return SQLITE_OK;
}

现在您可以将其编译为共享库:

$ gcc -c -fPIC sql_trig.c
$ ld -shared -o sql_trig.so sql_trig.o -lm

并使用SELECT load_extension('./sql_trig.so')

加载它
相关问题