由于地理邻近公式(商店定位器)而导致缺少结果

Fou*_*cks 7 php mysql wordpress proximity geo

好的 - 我已经和我一起打了大约3个月的摔跤,因为我已经筋疲力尽了我所遇到的每一个地理接近公式,而且我没有接近得到正确的结果我认为是时候了请求一些帮助.

目的

我正在建立一个商店定位器的相当基本的实现.用户输入他们的邮政编码并从预定义的搜索半径列表中进行选择.gmaps API为此地址生成纬度/经度坐标,并将它们传递给php脚本.在此脚本中,将针对mysql数据库表查询用户坐标(下面的结构)

post_id int(11)                             
post_type varchar(20)                                
lat   float(10,6)                               
lng   float(10,6)
Run Code Online (Sandbox Code Playgroud)

将此查询的结果(post id)输入到wordpress查询中,该查询生成包含地图标记数据的XML.(wordpress查询使用post__in和posts_per_page -1来显示查询生成的所有ID的信息

问题

简而言之,我遇到的Haversine公式的每一个实现似乎都会导致缺少标记 - 特别是任何非常靠近用户输入坐标的标记(不知道确切但我认为它在500米左右).这是一个很大的问题,好像用户输入他们的邮政编码,并且有一个非常接近他们位置的商店,它将不会出现.

我已经尝试了大约8种不同的论坛的排列,我从各种教程中挖出了相同的结果.以下是我目前在网站上使用的公式,该公式提供除了非常接近用户输入位置的标记之外的所有标记:

$center_lat = $_GET["lat"];
$center_lng = $_GET["lng"];
$radius = $_GET["radius"];

// Calculate square radius search

$lat1 = (float) $center_lat - ( (int) $radius / 69 );
$lat2 = (float) $center_lat + ( (int) $radius / 69 );
$lng1 = (float) $center_lng - (int) $radius / abs( cos( deg2rad( (float) $center_lat ) ) * 69 );
$lng2 = (float) $center_lng + (int) $radius / abs( cos( deg2rad( (float) $center_lat ) ) * 69 );

$sqlsquareradius = "
SELECT 
post_id, lat, lng
FROM
wp_geodatastore
WHERE
lat BETWEEN ".$lat1." AND ".$lat2."
AND
lng BETWEEN ".$lng1." AND ".$lng2."
"; // End $sqlsquareradius

// Create sql for circle radius check
$sqlcircleradius = "
SELECT
t.post_id,
3956 * 2 * ASIN(
    SQRT(
        POWER(
            SIN(
                ( ".(float) $center_lat." - abs(t.lat) ) * pi() / 180 / 2
            ), 2
        ) + COS(
            ".(float) $center_lat." * pi() / 180
        ) * COS(
            abs(t.lat) * pi() / 180
        ) * POWER(
            SIN(
                ( ".(float) $center_lng." - t.lng ) * pi() / 180 / 2
            ), 2
        )
    )
) AS distance
FROM
(".$sqlsquareradius.") AS t
HAVING
distance <= ".(int) $radius."
ORDER BY distance
"; // End $sqlcircleradius


$result = mysql_query($sqlcircleradius);

$row = mysql_fetch_array( $result );

while($row = mysql_fetch_array( $result )) {
// the contents of each row
$post_ids[] = $row['post_id'];
}
Run Code Online (Sandbox Code Playgroud)

有一个我试过的公式,这是迈克佩利在这里建议的:地理定位SQL查询找不到确切的位置

这个公式似乎显示了非常接近用户输入位置的标记,但错过了应该在给定半径内显示的其他标记.要清除任何混淆,这是我使用的代码:

$center_lat = $_GET["lat"];
$center_lng = $_GET["lng"];
$radius = $_GET["radius"];

$sql = "
SELECT post_id, lat, lng, 
truncate((degrees(acos( sin(radians(lat)) 
* sin(radians(".$center_lat.")) 
+ cos(radians(lat)) 
* cos(radians(".$center_lat.")) 
* cos(radians(".$center_lng." - lng) ) ) ) 
* 69.09*1.6),1) as distance 
FROM wp_geodatastore HAVING distance <= ".$radius." ORDER BY distance desc
"; // End $sqlcircleradius


$result = mysql_query($sql);

$row = mysql_fetch_array( $result );

while($row = mysql_fetch_array( $result )) {
// Print out the contents of each row
$post_ids[] = $row['post_id'];
}
Run Code Online (Sandbox Code Playgroud)

请求

基本上我想知道为什么这些代码块都没有显示正确的标记.如果任何人都可以建议对代码进行任何改进,或者可以指向一些我可能错过的资源,这将是很好的

编辑

认为我的psudeo答案正在起作用,但事实证明它仍然存在问题.我现在最终选择了一个非常不同的方法,我正在使用一个非常好的jquery商店定位器,可以在这里找到:http://www.bjornblog.com/web/jquery-store-locator-plugin

不适用于那里的每个项目,但为了我的需要它是完美的(并且有效!)

Fou*_*cks 0

稍微横向思考一下,我想出了一种解决标记缺失问题的“某种”解决方案。我最初发布的两个方程给出了正确的结果,但每个方程都错过了靠近目标或搜索半径边缘的标记

这不是很优雅,但我认为运行两个方程并生成 2 个数组,然后将它们组合起来(删除任何重复项)将为我提供我正在寻找的所有标记。这确实有效(显然会影响性能,但它不是高流量应用程序),所以我暂时会使用它,但如果有人有的话,我仍然在寻求更实用的解决方案!