【问题标题】:finding locations within a particular distance using db2使用 db2 查找特定距离内的位置
【发布时间】:2012-03-22 13:49:22
【问题描述】:

我正在使用 html5 地理定位 api 来获取我的经纬度位置。我想将它们存储在位置表中,并希望检索特定距离内的这些位置。

我当前的经纬度存储在变量“latval”、“longval”、“distance”中 我的桌子是“位置” 列是“位置”、“纬度”、“长” 我使用 DB2 Express C 作为数据库,现在将纬度和经度列设置为双精度类型。我应该使用什么类型来存储这些值以及在一定距离内获取位置名称的查询是什么 谢谢。

【问题讨论】:

    标签: geolocation db2


    【解决方案1】:

    看起来 Express C 有一个包含空间处理的扩展。我从未使用过它(目前似乎无法访问),所以我无法与它交谈。我假设您想使用它(查找半径内的所有位置是一个非常标准的查询)。

    如果由于某种原因您不能使用扩展程序,我会这样做:
    保持表格原样,或者使用浮点数据类型,尽管请使用完整的属性名称(没有理由截断它们)。对于简单的需求,“位置”的名称可以存储在表中,但如果不止一件东西在同一个位置,您可能希望给它一个数字 ID(因此实际点只有一次)。 您还需要涵盖纬度和经度的索引(可能单向一个,或每列一个)。

    然后,给定一个起始位置和距离,使用这个查询:

    SELECT name, latitude, longitude
    FROM location
    WHERE (latitude >= :currentLatitude - :distance
           AND latitude <= :currentLatitude + :distance)
    AND (longitude >= :currentLongitude - :distance
         AND longitude <= :currentLongitude + :distance)
      -- The previous four lines reduce the points selected to a box.
      -- This is, or course, not completely correct, but should allow
      -- the query to use the indicies to greatly reduce the initial 
      -- set of points evaluated.
      -- You may wish to flip the condition and use ABS(), but
      -- I don't think that would use the index...
    AND POWER(latitude - :currentLatitude, 2) + POWER(longitude - :currentLongitude, 2) 
             <= POWER (:distance, 2)
      -- This uses the pythagorean theorem to find all points within the specified
      -- distance.  This works best if the points have been pre-limited in some
      -- way, because an index would almost certainly not be used otherwise.
      -- Note that, on a spherical surface, this isn't completely accurate
      --  - namely, distances between longitude points get shorter the farther
      --       from the equator the latitude is - 
      -- but for your purposes is likely to be fine.
    


    编辑:

    找到this after searching for 2 seconds on google,这也提醒我:distance 的单位是错误的。修改后的查询是:

    WITH Nearby (name, latitude, longitude, dist) as (
     SELECT name, latitdude, longitude,
           ACOS(SIN(RADIANS(latitude)) * SIN(RADIANS(:currentLatitude)) + 
                COS(RADIANS(latitude)) * COS(RADIANS(:currentLatitude)) * 
                COS(RADIANS(:currentLongitude - longitude))) * :RADIUS_OF_EARTH as dist
    FROM location 
    WHERE (latitude >= :currentLatitude - DEGREES(:distance / :RADIUS_OF_EARTH)
           AND latitude <= :currentLatitude + DEGREES(:distance / :RADIUS_OF_EARTH))
    AND (longitude >= :currentLongitude - 
                   DEGREES(:distance / :RADIUS_OF_EARTH / COS(RADIANS(:currentLatitude)))
         AND longitude <= :currentLongitude + 
                   DEGREES(:distance / :RADIUS_OF_EARTH / COS(RADIANS(:currentLatitude))))
    )
    SELECT *
    FROM Nearby
    WHERE dist <= :distance
    

    请注意,将距离函数包装在标记为 DETERMINISTIC 的 UDF 中将允许将其放置在 SELECTHAVING 部分中,但实际上只调用一次,从而消除需要 CTE。

    【讨论】:

    • 感谢您的努力。我正在寻找使用球面公式的距离查询。使用大圆距离公式的查询是什么?
    • 非常感谢 x-zero。我现在在我的大学里。我回家后会检查它是否工作。我还安装了空间扩展器。但我无法弄清楚将坐标存储在其中。如果你知道任何对它有很大帮助的事情,请告诉我。你可以在 db2 页面的插件中找到空间扩展器。
    • 我已经尝试了上面的查询。它返回给我以下错误 SQL0206N“DIST”在使用它的上下文中无效。 SQLSTATE=42703 SQL0206N "DIST '
    • 以下查询正在运行,但使用边界坐标公式时未显示任何结果。 WITH Nearby as (SELECT NAME,ACOS(SIN(RADIANS(latitude)) * SIN(RADIANS(17.386211)) + COS(RADIANS(latitude)) * COS(RADIANS(17.386211)) * COS(RADIANS(78.430578 - longitude)))*6371 as dist FROM TEST ) SELECT * FROM Nearby WHERE dist &lt;= 10
    • 请注意,公式中有一些错误,主要是因为与表示相关的不精确(即,因为浮点数/双精度数不能精确地表示某些数字)。您确定在该距离内列出了点吗?
    猜你喜欢
    • 1970-01-01
    • 2022-06-15
    • 1970-01-01
    • 2011-02-18
    • 1970-01-01
    • 1970-01-01
    • 2011-06-29
    • 2015-12-02
    • 1970-01-01
    相关资源
    最近更新 更多