【问题标题】:SQL to pull locations within NE/SW boundsSQL 在 NE/SW 范围内提取位置
【发布时间】:2014-09-14 12:05:20
【问题描述】:

我正在尝试获取一个 SQL 查询来动态地提取城市范围内的事件。我有一个城镇/城市列表,通过谷歌地理编码,我可以获得每个城市的东北和西南边界。

我看到了解释如何检查某个位置(按纬度和经度)是否在美国等地范围内的代码,但我了解到这不适用于整个世界。

我试过下面的公式,但它似乎不起作用:

AND ( 
    ($swLat < $neLat AND lat BETWEEN $swLat AND $neLat) 
        OR 
    ($neLat < $swLat AND lat BETWEEN $neLat AND $swLat)
    AND 
    ($swLng < $neLng AND lng BETWEEN $swLng AND $neLng) 
        OR 
    ($neLng < $swLng AND lng BETWEEN $neLng AND $swLng)
)

刚刚尝试了下面的第一个建议,这是我得到的输出:

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID 
FROM wp_posts 
INNER JOIN lat_lng_post ON wp_posts.ID = lat_lng_post.post_id 
WHERE 1=1 
AND wp_posts.ID IN (10027,10095,...,10657) 
AND wp_posts.post_type = 'event' 
AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') 
AND lat_lng_post.lat = lat 
AND lat_lng_post.lng = lng 
AND ( 
       ( 
           (52.385999 < 52.5688762) AND (lat BETWEEN 52.385999 AND 52.5688762) 
           OR 
           (52.5688762 < 52.385999) AND (lat BETWEEN 52.5688762 AND 52.385999) 
        ) AND (
           (-2.0174336 < -1.7098294) AND (lng BETWEEN -2.0174336 AND -1.7098294) 
           OR 
           (-1.7098294 < -2.0174336) AND (lng BETWEEN -1.7098294 AND -2.0174336) 
        ) 
    )
ORDER BY wp_posts.post_date DESC 
LIMIT 0, 10

编辑 2 根据 barryhunter 的回答,我有这个在查询中调用的函数:

function bounds_query($bounds) {

    $swLat = $_SESSION['search']['SW'][0];
    $swLng = $_SESSION['search']['SW'][1];
    $neLat = $_SESSION['search']['NE'][0];
    $neLng = $_SESSION['search']['NE'][1];

    $bounds .= ' AND (lat BETWEEN '.$swLat.' AND '.$neLat.')';
    if ($neLng < $swLng) {
      $bounds .= ' AND NOT (lng BETWEEN '.$neLng.' AND '.$swLng.')';
    } else {
      $bounds .= ' AND (lng BETWEEN '.$swLng.' AND '.$neLng.')';
    }

    return $bounds;
}

这会输出以下 SQL:

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID 
FROM wp_posts 
INNER JOIN lat_lng_post 
ON wp_posts.ID = lat_lng_post.post_id 
WHERE 1=1 
AND wp_posts.ID IN (10060,10293,...,10657) 
AND wp_posts.post_type = 'event' 
AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') 
AND lat_lng_post.lat = lat 
AND lat_lng_post.lng = lng 
AND (lat BETWEEN 52.385999 AND 52.5688762) AND (lng BETWEEN -2.0174336 AND -1.7098294)      
ORDER BY wp_posts.post_date DESC 
LIMIT 0, 10

【问题讨论】:

    标签: mysql sql geolocation


    【解决方案1】:

    问题是当你的 BBOX 跨越日期线时,我在这里指出:http://sphinxsearch.com/forum/view.html?id=8969 与 sphinx 相关,但同样适用于 mysql....

    $where = "(lat BETWEEN $swLat AND $neLat)";
    if ($neLng < $swLng) {
      $where .= " AND NOT (lng BETWEEN $neLng AND $swLng)";
    } else {
      $where .= " AND (lng BETWEEN $swLng AND $neLng)";
    }
    

    使用 否定 过滤器排除东西方之间的项目(因为东 longtitde 值现在位于地球的西边0 - 只留下跨越日期线的狭窄停靠点上的结果。

    坦率地说,尽管您不应该遇到太多问题,因为不应该有任何城市跨越日期线!

    (会认为这段代码更简洁,因为它避免了对纬度的冗余检查,并将其移动到 PHP 而不是 mysel,但您也可以通过将 NOT 逻辑添加到 (lng BETWEEN $neLng AND $swLng) 子句来修复您的代码)

    【讨论】:

    • 嗨,我刚刚将它实现到一个 PHP 函数中,但恐怕它仍然没有返回正确的结果,我可以将该函数添加到我的问题中,以便您看看是否有帮助?
    • 好吧,我想说“边界框”查询在您的示例中很好 - 假设有问题的城市是英国伯明翰 :) 错误可能在其他地方,也许您的数据没有像您想的那样设置,或者查询可能是错误的。你说它“不起作用”,但没有详细说明什么不起作用,或者为什么你认为它不起作用。
    • 是的,这个城市是英国的伯明翰。我认为它不起作用,因为从查询中提取的事件位于伯恩茅斯和斯沃尼奇(离伯明翰很远)。我会仔细检查数据,但我确定纬度/经度是正确的。
    • 问题在于先前的查询未正确运行。感谢您的帮助!
    猜你喜欢
    • 2012-02-18
    • 2012-03-16
    • 2015-05-05
    • 1970-01-01
    • 2016-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多