Я читал о радиусе и mysql, и я очень озадачен тем, как точно реализовать код с несколькими переменными поиска, поэтому кто-то может разбить его для меня.
В моей базе данных есть следующие таблицы:
IDX | тип | цена | item_desc | s_lat | s_long | Дата создания
Вот мой текущий код.
$search_origin_radius = "200";
$search_dest_radius = "100";
$search_origin_lat = "37.2629742";
$search_origin_long = "-98.286158";
$search_dest_lat = "37.2629742";
$search_dest_long = "-98.286158";
$type = "consumers";
$price = "100";
$sql = "SELECT * FROM products WHERE `price` = '$price'";
if($type && !empty($type))
{
$sql .= " AND `type` = '$type'";
}
Все, что я нашел до сих пор, говорит об использовании:
SELECT id, ( 3959 * acos( cos( radians(37) ) * cos( radians( latitude ) )
* cos( radians( longitude ) - radians(-122) ) + sin( radians(37) ) * sin(radians(lat)) ) ) AS distance
FROM myTable
HAVING distance < 50
ORDER BY distance
Но я очень запутался в том, как реализовать это для $search_origin_radius
а также $search_dest_radius
, По сути, я пытаюсь найти все, что продается в ценовом диапазоне и радиусе вокруг двух городов.
Пример Я хочу найти все по цене $ 100 в Оклахома-Сити, ок. В пределах 200 миль и в Канзас-Сити, Миссури в пределах 100 миль.
РЕДАКТИРОВАТЬ ** Как предложено, добавил это как сохраненную функцию.
function Calc_Distance($latitudeFrom, $longitudeFrom, $latitudeTo, $longitudeTo, $earthRadius = 3959)
{
// convert from degrees to radians
$latFrom = deg2rad($latitudeFrom);
$lonFrom = deg2rad($longitudeFrom);
$latTo = deg2rad($latitudeTo);
$lonTo = deg2rad($longitudeTo);
$latDelta = $latTo - $latFrom;
$lonDelta = $lonTo - $lonFrom;
$angle = 2 * asin(sqrt(pow(sin($latDelta / 2), 2) +
cos($latFrom) * cos($latTo) * pow(sin($lonDelta / 2), 2)));
return $angle * $earthRadius;
}
Используя новый запрос, но все равно ничего не появляется:
$sql = "SELECT *
FROM products
WHERE Calc_Distance(s_lat, s_long, $search_origin_lat, $search_origin_long) < 200
AND Calc_Distance(s_lat, s_long, $search_dest_lat, $search_dest_long) < 100
AND price = $price
";
Оклахома-Сити и Канзас-Сити находятся в 300 милях друг от друга.
Существует очень мало земли, которая может считаться как в 200 милях от Оклахома-Сити AND
до 100 миль от Канзас-Сити, поэтому я не удивлен, что ваш запрос не дал результатов.
Возможно, вы хотели OR
логика тут ..
SELECT id
FROM products
WHERE (*Oklahoma City distance calc miles* < 200
OR *Kansas City distance calc miles* < 100)
AND price = 100;
..или ты мог UNION ALL
SELECT
для каждого города:
SELECT id, 'Oklahoma City' as city
FROM products
WHERE *Oklahoma City distance calc miles* < 200
AND price = 100
UNION ALL
SELECT id, 'Kansas City'
FROM products
WHERE *Kansas City distance calc miles* < 100
AND price = 100;
Лично я склоняюсь ко второму, поскольку в него легко встроить код, и он подскажет, в каком городе продукт найден аккуратно.
Хотя, как отмечает @PaulSpiegel, это (без изменений) может возвращать некоторые продукты более одного раза, если области поиска пересекаются.
Напишите хранимую функцию, которая принимает две пары lat и lng и возвращает расстояние.
$sql = "SELECT ...
FROM MyTbl
WHERE Distance(s_lat, s_long, $search_origin_lat, $search_origin_long) < 200
AND Distance(s_lat, s_long, $search_dest_lat, $search_dest_long) < 100
AND price = $price
";
Или произнесите выражение дважды.
Если вы используете MySQL версии 5.7, вы можете использовать его Пространственное удобство
функции и, более конкретноST_Distance_Sphere
. Сюда
у вас будет результат в метрах и оттуда вы можете легко
посчитай это в милях.Если ваша версия MySQL 5.6.1, вы можете использовать
ST_Distance
функционировать как в этой MySQL-Fiddle пример
SELECT *,ST_Distance(POINT(`s_lat`,`s_long`), POINT(35.5857,-97.4885))*68.925*1.60934 AS `exact_distance`
FROM `entries` WHERE `price`=100
HAVING `exact_distance`<=200;
Вы заметите 2 константы (68.925
а также 1.60934
).
1-й из них преобразует результат ST_Distance в мили
Второй (при добавлении) преобразует его в километры
В приведенном выше примере ST_Distance
используется, чтобы получить расстояние от точки географии от Оклахома-Сити. Если вы хотите добавить другой город в свой SELECT
запрос тогда что-то вроде этого будет то, что вы могли бы использовать.
SELECT *,ST_Distance(POINT(`s_lat`,`s_long`), POINT(35.5857,-97.4885))*68.925 AS `exact_distance_from_Oklahoma_City`,
ST_Distance(POINT(`s_lat`,`s_long`), POINT(39.127562,-94.598810))*68.925 AS `exact_distance_from_Kansas_City`
FROM `entries` WHERE `price`=100
HAVING `exact_distance_from_Oklahoma_City`<=200
AND `exact_distance_from_Kansas_City`<=100;