好的 - 我断断续续地为此苦苦挣扎了大约 3 个月,因为我已经用尽了我遇到的所有地理接近度公式,而且我离得到正确的结果还差得远,我想是时候了寻求帮助。
目的
我正在建立一个相当基本的商店定位器实现。用户输入他们的邮政编码并从预定义的搜索半径列表中进行选择。gmaps API 为该地址生成纬度/经度坐标并将它们传递给 php 脚本。在此脚本中,针对 mysql 数据库表查询用户坐标(结构如下)
post_id int(11)
post_type varchar(20)
lat float(10,6)
lng float(10,6)
该查询的结果(post ids)被输入到 wordpress 查询中,该查询生成包含地图标记数据的 XML。(wordpress 查询使用 post__in 和 posts_per_page -1 显示查询生成的所有 ID 的信息
问题
简而言之,我遇到的 Haversine 公式的每个实现似乎都会导致缺少标记 - 特别是任何非常接近用户输入坐标的标记(不确切知道,但我认为它在大约 500m 之内)。这是一个大问题,因为如果用户输入他们的邮政编码并且有一家商店非常靠近他们的位置,它就不会出现。
我已经尝试了大约 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'];
}
我尝试了 1 个公式,这是 Mike Pelley 在这里建议的:Geolocation SQL query not found exact location
这个公式似乎显示了非常接近用户输入位置的标记,但错过了应该在给定半径内显示的其他标记。为了消除任何混淆,这是我使用的代码:
$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'];
}
请求
基本上我想知道为什么这些代码块都没有显示正确的标记。如果有人可以建议对代码进行任何改进,或者可以将我指向一些我可能错过的资源,那就太好了
编辑
以为我的伪答案有效,但事实证明仍然存在问题。我现在最终选择了一个非常不同的方法,我正在使用一个非常好的 jquery 商店定位器,可以在这里找到:http ://www.bjornblog.com/web/jquery-store-locator-plugin
不适用于那里的每个项目,但对于我的需要,它是完美的(并且有效!)