据我所知,SQLite没有数学函数来在直接SQL中正确实现Haversine公式。我认为这应该可以使用external function,实现在C中。
目标是在iPhone中安装一个SQLite数据库,并能够按照距用户当前位置的距离进行排序。我已经搜索过了,但是我找不到这个例子。我认为困难的部分是让函数声明正确。我希望的最终结果是能够执行如下的SQL语句:
SELECT * FROM LOCATION loc ORDER BY distance(loc.lat, loc.long, ?, ?)
我有一个C Haversine公式。功能定义如下:
float distance( float nLat1, float nLon1, float nLat2, float nLon2 );
有没有人知道这是否可行和/或有一些示例代码可以从哪个开始?
答案 0 :(得分:4)
这演示了一个sqlite函数,它接受一个字符串参数并返回一个字符串结果。
在你的情况下,你需要一个读取四个浮点数并返回浮点数的函数,但原理是相同的(你可以用 sqlite3_value_double 和替换 sqlite3_value_text 带有 sqlite3_result_double 的sqlite3_result_text :
#include <stdlib.h>
#include <sqlite3.h>
#include <stdio.h>
void haver(sqlite3_context* ctx,int cnt,sqlite3_value** val)
{
printf("In SQLite haver implementation, called for value: %s\n", sqlite3_value_text(*val));
char * resultOfCall = "Result of function call"; //this would call the distance function
sqlite3_result_text(ctx, resultOfCall, strlen(resultOfCall), NULL);
}
int cback (void* udata,int ncol,char** value,char** colname)
{
int i=0;
for(;i<ncol;i++)
printf("Result column: %s value: %s \n", colname[i], value[i]);
return 0;
}
int main()
{
sqlite3 * handle;
int res = sqlite3_open("./test.sql", &handle);
res = sqlite3_create_function(handle, "haver", 1, SQLITE_UTF8, NULL, &haver, NULL, NULL);
char * errmsg = NULL;
res = sqlite3_exec(handle, "select haver(w) from t", &cback, NULL, &errmsg);
printf("sqlite3_exec result: %d %s\n", res, errmsg != NULL ? errmsg : "No error");
sqlite3_close(handle);
}
答案 1 :(得分:4)
我对这篇文章感到非常幸运:http://www.thismuchiknow.co.uk/?p=71