Хорошо, я боролся с этим около 3 месяцев, и с тех пор, как я исчерпал все формулы географической близости, с которыми я сталкивался, и я не приблизился к получению правильных результатов, я решил, что пришло время попросить некоторую помощь.
ЦЕЛЬ
Я настраиваю довольно простую реализацию локатора магазинов. Пользователь вводит свой почтовый индекс и выбирает из заранее заданного списка радиусов поиска. API gmaps генерирует координаты широты и долготы для этого адреса и передает их скрипту php. В этом сценарии пользовательские координаты запрашиваются в таблице базы данных mysql (структура ниже)
post_id int(11)
post_type varchar(20)
lat float(10,6)
lng float(10,6)
Результаты этого запроса (идентификаторы сообщений) вводятся в запрос wordpress, который генерирует XML, содержащий данные маркеров карты. (запрос wordpress использует post__in и posts_per_page -1 для отображения информации для всех идентификаторов, сгенерированных запросом
ПРОБЛЕМА
В двух словах, каждая реализация формулы Хаверсина, с которой я столкнулся, похоже, приводит к отсутствию маркеров - в частности, любые маркеры, которые очень близки к координатам, введенным пользователем (точно не знаю, но я думаю, что это примерно в 500 м). Это большая проблема, как если бы пользователь вводил свой почтовый индекс, а рядом с их местоположением есть магазин. не появится.
Я пробовал около 8 различных перестановок forumla, которые я откопал из разных руководств, с одинаковыми результатами. Ниже приведена формула, которую я в настоящее время использую на сайте, которая предоставляет все маркеры, кроме тех, которые очень близки к позиции, введенной пользователем:
$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'];
}
Я попробовал одну формулу, предложенную Майком Пелли здесь: 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'];
}
ЗАПРОС
В основном я хотел бы знать, почему ни один из этих блоков кода не отображает правильные маркеры. Если кто-нибудь может предложить какие-либо улучшения в коде или указать мне на какой-то ресурс, который я мог пропустить, это было бы здорово
РЕДАКТИРОВАТЬ
Я думал, что мой psudeo-ответ работает, но, как оказалось, проблемы все еще были. В итоге я выбрал совсем другой подход, и я использую очень хороший указатель хранилища jquery, который можно найти здесь: http://www.bjornblog.com/web/jquery-store-locator- plugin
Не будет работать для всех проектов, но для моих нужд он идеален (и работает!)