2013-01-04 99 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')

相關問題