代码之家  ›  专栏  ›  技术社区  ›  Don Jones

基于lat/long-SQLite的SQL查询

  •  11
  • Don Jones  · 技术社区  · 15 年前

    纬度 接近

    其中Lat和Long是GPS坐标,而接近度是(一些单位英尺?几秒钟?分钟?)

    诀窍是:这必须在SQLite中工作,它只支持相当原始的数据类型。不作弊,不依赖SQL Server(或其他提供更好地理空间功能的产品)。

    有什么建议吗?

    3 回复  |  直到 15 年前
        1
  •  7
  •   StayOnTarget Charlie Flowers    8 年前

    #define DEG2RAD(degrees) (degrees * 0.01745327) // degrees * pi over 180
    
    static void distanceFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
    {
      // check that we have four arguments (lat1, lon1, lat2, lon2)
      assert(argc == 4);
      // check that all four arguments are non-null
      if (sqlite3_value_type(argv[0]) == SQLITE_NULL || sqlite3_value_type(argv[1]) == SQLITE_NULL ||
      sqlite3_value_type(argv[2]) == SQLITE_NULL ||
      sqlite3_value_type(argv[3]) == SQLITE_NULL) {
      sqlite3_result_null(context);
      return;
    }
    
    // get the four argument values
    double lat1 = sqlite3_value_double(argv[0]);
    double lon1 = sqlite3_value_double(argv[1]);
    double lat2 = sqlite3_value_double(argv[2]);
    double lon2 = sqlite3_value_double(argv[3]);
    
    // convert lat1 and lat2 into radians now, to avoid doing it twice below
    double lat1rad = DEG2RAD(lat1);
    double lat2rad = DEG2RAD(lat2);
    
    // apply the spherical law of cosines to our latitudes and longitudes, and set the result appropriately
    
    // 6378.1 is the approximate radius of the earth in kilometres
    sqlite3_result_double(context, acos(sin(lat1rad) * sin(lat2rad) + cos(lat1rad) * cos(lat2rad) * cos(DEG2RAD(lon2) - DEG2RAD(lon1))) *
    6378.1);
    }
    

    这定义了一个SQL函数距离(Latitude1,longtude1, Latitude2,longtude2),返回距离(以公里为单位) 在两点之间。

    然后在调用sqlite3\u open之后立即添加此行:

    sqlite3_create_function(sqliteDatabasePtr, "distance", 4, SQLITE_UTF8, NULL, &distanceFunc, NULL, NULL);
    

    打开sqlite3。

    假设您有一个名为Locations的表,其中的列名为 纬度和经度(都是double类型)包含 度,然后可以在SQL中使用此函数,如下所示:

    SELECT * FROM Locations ORDER BY distance(Latitude, Longitude, 51.503357, -0.1199)
    

    本例根据距离对数据库中的位置进行排序 离伦敦眼51.503357,-0.1199不远。

    编辑:

    http://www.thismuchiknow.co.uk/?p=71 已死亡,因此如评论中所述,您可以使用以下链接: https://web.archive.org/web/20160808122817/http://www.thismuchiknow.co.uk/?p=71 获取该网页

        2
  •  3
  •   Community Mohan Dere    8 年前

    Haversine formula 是你想要的。用简单的欧几里德距离公式是不够的,因为地球的曲率会影响两点之间的距离。

    Creating a Store Locator with PHP, MySQL & Google Maps 是一篇关于用MySQL实现这个解决方案的文章,但是SQLite不支持trig函数。

    Calculating Great-Circle Distance with SQLite 下面是关于堆栈溢出的更多关于扩展SQLite函数的提示,您可以解决这个问题。

        3
  •  2
  •   TheSteve0    15 年前

    您还知道SQLite有一个名为Spatialite的插件,它的功能与PostGIS和SQLServer完全相同?我假设您正在尝试在iPhone或浏览器上使用SQLLite。如果不是他们,我高度推荐他们。