2013-01-04 45 views
1

我有一个问题。我想在Android应用程序的谷歌地图上找到最近的点。不同的点/坐标存储在sqlite数据库中。我必须得到他们最近的5个。我使用的查询是:没有这样的acos功能存在

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存在”。 什么是它的正确解决方案

回答

3

SQLite默认不支持任何三角函数,所以你不能在SQL查询中使用它们。

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

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')

相关问题