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
不适用于那里的每个项目,但为了我的需要它是完美的(并且有效!)
稍微横向思考一下,我想出了一种解决标记缺失问题的“某种”解决方案。我最初发布的两个方程给出了正确的结果,但每个方程都错过了靠近目标或搜索半径边缘的标记
这不是很优雅,但我认为运行两个方程并生成 2 个数组,然后将它们组合起来(删除任何重复项)将为我提供我正在寻找的所有标记。这确实有效(显然会影响性能,但它不是高流量应用程序),所以我暂时会使用它,但如果有人有的话,我仍然在寻求更实用的解决方案!
| 归档时间: |
|
| 查看次数: |
854 次 |
| 最近记录: |